1/*! 2 * ApexCharts v3.6.12 3 * (c) 2018-2019 Juned Chhipa 4 * Released under the MIT License. 5 */ 6(function (global, factory) { 7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 typeof define === 'function' && define.amd ? define(factory) : 9 (global = global || self, global.ApexCharts = factory()); 10}(this, function () { 'use strict'; 11 12 function _typeof(obj) { 13 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 14 _typeof = function (obj) { 15 return typeof obj; 16 }; 17 } else { 18 _typeof = function (obj) { 19 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 20 }; 21 } 22 23 return _typeof(obj); 24 } 25 26 function _classCallCheck(instance, Constructor) { 27 if (!(instance instanceof Constructor)) { 28 throw new TypeError("Cannot call a class as a function"); 29 } 30 } 31 32 function _defineProperties(target, props) { 33 for (var i = 0; i < props.length; i++) { 34 var descriptor = props[i]; 35 descriptor.enumerable = descriptor.enumerable || false; 36 descriptor.configurable = true; 37 if ("value" in descriptor) descriptor.writable = true; 38 Object.defineProperty(target, descriptor.key, descriptor); 39 } 40 } 41 42 function _createClass(Constructor, protoProps, staticProps) { 43 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 44 if (staticProps) _defineProperties(Constructor, staticProps); 45 return Constructor; 46 } 47 48 function _defineProperty(obj, key, value) { 49 if (key in obj) { 50 Object.defineProperty(obj, key, { 51 value: value, 52 enumerable: true, 53 configurable: true, 54 writable: true 55 }); 56 } else { 57 obj[key] = value; 58 } 59 60 return obj; 61 } 62 63 function _objectSpread(target) { 64 for (var i = 1; i < arguments.length; i++) { 65 var source = arguments[i] != null ? arguments[i] : {}; 66 var ownKeys = Object.keys(source); 67 68 if (typeof Object.getOwnPropertySymbols === 'function') { 69 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 70 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 71 })); 72 } 73 74 ownKeys.forEach(function (key) { 75 _defineProperty(target, key, source[key]); 76 }); 77 } 78 79 return target; 80 } 81 82 function _inherits(subClass, superClass) { 83 if (typeof superClass !== "function" && superClass !== null) { 84 throw new TypeError("Super expression must either be null or a function"); 85 } 86 87 subClass.prototype = Object.create(superClass && superClass.prototype, { 88 constructor: { 89 value: subClass, 90 writable: true, 91 configurable: true 92 } 93 }); 94 if (superClass) _setPrototypeOf(subClass, superClass); 95 } 96 97 function _getPrototypeOf(o) { 98 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { 99 return o.__proto__ || Object.getPrototypeOf(o); 100 }; 101 return _getPrototypeOf(o); 102 } 103 104 function _setPrototypeOf(o, p) { 105 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { 106 o.__proto__ = p; 107 return o; 108 }; 109 110 return _setPrototypeOf(o, p); 111 } 112 113 function _assertThisInitialized(self) { 114 if (self === void 0) { 115 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 116 } 117 118 return self; 119 } 120 121 function _possibleConstructorReturn(self, call) { 122 if (call && (typeof call === "object" || typeof call === "function")) { 123 return call; 124 } 125 126 return _assertThisInitialized(self); 127 } 128 129 function _toConsumableArray(arr) { 130 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); 131 } 132 133 function _arrayWithoutHoles(arr) { 134 if (Array.isArray(arr)) { 135 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; 136 137 return arr2; 138 } 139 } 140 141 function _iterableToArray(iter) { 142 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); 143 } 144 145 function _nonIterableSpread() { 146 throw new TypeError("Invalid attempt to spread non-iterable instance"); 147 } 148 149 /* 150 ** Generic functions which are not dependent on ApexCharts 151 */ 152 var Utils = 153 /*#__PURE__*/ 154 function () { 155 function Utils() { 156 _classCallCheck(this, Utils); 157 } 158 159 _createClass(Utils, [{ 160 key: "shadeRGBColor", 161 value: function shadeRGBColor(percent, color) { 162 var f = color.split(','), 163 t = percent < 0 ? 0 : 255, 164 p = percent < 0 ? percent * -1 : percent, 165 R = parseInt(f[0].slice(4)), 166 G = parseInt(f[1]), 167 B = parseInt(f[2]); 168 return 'rgb(' + (Math.round((t - R) * p) + R) + ',' + (Math.round((t - G) * p) + G) + ',' + (Math.round((t - B) * p) + B) + ')'; 169 } 170 }, { 171 key: "shadeHexColor", 172 value: function shadeHexColor(percent, color) { 173 var f = parseInt(color.slice(1), 16), 174 t = percent < 0 ? 0 : 255, 175 p = percent < 0 ? percent * -1 : percent, 176 R = f >> 16, 177 G = f >> 8 & 0x00ff, 178 B = f & 0x0000ff; 179 return '#' + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1); 180 } // beautiful color shading blending code 181 // http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors 182 183 }, { 184 key: "shadeColor", 185 value: function shadeColor(p, color) { 186 if (color.length > 7) return this.shadeRGBColor(p, color);else return this.shadeHexColor(p, color); 187 } 188 }], [{ 189 key: "bind", 190 value: function bind(fn, me) { 191 return function () { 192 return fn.apply(me, arguments); 193 }; 194 } 195 }, { 196 key: "isObject", 197 value: function isObject(item) { 198 return item && _typeof(item) === 'object' && !Array.isArray(item) && item != null; 199 } 200 }, { 201 key: "listToArray", 202 value: function listToArray(list) { 203 var i, 204 array = []; 205 206 for (i = 0; i < list.length; i++) { 207 array[i] = list[i]; 208 } 209 210 return array; 211 } // to extend defaults with user options 212 // credit: http://stackoverflow.com/questions/27936772/deep-object-merging-in-es6-es7#answer-34749873 213 214 }, { 215 key: "extend", 216 value: function extend(target, source) { 217 var _this = this; 218 219 if (typeof Object.assign !== 'function') { 220 221 (function () { 222 Object.assign = function (target) { 223 224 if (target === undefined || target === null) { 225 throw new TypeError('Cannot convert undefined or null to object'); 226 } 227 228 var output = Object(target); 229 230 for (var index = 1; index < arguments.length; index++) { 231 var _source = arguments[index]; 232 233 if (_source !== undefined && _source !== null) { 234 for (var nextKey in _source) { 235 if (_source.hasOwnProperty(nextKey)) { 236 output[nextKey] = _source[nextKey]; 237 } 238 } 239 } 240 } 241 242 return output; 243 }; 244 })(); 245 } 246 247 var output = Object.assign({}, target); 248 249 if (this.isObject(target) && this.isObject(source)) { 250 Object.keys(source).forEach(function (key) { 251 if (_this.isObject(source[key])) { 252 if (!(key in target)) { 253 Object.assign(output, _defineProperty({}, key, source[key])); 254 } else { 255 output[key] = _this.extend(target[key], source[key]); 256 } 257 } else { 258 Object.assign(output, _defineProperty({}, key, source[key])); 259 } 260 }); 261 } 262 263 return output; 264 } 265 }, { 266 key: "extendArray", 267 value: function extendArray(arrToExtend, resultArr) { 268 var extendedArr = []; 269 arrToExtend.map(function (item) { 270 extendedArr.push(Utils.extend(resultArr, item)); 271 }); 272 arrToExtend = extendedArr; 273 return arrToExtend; 274 } // If month counter exceeds 12, it starts again from 1 275 276 }, { 277 key: "monthMod", 278 value: function monthMod(month) { 279 return month % 12; 280 } 281 }, { 282 key: "addProps", 283 value: function addProps(obj, arr, val) { 284 if (typeof arr === 'string') { 285 arr = arr.split('.'); 286 } 287 288 obj[arr[0]] = obj[arr[0]] || {}; 289 var tmpObj = obj[arr[0]]; 290 291 if (arr.length > 1) { 292 arr.shift(); 293 this.addProps(tmpObj, arr, val); 294 } else { 295 obj[arr[0]] = val; 296 } 297 298 return obj;
299 } 300 }, { 301 key: "clone", 302 value: function clone(source) { 303 if (Object.prototype.toString.call(source) === '[object Array]') { 304 var cloneResult = []; 305 306 for (var i = 0; i < source.length; i++) { 307 cloneResult[i] = this.clone(source[i]); 308 } 309 310 return cloneResult; 311 } else if (_typeof(source) === 'object') { 312 var _cloneResult = {}; 313 314 for (var prop in source) { 315 if (source.hasOwnProperty(prop)) { 316 _cloneResult[prop] = this.clone(source[prop]); 317 } 318 } 319 320 return _cloneResult; 321 } else { 322 return source; 323 } 324 } 325 }, { 326 key: "log10", 327 value: function log10(x) { 328 return Math.log(x) / Math.LN10; 329 } 330 }, { 331 key: "roundToBase10", 332 value: function roundToBase10(x) { 333 return Math.pow(10, Math.floor(Math.log10(x))); 334 } 335 }, { 336 key: "roundToBase", 337 value: function roundToBase(x, base) { 338 return Math.pow(base, Math.floor(Math.log(x) / Math.log(base))); 339 } 340 }, { 341 key: "parseNumber", 342 value: function parseNumber(val) { 343 if (val === null) return val; 344 return parseFloat(val); 345 } 346 }, { 347 key: "noExponents", 348 value: function noExponents(val) { 349 var data = String(val).split(/[eE]/); 350 if (data.length == 1) return data[0]; 351 var z = '', 352 sign = val < 0 ? '-' : '', 353 str = data[0].replace('.', ''), 354 mag = Number(data[1]) + 1; 355 356 if (mag < 0) { 357 z = sign + '0.'; 358 359 while (mag++) { 360 z += '0'; 361 } 362 363 return z + str.replace(/^\-/, ''); 364 } 365 366 mag -= str.length; 367 368 while (mag--) { 369 z += '0'; 370 } 371 372 return str + z; 373 } 374 }, { 375 key: "getDimensions", 376 value: function getDimensions(el) { 377 var computedStyle = getComputedStyle(el); 378 var ret = []; 379 var elementHeight = el.clientHeight; 380 var elementWidth = el.clientWidth; 381 elementHeight -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom); 382 elementWidth -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight); 383 ret.push(elementWidth); 384 ret.push(elementHeight); 385 return ret; 386 } 387 }, { 388 key: "getBoundingClientRect", 389 value: function getBoundingClientRect(element) { 390 var rect = element.getBoundingClientRect(); 391 return { 392 top: rect.top, 393 right: rect.right, 394 bottom: rect.bottom, 395 left: rect.left, 396 width: rect.width, 397 height: rect.height, 398 x: rect.x, 399 y: rect.y 400 }; 401 } // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-12342275 402 403 }, { 404 key: "hexToRgba", 405 value: function hexToRgba() { 406 var hex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '#999999'; 407 var opacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.6; 408 409 if (hex.substring(0, 1) !== '#') { 410 hex = '#999999'; 411 } 412 413 var h = hex.replace('#', ''); 414 h = h.match(new RegExp('(.{' + h.length / 3 + '})', 'g')); 415 416 for (var i = 0; i < h.length; i++) { 417 h[i] = parseInt(h[i].length === 1 ? h[i] + h[i] : h[i], 16); 418 } 419 420 if (typeof opacity !== 'undefined') h.push(opacity); 421 return 'rgba(' + h.join(',') + ')'; 422 } 423 }, { 424 key: "getOpacityFromRGBA", 425 value: function getOpacityFromRGBA(rgba) { 426 rgba = rgba.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); 427 return rgba[3]; 428 } 429 }, { 430 key: "rgb2hex", 431 value: function rgb2hex(rgb) { 432 rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); 433 return rgb && rgb.length === 4 ? '#' + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[3], 10).toString(16)).slice(-2) : ''; 434 } 435 }, { 436 key: "isColorHex", 437 value: function isColorHex(color) { 438 return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); 439 } 440 }, { 441 key: "polarToCartesian", 442 value: function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
443 var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0; 444 return { 445 x: centerX + radius * Math.cos(angleInRadians), 446 y: centerY + radius * Math.sin(angleInRadians) 447 }; 448 } 449 }, { 450 key: "escapeString", 451 value: function escapeString(str) { 452 var escapeWith = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'x'; 453 var newStr = str.toString().slice(); 454 newStr = newStr.replace(/[` ~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, escapeWith); 455 return newStr; 456 } 457 }, { 458 key: "negToZero", 459 value: function negToZero(val) { 460 return val < 0 ? 0 : val; 461 } 462 }, { 463 key: "moveIndexInArray", 464 value: function moveIndexInArray(arr, old_index, new_index) { 465 if (new_index >= arr.length) { 466 var k = new_index - arr.length + 1; 467 468 while (k--) { 469 arr.push(undefined); 470 } 471 } 472 473 arr.splice(new_index, 0, arr.splice(old_index, 1)[0]); 474 return arr; 475 } 476 }, { 477 key: "extractNumber", 478 value: function extractNumber(s) { 479 return parseFloat(s.replace(/[^\d\.]*/g, '')); 480 } 481 }, { 482 key: "randomString", 483 value: function randomString(len) { 484 var text = ''; 485 var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 486 487 for (var i = 0; i < len; i++) { 488 text += possible.charAt(Math.floor(Math.random() * possible.length)); 489 } 490 491 return text; 492 } 493 }, { 494 key: "findAncestor", 495 value: function findAncestor(el, cls) { 496 while ((el = el.parentElement) && !el.classList.contains(cls)) { 497 } 498 499 return el; 500 } 501 }, { 502 key: "setELstyles", 503 value: function setELstyles(el, styles) { 504 for (var key in styles) { 505 if (styles.hasOwnProperty(key)) { 506 el.style.key = styles[key]; 507 } 508 } 509 } 510 }, { 511 key: "isNumber", 512 value: function isNumber(value) { 513 return !isNaN(value) && parseFloat(Number(value)) === value && !isNaN(parseInt(value, 10)); 514 } 515 }, { 516 key: "isFloat", 517 value: function isFloat(n) { 518 return Number(n) === n && n % 1 !== 0; 519 } 520 }, { 521 key: "isSafari", 522 value: function isSafari() { 523 return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 524 } 525 }, { 526 key: "isFirefox", 527 value: function isFirefox() { 528 return navigator.userAgent.toLowerCase().indexOf('firefox') > -1; 529 } 530 }, { 531 key: "isIE11", 532 value: function isIE11() { 533 if (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.appVersion.indexOf('Trident/') > -1) { 534 return true; 535 } 536 } 537 }, { 538 key: "isIE", 539 value: function isIE() { 540 var ua = window.navigator.userAgent; 541 var msie = ua.indexOf('MSIE '); 542 543 if (msie > 0) { 544 // IE 10 or older => return version number 545 return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); 546 } 547 548 var trident = ua.indexOf('Trident/'); 549 550 if (trident > 0) { 551 // IE 11 => return version number 552 var rv = ua.indexOf('rv:'); 553 return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); 554 } 555 556 var edge = ua.indexOf('Edge/'); 557 558 if (edge > 0) { 559 // Edge (IE 12+) => return version number 560 return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); 561 } // other browser 562 563 564 return false; 565 } 566 }]); 567 568 return Utils; 569 }(); 570 571 /** 572 * ApexCharts Filters Class for setting hover/active states on the paths. 573 * 574 * @module Formatters 575 **/ 576 577 var Filters = 578 /*#__PURE__*/ 579 function () { 580 function Filters(ctx) { 581 _classCallCheck(this, Filters); 582 583 this.ctx = ctx; 584 this.w = ctx.w; 585 } // create a re-usable filter which can be appended other filter effects and applied to multiple elements 586 587 588 _createClass(Filters, [{ 589 key: "getDefaultFilter", 590 value: function getDefaultFilter(el, i) { 591 var w = this.w; 592 el.unfilter(true); 593 var filter = new window.SVG.Filter();
594 filter.size('120%', '180%', '-5%', '-40%'); 595 596 if (w.config.states.normal.filter !== 'none') { 597 this.applyFilter(el, i, w.config.states.normal.filter.type, w.config.states.normal.filter.value); 598 } else { 599 if (w.config.chart.dropShadow.enabled) { 600 this.dropShadow(el, w.config.chart.dropShadow, i); 601 } 602 } 603 } 604 }, { 605 key: "addNormalFilter", 606 value: function addNormalFilter(el, i) { 607 var w = this.w; 608 609 if (w.config.chart.dropShadow.enabled) { 610 this.dropShadow(el, w.config.chart.dropShadow, i); 611 } 612 } // appends dropShadow to the filter object which can be chained with other filter effects 613 614 }, { 615 key: "addLightenFilter", 616 value: function addLightenFilter(el, i, attrs) { 617 var _this = this; 618 619 var w = this.w; 620 var intensity = attrs.intensity; 621 622 if (Utils.isFirefox()) { 623 return; 624 } 625 626 el.unfilter(true); 627 var filter = new window.SVG.Filter(); 628 filter.size('120%', '180%', '-5%', '-40%'); 629 el.filter(function (add) { 630 var shadowAttr = w.config.chart.dropShadow; 631 632 if (shadowAttr.enabled) { 633 filter = _this.addShadow(add, i, shadowAttr); 634 } else { 635 filter = add; 636 } 637 638 filter.componentTransfer({ 639 rgb: { 640 type: 'linear', 641 slope: 1.5, 642 intercept: intensity 643 } 644 }); 645 }); 646 el.filterer.node.setAttribute('filterUnits', 'userSpaceOnUse'); 647 } // appends dropShadow to the filter object which can be chained with other filter effects 648 649 }, { 650 key: "addDarkenFilter", 651 value: function addDarkenFilter(el, i, attrs) { 652 var _this2 = this; 653 654 var w = this.w; 655 var intensity = attrs.intensity; 656 657 if (Utils.isFirefox()) { 658 return; 659 } 660 661 el.unfilter(true); 662 var filter = new window.SVG.Filter(); 663 filter.size('120%', '180%', '-5%', '-40%'); 664 el.filter(function (add) { 665 var shadowAttr = w.config.chart.dropShadow; 666 667 if (shadowAttr.enabled) { 668 filter = _this2.addShadow(add, i, shadowAttr); 669 } else { 670 filter = add; 671 } 672 673 filter.componentTransfer({ 674 rgb: { 675 type: 'linear', 676 slope: intensity 677 } 678 }); 679 }); 680 el.filterer.node.setAttribute('filterUnits', 'userSpaceOnUse'); 681 } 682 }, { 683 key: "applyFilter", 684 value: function applyFilter(el, i, filter) { 685 var intensity = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0.5; 686 687 switch (filter) { 688 case 'none': 689 { 690 this.addNormalFilter(el, i); 691 break; 692 } 693 694 case 'lighten': 695 { 696 this.addLightenFilter(el, i, { 697 intensity: intensity 698 }); 699 break; 700 } 701 702 case 'darken': 703 { 704 this.addDarkenFilter(el, i, { 705 intensity: intensity 706 }); 707 break; 708 } 709 710 default: 711 // do nothing 712 break; 713 } 714 } // appends dropShadow to the filter object which can be chained with other filter effects 715 716 }, { 717 key: "addShadow", 718 value: function addShadow(add, i, attrs) { 719 var blur = attrs.blur, 720 top = attrs.top, 721 left = attrs.left, 722 color = attrs.color, 723 opacity = attrs.opacity; 724 var shadowBlur = add.flood(Array.isArray(color) ? color[i] : color, opacity).composite(add.sourceAlpha, 'in').offset(left, top).gaussianBlur(blur).merge(add.source); 725 return add.blend(add.source, shadowBlur); 726 } // directly adds dropShadow to the element and returns the same element. 727 // the only way it is different from the addShadow() function is that addShadow is chainable to other filters, while this function discards all filters and add dropShadow 728 729 }, { 730 key: "dropShadow", 731 value: function dropShadow(el, attrs) { 732 var i = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 733 var top = attrs.top, 734 left = attrs.left, 735 blur = attrs.blur, 736 color = attrs.color, 737 opacity = attrs.opacity, 738 noUserSpaceOnUse = attrs.noUserSpaceOnUse; 739 el.unfilter(true);
740 color = Array.isArray(color) ? color[i] : color; 741 var filter = new window.SVG.Filter(); 742 filter.size('120%', '180%', '-5%', '-40%'); 743 el.filter(function (add) { 744 var shadowBlur = null; 745 746 if (Utils.isSafari() || Utils.isFirefox() || Utils.isIE()) { 747 // safari/firefox has some alternative way to use this filter 748 shadowBlur = add.flood(color, opacity).composite(add.sourceAlpha, 'in').offset(left, top).gaussianBlur(blur); 749 } else { 750 shadowBlur = add.flood(color, opacity).composite(add.sourceAlpha, 'in').offset(left, top).gaussianBlur(blur).merge(add.source); 751 } 752 753 add.blend(add.source, shadowBlur); 754 }); 755 756 if (!noUserSpaceOnUse) { 757 el.filterer.node.setAttribute('filterUnits', 'userSpaceOnUse'); 758 } 759 760 return el; 761 } 762 }, { 763 key: "setSelectionFilter", 764 value: function setSelectionFilter(el, realIndex, dataPointIndex) { 765 var w = this.w; 766 767 if (typeof w.globals.selectedDataPoints[realIndex] !== 'undefined') { 768 if (w.globals.selectedDataPoints[realIndex].indexOf(dataPointIndex) > -1) { 769 el.node.setAttribute('selected', true); 770 var activeFilter = w.config.states.active.filter; 771 772 if (activeFilter !== 'none') { 773 this.applyFilter(el, realIndex, activeFilter.type, activeFilter.value); 774 } 775 } 776 } 777 } 778 }]); 779 780 return Filters; 781 }(); 782 783 /** 784 * ApexCharts Animation Class. 785 * 786 * @module Animations 787 **/ 788 789 var Animations = 790 /*#__PURE__*/ 791 function () { 792 function Animations(ctx) { 793 _classCallCheck(this, Animations); 794 795 this.ctx = ctx; 796 this.w = ctx.w; 797 this.setEasingFunctions(); 798 } 799 800 _createClass(Animations, [{ 801 key: "setEasingFunctions", 802 value: function setEasingFunctions() { 803 var easing; 804 var userDefinedEasing = this.w.config.chart.animations.easing; 805 806 switch (userDefinedEasing) { 807 case 'linear': 808 { 809 easing = '-'; 810 break; 811 } 812 813 case 'easein': 814 { 815 easing = '<'; 816 break; 817 } 818 819 case 'easeout': 820 { 821 easing = '>'; 822 break; 823 } 824 825 case 'easeinout': 826 { 827 easing = '<>'; 828 break; 829 } 830 831 case 'swing': 832 { 833 easing = function easing(pos) { 834 var s = 1.70158; 835 return (pos -= 1) * pos * ((s + 1) * pos + s) + 1; 836 }; 837 838 break; 839 } 840 841 case 'bounce': 842 { 843 easing = function easing(pos) { 844 if (pos < 1 / 2.75) { 845 return 7.5625 * pos * pos; 846 } else if (pos < 2 / 2.75) { 847 return 7.5625 * (pos -= 1.5 / 2.75) * pos + 0.75; 848 } else if (pos < 2.5 / 2.75) { 849 return 7.5625 * (pos -= 2.25 / 2.75) * pos + 0.9375; 850 } else { 851 return 7.5625 * (pos -= 2.625 / 2.75) * pos + 0.984375; 852 } 853 }; 854 855 break; 856 } 857 858 case 'elastic': 859 { 860 easing = function easing(pos) { 861 if (pos === !!pos) return pos; 862 return Math.pow(2, -10 * pos) * Math.sin((pos - 0.075) * (2 * Math.PI) / 0.3) + 1; 863 }; 864 865 break; 866 } 867 868 default: 869 { 870 easing = '<>'; 871 } 872 } 873 874 this.w.globals.easing = easing; 875 } 876 }, { 877 key: "animateLine", 878 value: function animateLine(el, from, to, speed) { 879 el.attr(from).animate(speed).attr(to); 880 } 881 /* 882 ** Animate radius of a circle element 883 */ 884 885 }, { 886 key: "animateCircleRadius", 887 value: function animateCircleRadius(el, from, to, speed, easing) { 888 if (!from) from = 0; 889 el.attr({ 890 r: from 891 }).animate(speed, easing).attr({ 892 r: to 893 }); 894 } 895 /* 896 ** Animate radius and position of a circle element 897 */ 898 899 }, { 900 key: "animateCircle", 901 value: function animateCircle(el, from, to, speed, easing) { 902 el.attr({ 903 r: from.r, 904 cx: from.cx, 905 cy: from.cy 906 }).animate(speed, easing).attr({ 907 r: to.r, 908 cx: to.cx, 909 cy: to.cy 910 }); 911 } 912 /* 913 ** Animate rect properties 914 */ 915 916 }, { 917 key: "animateRect",
918 value: function animateRect(el, from, to, speed, fn) { 919 el.attr(from).animate(speed).attr(to).afterAll(function () { 920 fn(); 921 }); 922 } 923 }, { 924 key: "animatePathsGradually", 925 value: function animatePathsGradually(params) { 926 var el = params.el, 927 j = params.j, 928 pathFrom = params.pathFrom, 929 pathTo = params.pathTo, 930 speed = params.speed, 931 delay = params.delay, 932 strokeWidth = params.strokeWidth; 933 var me = this; 934 var w = this.w; 935 var delayFactor = 0; 936 937 if (w.config.chart.animations.animateGradually.enabled) { 938 delayFactor = w.config.chart.animations.animateGradually.delay; 939 } 940 941 if (w.config.chart.animations.dynamicAnimation.enabled && w.globals.dataChanged) { 942 delayFactor = 0; 943 } 944 945 me.morphSVG(el, j, pathFrom, pathTo, speed, strokeWidth, delay * delayFactor); 946 } 947 }, { 948 key: "showDelayedElements", 949 value: function showDelayedElements() { 950 this.w.globals.delayedElements.forEach(function (d) { 951 var ele = d.el; 952 ele.classList.remove('hidden'); 953 }); 954 } // SVG.js animation for morphing one path to another 955 956 }, { 957 key: "morphSVG", 958 value: function morphSVG(el, j, pathFrom, pathTo, speed, strokeWidth, delay) { 959 var _this = this; 960 961 var w = this.w; 962 963 if (!pathFrom) { 964 pathFrom = el.attr('pathFrom'); 965 } 966 967 if (!pathTo) { 968 pathTo = el.attr('pathTo'); 969 } 970 971 if (!pathFrom || pathFrom.indexOf('undefined') > -1 || pathFrom.indexOf('NaN') > -1) { 972 pathFrom = "M 0 ".concat(w.globals.gridHeight); 973 speed = 1; 974 } 975 976 if (pathTo.indexOf('undefined') > -1 || pathTo.indexOf('NaN') > -1) { 977 pathTo = "M 0 ".concat(w.globals.gridHeight); 978 speed = 1; 979 } 980 981 if (!w.globals.shouldAnimate) { 982 speed = 1; 983 } 984 985 el.plot(pathFrom).animate(1, w.globals.easing, delay).plot(pathFrom).animate(speed, w.globals.easing, delay).plot(pathTo).afterAll(function () { 986 // a flag to indicate that the original mount function can return true now as animation finished here 987 if (Utils.isNumber(j)) { 988 if (j === w.globals.series[w.globals.maxValsInArrayIndex].length - 2 && w.globals.shouldAnimate) { 989 w.globals.animationEnded = true; 990 } 991 } else if (w.globals.shouldAnimate) { 992 w.globals.animationEnded = true; 993 994 if (typeof w.config.chart.events.animationEnd === 'function') { 995 w.config.chart.events.animationEnd(_this.ctx, w); 996 } 997 } 998 999 _this.showDelayedElements(); 1000 }); 1001 } 1002 }]); 1003 1004 return Animations; 1005 }(); 1006 1007 /** 1008 * ApexCharts Graphics Class for all drawing operations. 1009 * 1010 * @module Graphics 1011 **/ 1012 1013 var Graphics = 1014 /*#__PURE__*/ 1015 function () { 1016 function Graphics(ctx) { 1017 _classCallCheck(this, Graphics); 1018 1019 this.ctx = ctx; 1020 this.w = ctx.w; 1021 } 1022 1023 _createClass(Graphics, [{ 1024 key: "drawLine", 1025 value: function drawLine(x1, y1, x2, y2) { 1026 var lineColor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '#a8a8a8'; 1027 var dashArray = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 1028 var strokeWidth = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null; 1029 var w = this.w; 1030 var line = w.globals.dom.Paper.line().attr({ 1031 x1: x1, 1032 y1: y1, 1033 x2: x2, 1034 y2: y2, 1035 stroke: lineColor, 1036 'stroke-dasharray': dashArray, 1037 'stroke-width': strokeWidth 1038 }); 1039 return line; 1040 } 1041 }, { 1042 key: "drawRect", 1043 value: function drawRect() { 1044 var x1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1045 var y1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 1046 var x2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 1047 var y2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; 1048 var radius = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; 1049 var color = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : '#fefefe'; 1050 var opacity = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 1; 1051 var strokeWidth = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null; 1052 var strokeColor = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : null; 1053 var strokeDashArray = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 0; 1054 var w = this.w; 1055 var rect = w.globals.dom.Paper.rect(); 1056 rect.attr({ 1057 x: x1, 1058 y: y1, 1059 width: x2 > 0 ? x2 : 0, 1060 height: y2 > 0 ? y2 : 0, 1061 rx: radius, 1062 ry: radius, 1063 fill: color, 1064 opacity: opacity, 1065 'stroke-width': strokeWidth !== null ? strokeWidth : 0, 1066 stroke: strokeColor !== null ? strokeColor : 'none', 1067 'stroke-dasharray': strokeDashArray 1068 }); 1069 return rect; 1070 } 1071 }, { 1072 key: "drawPolygon", 1073 value: function drawPolygon(polygonString) { 1074 var stroke = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '#e1e1e1'; 1075 var fill = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'none'; 1076 var w = this.w; 1077 var polygon = w.globals.dom.Paper.polygon(polygonString).attr({ 1078 fill: fill, 1079 stroke: stroke 1080 }); 1081 return polygon; 1082 } 1083 }, { 1084 key: "drawCircle", 1085 value: function drawCircle(radius) { 1086 var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 1087 var w = this.w; 1088 var c = w.globals.dom.Paper.circle(radius * 2); 1089 1090 if (attrs !== null) { 1091 c.attr(attrs); 1092 } 1093 1094 return c; 1095 } 1096 }, { 1097 key: "drawPath", 1098 value: function drawPath(_ref) { 1099 var _ref$d = _ref.d, 1100 d = _ref$d === void 0 ? '' : _ref$d, 1101 _ref$stroke = _ref.stroke, 1102 stroke = _ref$stroke === void 0 ? '#a8a8a8' : _ref$stroke, 1103 _ref$strokeWidth = _ref.strokeWidth, 1104 strokeWidth = _ref$strokeWidth === void 0 ? 1 : _ref$strokeWidth, 1105 fill = _ref.fill, 1106 _ref$fillOpacity = _ref.fillOpacity, 1107 fillOpacity = _ref$fillOpacity === void 0 ? 1 : _ref$fillOpacity, 1108 _ref$strokeOpacity = _ref.strokeOpacity, 1109 strokeOpacity = _ref$strokeOpacity === void 0 ? 1 : _ref$strokeOpacity, 1110 classes = _ref.classes, 1111 _ref$strokeLinecap = _ref.strokeLinecap, 1112 strokeLinecap = _ref$strokeLinecap === void 0 ? null : _ref$strokeLinecap, 1113 _ref$strokeDashArray = _ref.strokeDashArray, 1114 strokeDashArray = _ref$strokeDashArray === void 0 ? 0 : _ref$strokeDashArray; 1115 var w = this.w; 1116 1117 if (strokeLinecap === null) { 1118 strokeLinecap = w.config.stroke.lineCap; 1119 } 1120 1121 if (d.indexOf('undefined') > -1 || d.indexOf('NaN') > -1) { 1122 d = "M 0 ".concat(w.globals.gridHeight); 1123 } 1124 1125 var p = w.globals.dom.Paper.path(d).attr({ 1126 fill: fill, 1127 'fill-opacity': fillOpacity, 1128 stroke: stroke, 1129 'stroke-opacity': strokeOpacity, 1130 'stroke-linecap': strokeLinecap, 1131 'stroke-width': strokeWidth, 1132 'stroke-dasharray': strokeDashArray, 1133 class: classes 1134 }); 1135 return p; 1136 } 1137 }, { 1138 key: "group", 1139 value: function group() { 1140 var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 1141 var w = this.w; 1142 var g = w.globals.dom.Paper.group(); 1143 1144 if (attrs !== null) { 1145 g.attr(attrs); 1146 } 1147 1148 return g; 1149 } 1150 }, { 1151 key: "move", 1152 value: function move(x, y) { 1153 var move = ['M', x, y].join(' '); 1154 return move; 1155 } 1156 }, { 1157 key: "line", 1158 value: function line(x, y) { 1159 var hORv = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 1160 var line = null; 1161 1162 if (hORv === null) { 1163 line = ['L', x, y].join(' '); 1164 } else if (hORv === 'H') { 1165 line = ['H', x].join(' '); 1166 } else if (hORv === 'V') { 1167 line = ['V', y].join(' '); 1168 } 1169 1170 return line; 1171 } 1172 }, { 1173 key: "curve", 1174 value: function curve(x1, y1, x2, y2, x, y) { 1175 var curve = ['C', x1, y1, x2, y2, x, y].join(' '); 1176 return curve; 1177 } 1178 }, { 1179 key: "quadraticCurve", 1180 value: function quadraticCurve(x1, y1, x, y) { 1181 var curve = ['Q', x1, y1, x, y].join(' '); 1182 return curve; 1183 } 1184 }, { 1185 key: "arc", 1186 value: function arc(rx, ry, axisRotation, largeArcFlag, sweepFlag, x, y) { 1187 var relative = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false; 1188 var coord = 'A'; 1189 if (relative) coord = 'a'; 1190 var arc = [coord, rx, ry, axisRotation, largeArcFlag, sweepFlag, x, y].join(' '); 1191 return arc; 1192 } 1193 /** 1194 * @memberof Graphics 1195 * @param {object} 1196 * i = series's index 1197 * realIndex = realIndex is series's actual index when it was drawn time. After several redraws, the iterating "i" may change in loops, but realIndex doesn't 1198 * pathFrom = existing pathFrom to animateTo 1199 * pathTo = new Path to which d attr will be animated from pathFrom to pathTo 1200 * stroke = line Color 1201 * strokeWidth = width of path Line 1202 * fill = it can be gradient, single color, pattern or image 1203 * animationDelay = how much to delay when starting animation (in milliseconds) 1204 * dataChangeSpeed = for dynamic animations, when data changes 1205 * className = class attribute to add 1206 * @return {object} svg.js path object 1207 **/ 1208 1209 }, { 1210 key: "renderPaths", 1211 value: function renderPaths(_ref2) { 1212 var i = _ref2.i, 1213 j = _ref2.j, 1214 realIndex = _ref2.realIndex, 1215 pathFrom = _ref2.pathFrom, 1216 pathTo = _ref2.pathTo, 1217 stroke = _ref2.stroke, 1218 strokeWidth = _ref2.strokeWidth, 1219 strokeLinecap = _ref2.strokeLinecap, 1220 fill = _ref2.fill, 1221 animationDelay = _ref2.animationDelay, 1222 initialSpeed = _ref2.initialSpeed, 1223 dataChangeSpeed = _ref2.dataChangeSpeed, 1224 className = _ref2.className, 1225 id = _ref2.id, 1226 _ref2$shouldClipToGri = _ref2.shouldClipToGrid, 1227 shouldClipToGrid = _ref2$shouldClipToGri === void 0 ? true : _ref2$shouldClipToGri, 1228 _ref2$bindEventsOnPat = _ref2.bindEventsOnPaths, 1229 bindEventsOnPaths = _ref2$bindEventsOnPat === void 0 ? true : _ref2$bindEventsOnPat, 1230 _ref2$drawShadow = _ref2.drawShadow, 1231 drawShadow = _ref2$drawShadow === void 0 ? true : _ref2$drawShadow; 1232 var w = this.w; 1233 var filters = new Filters(this.ctx); 1234 var anim = new Animations(this.ctx); 1235 var initialAnim = this.w.config.chart.animations.enabled; 1236 var dynamicAnim = initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled; 1237 var d; 1238 var shouldAnimate = !!(initialAnim && !w.globals.resized || dynamicAnim && w.globals.dataChanged && w.globals.shouldAnimate); 1239 1240 if (shouldAnimate) { 1241 d = pathFrom; 1242 } else { 1243 d = pathTo; 1244 this.w.globals.animationEnded = true; 1245 } 1246 1247 var strokeDashArrayOpt = w.config.stroke.dashArray; 1248 var strokeDashArray = 0; 1249 1250 if (Array.isArray(strokeDashArrayOpt)) { 1251 strokeDashArray = strokeDashArrayOpt[realIndex]; 1252 } else { 1253 strokeDashArray = w.config.stroke.dashArray; 1254 } 1255 1256 var el = this.drawPath({ 1257 d: d, 1258 stroke: stroke, 1259 strokeWidth: strokeWidth, 1260 fill: fill, 1261 fillOpacity: 1, 1262 classes: className, 1263 strokeLinecap: strokeLinecap,
1264 strokeDashArray: strokeDashArray 1265 }); 1266 el.attr('id', "".concat(id, "-").concat(i)); 1267 el.attr('index', realIndex); 1268 1269 if (shouldClipToGrid) { 1270 el.attr({ 1271 'clip-path': "url(#gridRectMask".concat(w.globals.cuid, ")") 1272 }); 1273 } // const defaultFilter = el.filterer 1274 1275 1276 if (w.config.states.normal.filter.type !== 'none') { 1277 filters.getDefaultFilter(el, realIndex); 1278 } else { 1279 if (w.config.chart.dropShadow.enabled && drawShadow) { 1280 if (!w.config.chart.dropShadow.enabledSeries || w.config.chart.dropShadow.enabledSeries && w.config.chart.dropShadow.enabledSeries.indexOf(realIndex) !== -1) { 1281 var shadow = w.config.chart.dropShadow; 1282 filters.dropShadow(el, shadow, realIndex); 1283 } 1284 } 1285 } 1286 1287 if (bindEventsOnPaths) { 1288 el.node.addEventListener('mouseenter', this.pathMouseEnter.bind(this, el)); 1289 el.node.addEventListener('mouseleave', this.pathMouseLeave.bind(this, el)); 1290 el.node.addEventListener('mousedown', this.pathMouseDown.bind(this, el)); 1291 } 1292 1293 el.attr({ 1294 pathTo: pathTo, 1295 pathFrom: pathFrom 1296 }); 1297 var defaultAnimateOpts = { 1298 el: el, 1299 j: j, 1300 pathFrom: pathFrom, 1301 pathTo: pathTo, 1302 strokeWidth: strokeWidth 1303 }; 1304 1305 if (initialAnim && !w.globals.resized && !w.globals.dataChanged) { 1306 anim.animatePathsGradually(_objectSpread({}, defaultAnimateOpts, { 1307 speed: initialSpeed, 1308 delay: animationDelay 1309 })); 1310 } else { 1311 if (w.globals.resized || !w.globals.dataChanged) { 1312 anim.showDelayedElements(); 1313 } 1314 } 1315 1316 if (w.globals.dataChanged && dynamicAnim && shouldAnimate) { 1317 anim.animatePathsGradually(_objectSpread({}, defaultAnimateOpts, { 1318 speed: dataChangeSpeed 1319 })); 1320 } 1321 1322 return el; 1323 } 1324 }, { 1325 key: "drawPattern", 1326 value: function drawPattern(style, width, height) { 1327 var stroke = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '#a8a8a8'; 1328 var strokeWidth = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; 1329 var w = this.w; 1330 var p = w.globals.dom.Paper.pattern(width, height, function (add) { 1331 if (style === 'horizontalLines') { 1332 add.line(0, 0, height, 0).stroke({ 1333 color: stroke, 1334 width: strokeWidth + 1 1335 }); 1336 } else if (style === 'verticalLines') { 1337 add.line(0, 0, 0, width).stroke({ 1338 color: stroke, 1339 width: strokeWidth + 1 1340 }); 1341 } else if (style === 'slantedLines') { 1342 add.line(0, 0, width, height).stroke({ 1343 color: stroke, 1344 width: strokeWidth 1345 }); 1346 } else if (style === 'squares') { 1347 add.rect(width, height).fill('none').stroke({ 1348 color: stroke, 1349 width: strokeWidth 1350 }); 1351 } else if (style === 'circles') { 1352 add.circle(width).fill('none').stroke({ 1353 color: stroke, 1354 width: strokeWidth 1355 }); 1356 } 1357 }); 1358 return p; 1359 } 1360 }, { 1361 key: "drawGradient", 1362 value: function drawGradient(style, gfrom, gto, opacityFrom, opacityTo) { 1363 var size = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null; 1364 var stops = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null; 1365 var colorStops = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null; 1366 var i = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 0; 1367 var w = this.w; 1368 var g; 1369 gfrom = Utils.hexToRgba(gfrom, opacityFrom); 1370 gto = Utils.hexToRgba(gto, opacityTo); 1371 var stop1 = 0; 1372 var stop2 = 1; 1373 var stop3 = 1; 1374 var stop4 = null; 1375 1376 if (stops !== null) { 1377 stop1 = typeof stops[0] !== 'undefined' ? stops[0] / 100 : 0; 1378 stop2 = typeof stops[1] !== 'undefined' ? stops[1] / 100 : 1; 1379 stop3 = typeof stops[2] !== 'undefined' ? stops[2] / 100 : 1; 1380 stop4 = typeof stops[3] !== 'undefined' ? stops[3] / 100 : null; 1381 } 1382 1383 var radial = !!(w.config.chart.type === 'donut' || w.config.chart.type === 'pie' || w.config.chart.type === 'bubble'); 1384 1385 if (colorStops === null || colorStops.length === 0) { 1386 g = w.globals.dom.Paper.gradient(radial ? 'radial' : 'linear', function (stop) { 1387 stop.at(stop1, gfrom, opacityFrom); 1388 stop.at(stop2, gto, opacityTo); 1389 stop.at(stop3, gto, opacityTo); 1390 1391 if (stop4 !== null) { 1392 stop.at(stop4, gfrom, opacityFrom); 1393 } 1394 }); 1395 } else { 1396 g = w.globals.dom.Paper.gradient(radial ? 'radial' : 'linear', function (stop) { 1397 var stops = Array.isArray(colorStops[i]) ? colorStops[i] : colorStops; 1398 stops.forEach(function (s) { 1399 stop.at(s.offset / 100, s.color, s.opacity); 1400 }); 1401 }); 1402 } 1403 1404 if (!radial) { 1405 if (style === 'vertical') { 1406 g.from(0, 0).to(0, 1); 1407 } else if (style === 'diagonal') { 1408 g.from(0, 0).to(1, 1); 1409 } else if (style === 'horizontal') { 1410 g.from(0, 1).to(1, 1); 1411 } else if (style === 'diagonal2') { 1412 g.from(0, 1).to(2, 2); 1413 } 1414 } else { 1415 var offx = w.globals.gridWidth / 2; 1416 var offy = w.globals.gridHeight / 2; 1417 1418 if (w.config.chart.type !== 'bubble') { 1419 g.attr({ 1420 gradientUnits: 'userSpaceOnUse', 1421 cx: offx, 1422 cy: offy, 1423 r: size 1424 }); 1425 } else { 1426 g.attr({ 1427 cx: 0.5, 1428 cy: 0.5, 1429 r: 0.8, 1430 fx: 0.2, 1431 fy: 0.2 1432 }); 1433 } 1434 } 1435 1436 return g; 1437 } 1438 }, { 1439 key: "drawText",
1440 value: function drawText(opts) { 1441 var w = this.w; 1442 var x = opts.x, 1443 y = opts.y, 1444 text = opts.text, 1445 textAnchor = opts.textAnchor, 1446 fontSize = opts.fontSize, 1447 fontFamily = opts.fontFamily, 1448 foreColor = opts.foreColor, 1449 opacity = opts.opacity; 1450 if (typeof text === 'undefined') text = ''; 1451 1452 if (!textAnchor) { 1453 textAnchor = 'start'; 1454 } 1455 1456 if (!foreColor) { 1457 foreColor = w.config.chart.foreColor; 1458 } 1459 1460 fontFamily = fontFamily || w.config.chart.fontFamily; 1461 var elText; 1462 1463 if (Array.isArray(text)) { 1464 elText = w.globals.dom.Paper.text(function (add) { 1465 for (var i = 0; i < text.length; i++) { 1466 add.tspan(text[i]); 1467 } 1468 }); 1469 } else { 1470 elText = w.globals.dom.Paper.plain(text); 1471 } 1472 1473 elText.attr({ 1474 x: x, 1475 y: y, 1476 'text-anchor': textAnchor, 1477 'dominant-baseline': 'auto', 1478 'font-size': fontSize, 1479 'font-family': fontFamily, 1480 fill: foreColor, 1481 class: 'apexcharts-text ' + opts.cssClass ? opts.cssClass : '' 1482 }); 1483 elText.node.style.fontFamily = fontFamily; 1484 elText.node.style.opacity = opacity; 1485 return elText; 1486 } 1487 }, { 1488 key: "addTspan", 1489 value: function addTspan(textEl, text, fontFamily) { 1490 var tspan = textEl.tspan(text); 1491 1492 if (!fontFamily) { 1493 fontFamily = this.w.config.chart.fontFamily; 1494 } 1495 1496 tspan.node.style.fontFamily = fontFamily; 1497 } 1498 }, { 1499 key: "drawMarker", 1500 value: function drawMarker(x, y, opts) { 1501 x = x || 0; 1502 var size = opts.pSize || 0; 1503 var elPoint = null; 1504 1505 if (opts.shape === 'square') { 1506 var radius = opts.pRadius === undefined ? size / 2 : opts.pRadius; 1507 1508 if (y === null) { 1509 size = 0; 1510 radius = 0; 1511 } 1512 1513 var nSize = size * 1.2 + radius; 1514 var p = this.drawRect(nSize, nSize, nSize, nSize, radius); 1515 p.attr({ 1516 x: x - nSize / 2, 1517 y: y - nSize / 2, 1518 cx: x, 1519 cy: y, 1520 class: opts.class ? opts.class : '', 1521 fill: opts.pointFillColor, 1522 'fill-opacity': opts.pointFillOpacity ? opts.pointFillOpacity : 1, 1523 stroke: opts.pointStrokeColor, 1524 'stroke-width': opts.pWidth ? opts.pWidth : 0, 1525 'stroke-opacity': opts.pointStrokeOpacity ? opts.pointStrokeOpacity : 1 1526 }); 1527 elPoint = p; 1528 } else if (opts.shape === 'circle') { 1529 if (!Utils.isNumber(y)) { 1530 size = 0; 1531 y = 0; 1532 } // let nSize = size - opts.pRadius / 2 < 0 ? 0 : size - opts.pRadius / 2 1533 1534 1535 elPoint = this.drawCircle(size, { 1536 cx: x, 1537 cy: y, 1538 class: opts.class ? opts.class : '', 1539 stroke: opts.pointStrokeColor, 1540 fill: opts.pointFillColor, 1541 'fill-opacity': opts.pointFillOpacity ? opts.pointFillOpacity : 1, 1542 'stroke-width': opts.pWidth ? opts.pWidth : 0, 1543 'stroke-opacity': opts.pointStrokeOpacity ? opts.pointStrokeOpacity : 1 1544 }); 1545 } 1546 1547 return elPoint; 1548 } 1549 }, { 1550 key: "pathMouseEnter", 1551 value: function pathMouseEnter(path, e) { 1552 var w = this.w; 1553 var filters = new Filters(this.ctx); 1554 var i = parseInt(path.node.getAttribute('index')); 1555 var j = parseInt(path.node.getAttribute('j')); 1556 1557 if (typeof w.config.chart.events.dataPointMouseEnter === 'function') { 1558 w.config.chart.events.dataPointMouseEnter(e, this.ctx, { 1559 seriesIndex: i, 1560 dataPointIndex: j, 1561 w: w 1562 }); 1563 } 1564 1565 this.ctx.fireEvent('dataPointMouseEnter', [e, this.ctx, { 1566 seriesIndex: i, 1567 dataPointIndex: j, 1568 w: w 1569 }]); 1570 1571 if (w.config.states.active.filter.type !== 'none') { 1572 if (path.node.getAttribute('selected') === 'true') { 1573 return; 1574 } 1575 } 1576
1577 if (w.config.states.hover.filter.type !== 'none') { 1578 if (w.config.states.active.filter.type !== 'none' && !w.globals.isTouchDevice) { 1579 var hoverFilter = w.config.states.hover.filter; 1580 filters.applyFilter(path, i, hoverFilter.type, hoverFilter.value); 1581 } 1582 } 1583 } 1584 }, { 1585 key: "pathMouseLeave", 1586 value: function pathMouseLeave(path, e) { 1587 var w = this.w; 1588 var filters = new Filters(this.ctx); 1589 var i = parseInt(path.node.getAttribute('index')); 1590 var j = parseInt(path.node.getAttribute('j')); 1591 1592 if (typeof w.config.chart.events.dataPointMouseLeave === 'function') { 1593 w.config.chart.events.dataPointMouseLeave(e, this.ctx, { 1594 seriesIndex: i, 1595 dataPointIndex: j, 1596 w: w 1597 }); 1598 } 1599 1600 this.ctx.fireEvent('dataPointMouseLeave', [e, this.ctx, { 1601 seriesIndex: i, 1602 dataPointIndex: j, 1603 w: w 1604 }]); 1605 1606 if (w.config.states.active.filter.type !== 'none') { 1607 if (path.node.getAttribute('selected') === 'true') { 1608 return; 1609 } 1610 } 1611 1612 if (w.config.states.hover.filter.type !== 'none') { 1613 filters.getDefaultFilter(path, i); 1614 } 1615 } 1616 }, { 1617 key: "pathMouseDown", 1618 value: function pathMouseDown(path, e) { 1619 var w = this.w; 1620 var filters = new Filters(this.ctx); 1621 var i = parseInt(path.node.getAttribute('index')); 1622 var j = parseInt(path.node.getAttribute('j')); 1623 var selected = 'false'; 1624 1625 if (path.node.getAttribute('selected') === 'true') { 1626 path.node.setAttribute('selected', 'false'); 1627 1628 if (w.globals.selectedDataPoints[i].indexOf(j) > -1) { 1629 var index = w.globals.selectedDataPoints[i].indexOf(j); 1630 w.globals.selectedDataPoints[i].splice(index, 1); 1631 } 1632 } else { 1633 if (!w.config.states.active.allowMultipleDataPointsSelection && w.globals.selectedDataPoints.length > 0) { 1634 w.globals.selectedDataPoints = []; 1635 var elPaths = w.globals.dom.Paper.select('.apexcharts-series path').members; 1636 var elCircles = w.globals.dom.Paper.select('.apexcharts-series circle, .apexcharts-series rect').members; 1637 elPaths.forEach(function (elPath) { 1638 elPath.node.setAttribute('selected', 'false'); 1639 filters.getDefaultFilter(elPath, i); 1640 }); 1641 elCircles.forEach(function (circle) { 1642 circle.node.setAttribute('selected', 'false'); 1643 filters.getDefaultFilter(circle, i); 1644 }); 1645 } 1646 1647 path.node.setAttribute('selected', 'true'); 1648 selected = 'true'; 1649 1650 if (typeof w.globals.selectedDataPoints[i] === 'undefined') { 1651 w.globals.selectedDataPoints[i] = []; 1652 } 1653 1654 w.globals.selectedDataPoints[i].push(j); 1655 } 1656 1657 if (selected === 'true') { 1658 var activeFilter = w.config.states.active.filter; 1659 1660 if (activeFilter !== 'none') { 1661 filters.applyFilter(path, i, activeFilter.type, activeFilter.value); 1662 } 1663 } else { 1664 if (w.config.states.active.filter.type !== 'none') { 1665 filters.getDefaultFilter(path, i); 1666 } 1667 } 1668 1669 if (typeof w.config.chart.events.dataPointSelection === 'function') { 1670 w.config.chart.events.dataPointSelection(e, this.ctx, { 1671 selectedDataPoints: w.globals.selectedDataPoints, 1672 seriesIndex: i, 1673 dataPointIndex: j, 1674 w: w 1675 }); 1676 } 1677 1678 this.ctx.fireEvent('dataPointSelection', [e, this.ctx, { 1679 selectedDataPoints: w.globals.selectedDataPoints, 1680 seriesIndex: i, 1681 dataPointIndex: j, 1682 w: w 1683 }]); // if (this.w.config.chart.selection.selectedPoints !== undefined) { 1684 // this.w.config.chart.selection.selectedPoints(w.globals.selectedDataPoints) 1685 // } 1686 } 1687 }, {
1688 key: "rotateAroundCenter", 1689 value: function rotateAroundCenter(el) { 1690 var coord = el.getBBox(); 1691 var x = coord.x + coord.width / 2; 1692 var y = coord.y + coord.height / 2; 1693 return { 1694 x: x, 1695 y: y 1696 }; 1697 } 1698 }, { 1699 key: "getTextRects", 1700 value: function getTextRects(text, fontSize, fontFamily, transform) { 1701 var useBBox = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; 1702 var w = this.w; 1703 var virtualText = this.drawText({ 1704 x: -200, 1705 y: -200, 1706 text: text, 1707 textAnchor: 'start', 1708 fontSize: fontSize, 1709 fontFamily: fontFamily, 1710 foreColor: '#fff', 1711 opacity: 0 1712 }); 1713 1714 if (transform) { 1715 virtualText.attr('transform', transform); 1716 } 1717 1718 w.globals.dom.Paper.add(virtualText); 1719 var rect = virtualText.bbox(); 1720 1721 if (!useBBox) { 1722 rect = virtualText.node.getBoundingClientRect(); 1723 } 1724 1725 virtualText.remove(); 1726 return { 1727 width: rect.width, 1728 height: rect.height 1729 }; 1730 } 1731 /** 1732 * append ... to long text 1733 * http://stackoverflow.com/questions/9241315/trimming-text-to-a-given-pixel-width-in-svg 1734 * @memberof Graphics 1735 **/ 1736 1737 }, { 1738 key: "placeTextWithEllipsis", 1739 value: function placeTextWithEllipsis(textObj, textString, width) { 1740 textObj.textContent = textString; 1741 1742 if (textString.length > 0) { 1743 // ellipsis is needed 1744 if (textObj.getSubStringLength(0, textString.length) >= width) { 1745 for (var x = textString.length - 3; x > 0; x -= 3) { 1746 if (textObj.getSubStringLength(0, x) <= width) { 1747 textObj.textContent = textString.substring(0, x) + '...'; 1748 return; 1749 } 1750 } 1751 1752 textObj.textContent = '...'; // can't place at all 1753 } 1754 } 1755 } 1756 }], [{ 1757 key: "setAttrs", 1758 value: function setAttrs(el, attrs) { 1759 for (var key in attrs) { 1760 if (attrs.hasOwnProperty(key)) { 1761 el.setAttribute(key, attrs[key]); 1762 } 1763 } 1764 } 1765 }]); 1766 1767 return Graphics; 1768 }(); 1769 1770 const name = "en"; 1771 const options = { 1772 months: [ 1773 "January", 1774 "February", 1775 "March", 1776 "April", 1777 "May", 1778 "June", 1779 "July", 1780 "August", 1781 "September", 1782 "October", 1783 "November", 1784 "December" 1785 ], 1786 shortMonths: [ 1787 "Jan", 1788 "Feb", 1789 "Mar", 1790 "Apr", 1791 "May", 1792 "Jun", 1793 "Jul", 1794 "Aug", 1795 "Sep", 1796 "Oct", 1797 "Nov", 1798 "Dec" 1799 ], 1800 days: [ 1801 "Sunday", 1802 "Monday", 1803 "Tuesday", 1804 "Wednesday", 1805 "Thursday", 1806 "Friday", 1807 "Saturday" 1808 ], 1809 shortDays: [ 1810 "Sun", 1811 "Mon", 1812 "Tue", 1813 "Wed", 1814 "Thu", 1815 "Fri", 1816 "Sat" 1817 ], 1818 toolbar: { 1819 exportToSVG: "Download SVG", 1820 exportToPNG: "Download PNG", 1821 menu: "Menu", 1822 selection: "Selection", 1823 selectionZoom: "Selection Zoom", 1824 zoomIn: "Zoom In", 1825 zoomOut: "Zoom Out", 1826 pan: "Panning", 1827 reset: "Reset Zoom" 1828 } 1829 }; 1830 var en = { 1831 name: name, 1832 options: options 1833 }; 1834 1835 var Options = 1836 /*#__PURE__*/ 1837 function () { 1838 function Options() { 1839 _classCallCheck(this, Options); 1840 1841 this.yAxis = { 1842 show: true, 1843 showAlways: false, 1844 seriesName: undefined, 1845 opposite: false, 1846 reversed: false, 1847 logarithmic: false, 1848 tickAmount: undefined, 1849 forceNiceScale: false, 1850 max: undefined, 1851 min: undefined, 1852 floating: false, 1853 decimalsInFloat: undefined, 1854 labels: { 1855 show: true, 1856 minWidth: 0, 1857 maxWidth: 160, 1858 offsetX: 0, 1859 offsetY: 0, 1860 align: undefined, 1861 rotate: 0, 1862 padding: 20, 1863 style: { 1864 colors: [], 1865 fontSize: '11px', 1866 fontFamily: undefined, 1867 cssClass: '' 1868 }, 1869 formatter: undefined 1870 }, 1871 axisBorder: { 1872 show: false, 1873 color: '#78909C', 1874 offsetX: 0, 1875 offsetY: 0 1876 }, 1877 axisTicks: { 1878 show: false, 1879 color: '#78909C', 1880 width: 6, 1881 offsetX: 0, 1882 offsetY: 0 1883 }, 1884 title: { 1885 text: undefined, 1886 rotate: 90, 1887 offsetY: 0, 1888 offsetX: 0, 1889 style: { 1890 color: undefined, 1891 fontSize: '11px', 1892 fontFamily: undefined, 1893 cssClass: '' 1894 } 1895 }, 1896 tooltip: { 1897 enabled: false, 1898 offsetX: 0 1899 }, 1900 crosshairs: { 1901 show: true, 1902 position: 'front', 1903 stroke: { 1904 color: '#b6b6b6', 1905 width: 1, 1906 dashArray: 0 1907 } 1908 } 1909 }; 1910 this.xAxisAnnotation = { 1911 x: 0, 1912 x2: null, 1913 strokeDashArray: 1, 1914 fillColor: '#c2c2c2', 1915 borderColor: '#c2c2c2', 1916 opacity: 0.3, 1917 offsetX: 0, 1918 offsetY: 0, 1919 label: { 1920 borderColor: '#c2c2c2', 1921 borderWidth: 1, 1922 text: undefined, 1923 textAnchor: 'middle', 1924 orientation: 'vertical', 1925 position: 'top', 1926 offsetX: 0, 1927 offsetY: 0, 1928 style: { 1929 background: '#fff', 1930 color: undefined, 1931 fontSize: '11px', 1932 fontFamily: undefined, 1933 cssClass: '', 1934 padding: { 1935 left: 5, 1936 right: 5, 1937 top: 2, 1938 bottom: 2 1939 } 1940 } 1941 } 1942 }; 1943 this.yAxisAnnotation = { 1944 y: 0, 1945 y2: null, 1946 strokeDashArray: 1, 1947 fillColor: '#c2c2c2', 1948 borderColor: '#c2c2c2', 1949 opacity: 0.3, 1950 offsetX: 0, 1951 offsetY: 0, 1952 yAxisIndex: 0, 1953 label: { 1954 borderColor: '#c2c2c2', 1955 borderWidth: 1, 1956 text: undefined, 1957 textAnchor: 'end', 1958 position: 'right', 1959 offsetX: 0, 1960 offsetY: -3, 1961 style: { 1962 background: '#fff', 1963 color: undefined, 1964 fontSize: '11px', 1965 fontFamily: undefined, 1966 cssClass: '', 1967 padding: { 1968 left: 5, 1969 right: 5, 1970 top: 0, 1971 bottom: 2 1972 } 1973 } 1974 } 1975 }; 1976 this.pointAnnotation = { 1977 x: 0, 1978 y: null, 1979 yAxisIndex: 0, 1980 seriesIndex: 0, 1981 marker: { 1982 size: 0, 1983 fillColor: '#fff', 1984 strokeWidth: 2, 1985 strokeColor: '#333',
1986 shape: 'circle', 1987 offsetX: 0, 1988 offsetY: 0, 1989 radius: 2, 1990 cssClass: '' 1991 }, 1992 label: { 1993 borderColor: '#c2c2c2', 1994 borderWidth: 1, 1995 text: undefined, 1996 textAnchor: 'middle', 1997 offsetX: 0, 1998 offsetY: -15, 1999 style: { 2000 background: '#fff', 2001 color: undefined, 2002 fontSize: '11px', 2003 fontFamily: undefined, 2004 cssClass: '', 2005 padding: { 2006 left: 5, 2007 right: 5, 2008 top: 0, 2009 bottom: 2 2010 } 2011 } 2012 }, 2013 customSVG: { 2014 SVG: undefined, 2015 cssClass: undefined, 2016 offsetX: 0, 2017 offsetY: 0 2018 } 2019 }; 2020 } 2021 2022 _createClass(Options, [{ 2023 key: "init", 2024 value: function init() { 2025 return { 2026 annotations: { 2027 position: 'front', 2028 yaxis: [this.yAxisAnnotation], 2029 xaxis: [this.xAxisAnnotation], 2030 points: [this.pointAnnotation] 2031 }, 2032 chart: { 2033 animations: { 2034 enabled: true, 2035 easing: 'easeinout', 2036 // linear, easeout, easein, easeinout, swing, bounce, elastic 2037 speed: 800, 2038 animateGradually: { 2039 delay: 150, 2040 enabled: true 2041 }, 2042 dynamicAnimation: { 2043 enabled: true, 2044 speed: 350 2045 } 2046 }, 2047 background: 'transparent', 2048 locales: [en], 2049 defaultLocale: 'en', 2050 dropShadow: { 2051 enabled: false, 2052 enabledSeries: undefined, 2053 top: 2, 2054 left: 2, 2055 blur: 4, 2056 color: '#000', 2057 opacity: 0.35 2058 }, 2059 events: { 2060 animationEnd: undefined, 2061 beforeMount: undefined, 2062 mounted: undefined, 2063 updated: undefined, 2064 click: undefined, 2065 legendClick: undefined, 2066 markerClick: undefined, 2067 selection: undefined, 2068 dataPointSelection: undefined, 2069 dataPointMouseEnter: undefined, 2070 dataPointMouseLeave: undefined, 2071 beforeZoom: undefined, 2072 zoomed: undefined, 2073 scrolled: undefined 2074 }, 2075 foreColor: '#373d3f', 2076 fontFamily: 'Helvetica, Arial, sans-serif', 2077 height: 'auto', 2078 parentHeightOffset: 15, 2079 id: undefined, 2080 group: undefined, 2081 offsetX: 0, 2082 offsetY: 0, 2083 selection: { 2084 enabled: false, 2085 type: 'x', 2086 // selectedPoints: undefined, // default datapoints that should be selected automatically 2087 fill: { 2088 color: '#24292e', 2089 opacity: 0.1 2090 }, 2091 stroke: { 2092 width: 1, 2093 color: '#24292e', 2094 opacity: 0.4, 2095 dashArray: 3 2096 }, 2097 xaxis: { 2098 min: undefined, 2099 max: undefined 2100 }, 2101 yaxis: { 2102 min: undefined, 2103 max: undefined 2104 } 2105 }, 2106 sparkline: { 2107 enabled: false 2108 }, 2109 brush: { 2110 enabled: false, 2111 autoScaleYaxis: false, 2112 target: undefined 2113 }, 2114 stacked: false, 2115 stackType: 'normal', 2116 toolbar: { 2117 show: true, 2118 tools: { 2119 download: true, 2120 selection: true, 2121 zoom: true, 2122 zoomin: true, 2123 zoomout: true, 2124 pan: true, 2125 reset: true, 2126 customIcons: [] 2127 }, 2128 autoSelected: 'zoom' // accepts -> zoom, pan, selection 2129 2130 }, 2131 type: 'line', 2132 width: '100%', 2133 zoom: { 2134 enabled: true, 2135 type: 'x', 2136 // autoScaleYaxis: false, // TODO: rewrite the autoScaleY function 2137 zoomedArea: { 2138 fill: { 2139 color: '#90CAF9', 2140 opacity: 0.4 2141 }, 2142 stroke: { 2143 color: '#0D47A1', 2144 opacity: 0.4, 2145 width: 1 2146 } 2147 } 2148 } 2149 }, 2150 plotOptions: { 2151 bar: { 2152 horizontal: false, 2153 columnWidth: '70%', 2154 // should be in percent 0 - 100 2155 barHeight: '70%', 2156 // should be in percent 0 - 100 2157 distributed: false, 2158 endingShape: 'flat',
2159 colors: { 2160 ranges: [], 2161 backgroundBarColors: [], 2162 backgroundBarOpacity: 1 2163 }, 2164 dataLabels: { 2165 maxItems: 100, 2166 hideOverflowingLabels: true, 2167 position: 'top' // top, center, bottom 2168 // TODO: provide stackedLabels for stacked charts which gives additions of values 2169 2170 } 2171 }, 2172 candlestick: { 2173 colors: { 2174 upward: '#00B746', 2175 downward: '#EF403C' 2176 }, 2177 wick: { 2178 useFillColor: true 2179 } 2180 }, 2181 heatmap: { 2182 radius: 2, 2183 enableShades: true, 2184 shadeIntensity: 0.5, 2185 reverseNegativeShade: true, 2186 distributed: false, 2187 colorScale: { 2188 inverse: false, 2189 ranges: [], 2190 min: undefined, 2191 max: undefined 2192 } 2193 }, 2194 radialBar: { 2195 size: undefined, 2196 inverseOrder: false, 2197 startAngle: 0, 2198 endAngle: 360, 2199 offsetX: 0, 2200 offsetY: 0, 2201 hollow: { 2202 margin: 5, 2203 size: '50%', 2204 background: 'transparent', 2205 image: undefined, 2206 imageWidth: 150, 2207 imageHeight: 150, 2208 imageOffsetX: 0, 2209 imageOffsetY: 0, 2210 imageClipped: true, 2211 position: 'front', 2212 dropShadow: { 2213 enabled: false, 2214 top: 0, 2215 left: 0, 2216 blur: 3, 2217 color: '#000', 2218 opacity: 0.5 2219 } 2220 }, 2221 track: { 2222 show: true, 2223 startAngle: undefined, 2224 endAngle: undefined, 2225 background: '#f2f2f2', 2226 strokeWidth: '97%', 2227 opacity: 1, 2228 margin: 5, 2229 // margin is in pixels 2230 dropShadow: { 2231 enabled: false, 2232 top: 0, 2233 left: 0, 2234 blur: 3, 2235 color: '#000', 2236 opacity: 0.5 2237 } 2238 }, 2239 dataLabels: { 2240 show: true, 2241 name: { 2242 show: true, 2243 fontSize: '16px', 2244 fontFamily: undefined, 2245 color: undefined, 2246 offsetY: 0 2247 }, 2248 value: { 2249 show: true, 2250 fontSize: '14px', 2251 fontFamily: undefined, 2252 color: undefined, 2253 offsetY: 16, 2254 formatter: function formatter(val) { 2255 return val + '%'; 2256 } 2257 }, 2258 total: { 2259 show: false, 2260 label: 'Total', 2261 color: undefined, 2262 formatter: function formatter(w) { 2263 return w.globals.seriesTotals.reduce(function (a, b) { 2264 return a + b; 2265 }, 0) / w.globals.series.length + '%'; 2266 } 2267 } 2268 } 2269 }, 2270 rangeBar: {}, 2271 pie: { 2272 size: undefined, 2273 customScale: 1, 2274 offsetX: 0, 2275 offsetY: 0, 2276 expandOnClick: true, 2277 dataLabels: { 2278 // These are the percentage values which are displayed on slice 2279 offset: 0, 2280 // offset by which labels will move outside 2281 minAngleToShowLabel: 10 2282 }, 2283 donut: { 2284 size: '65%', 2285 background: 'transparent', 2286 labels: { 2287 // These are the inner labels appearing inside donut 2288 show: false, 2289 name: { 2290 show: true, 2291 fontSize: '16px', 2292 fontFamily: undefined, 2293 color: undefined, 2294 offsetY: -10 2295 }, 2296 value: { 2297 show: true, 2298 fontSize: '20px', 2299 fontFamily: undefined, 2300 color: undefined, 2301 offsetY: 10, 2302 formatter: function formatter(val) { 2303 return val; 2304 } 2305 }, 2306 total: { 2307 show: false, 2308 label: 'Total', 2309 color: undefined, 2310 formatter: function formatter(w) { 2311 return w.globals.seriesTotals.reduce(function (a, b) { 2312 return a + b; 2313 }, 0); 2314 } 2315 } 2316 } 2317 } 2318 }, 2319 radar: { 2320 size: undefined, 2321 offsetX: 0, 2322 offsetY: 0, 2323 polygons: { 2324 // strokeColor: '#e8e8e8', // should be deprecated
2324in the minor version i.e 3.2 2325 strokeColors: '#e8e8e8', 2326 connectorColors: '#e8e8e8', 2327 fill: { 2328 colors: undefined 2329 } 2330 } 2331 } 2332 }, 2333 colors: undefined, 2334 dataLabels: { 2335 enabled: true, 2336 enabledOnSeries: undefined, 2337 formatter: function formatter(val) { 2338 return val; 2339 }, 2340 textAnchor: 'middle', 2341 offsetX: 0, 2342 offsetY: 0, 2343 style: { 2344 fontSize: '12px', 2345 fontFamily: undefined, 2346 colors: undefined 2347 }, 2348 dropShadow: { 2349 enabled: false, 2350 top: 1, 2351 left: 1, 2352 blur: 1, 2353 color: '#000', 2354 opacity: 0.45 2355 } 2356 }, 2357 fill: { 2358 type: 'solid', 2359 colors: undefined, 2360 // array of colors 2361 opacity: 0.85, 2362 gradient: { 2363 shade: 'dark', 2364 type: 'horizontal', 2365 shadeIntensity: 0.5, 2366 gradientToColors: undefined, 2367 inverseColors: true, 2368 opacityFrom: 1, 2369 opacityTo: 1, 2370 stops: [0, 50, 100], 2371 colorStops: [] 2372 }, 2373 image: { 2374 src: [], 2375 width: undefined, 2376 // optional 2377 height: undefined // optional 2378 2379 }, 2380 pattern: { 2381 style: 'sqaures', 2382 // String | Array of Strings 2383 width: 6, 2384 height: 6, 2385 strokeWidth: 2 2386 } 2387 }, 2388 grid: { 2389 show: true, 2390 borderColor: '#e0e0e0', 2391 strokeDashArray: 0, 2392 position: 'back', 2393 xaxis: { 2394 lines: { 2395 show: false, 2396 animate: false 2397 } 2398 }, 2399 yaxis: { 2400 lines: { 2401 show: true, 2402 animate: false 2403 } 2404 }, 2405 row: { 2406 colors: undefined, 2407 // takes as array which will be repeated on rows 2408 opacity: 0.5 2409 }, 2410 column: { 2411 colors: undefined, 2412 // takes an array which will be repeated on columns 2413 opacity: 0.5 2414 }, 2415 padding: { 2416 top: 0, 2417 right: 10, 2418 bottom: 0, 2419 left: 12 2420 } 2421 }, 2422 labels: [], 2423 legend: { 2424 show: true, 2425 showForSingleSeries: false, 2426 showForNullSeries: true, 2427 showForZeroSeries: true, 2428 floating: false, 2429 position: 'bottom', 2430 // whether to position legends in 1 of 4 2431 // direction - top, bottom, left, right 2432 horizontalAlign: 'center', 2433 // when position top/bottom, you can specify whether to align legends left, right or center 2434 fontSize: '12px', 2435 fontFamily: undefined, 2436 width: undefined, 2437 height: undefined, 2438 formatter: undefined, 2439 offsetX: -20, 2440 offsetY: 0, 2441 labels: { 2442 colors: undefined, 2443 useSeriesColors: false 2444 }, 2445 markers: { 2446 width: 12, 2447 height: 12, 2448 strokeWidth: 0, 2449 strokeColor: '#fff', 2450 radius: 12, 2451 customHTML: undefined, 2452 offsetX: 0, 2453 offsetY: 0, 2454 onClick: undefined 2455 }, 2456 itemMargin: { 2457 horizontal: 0, 2458 vertical: 5 2459 }, 2460 onItemClick: { 2461 toggleDataSeries: true 2462 }, 2463 onItemHover: { 2464 highlightDataSeries: true 2465 } 2466 }, 2467 markers: { 2468 discrete: [], 2469 size: 0, 2470 colors: undefined, 2471 //strokeColor: '#fff', // TODO: deprecate in major version 4.0 2472 strokeColors: '#fff', 2473 strokeWidth: 2, 2474 strokeOpacity: 0.9, 2475 fillOpacity: 1, 2476 shape: 'circle', 2477 radius: 2, 2478 offsetX: 0, 2479 offsetY: 0, 2480 hover: { 2481 size: undefined, 2482 sizeOffset: 3 2483 } 2484 }, 2485 noData: { 2486 text: undefined, 2487 align: 'center', 2488 verticalAlign: 'middle', 2489 offsetX: 0, 2490 offsetY: 0, 2491 style: { 2492 color: undefined, 2493 fontSize: '14px', 2494 fontFamily: undefined 2495 } 2496 }, 2497 responsive: [], 2498 // breakpoints should follow ascending order 400, then 700, then 1000 2499 series: undefined, 2500 states: { 2501 normal: { 2502 filter: { 2503 type: 'none', 2504 value: 0 2505 } 2506 }, 2507 hover: { 2508 filter: { 2509 type: 'lighten', 2510 value: 0.15 2511 } 2512 }, 2513 active: { 2514 allowMultipleDataPointsSelection: false, 2515 filter: { 2516 type: 'darken', 2517 value: 0.65 2518 } 2519 } 2520 }, 2521 title: { 2522 text: undefined, 2523 align: 'left', 2524 margin: 10, 2525 offsetX: 0, 2526 offsetY: 0, 2527 floating: false, 2528 style: { 2529 fontSize: '14px', 2530 fontFamily: undefined, 2531 color: undefined 2532 } 2533 }, 2534 subtitle: { 2535 text: undefined, 2536 align: 'left', 2537 margin: 10, 2538 offsetX: 0, 2539 offsetY: 30, 2540 floating: false, 2541 style: { 2542 fontSize: '12px', 2543 fontFamily: undefined, 2544 color: undefined 2545 } 2546 }, 2547 stroke: { 2548 show: true, 2549 curve: 'smooth', 2550 // "smooth" / "straight" / "stepline" 2551 lineCap: 'butt', 2552 // round, butt , square 2553 width: 2, 2554 colors: undefined, 2555 // array of colors 2556 dashArray: 0 // single value or array of values 2557 2558 }, 2559 tooltip: { 2560 enabled: true, 2561 enabledOnSeries: undefined, 2562 shared: true, 2563 followCursor: false, 2564 // when disabled, the tooltip will show on top of the series instead of mouse position 2565 intersect: false, 2566 // when enabled, tooltip will only show when user directly hovers over point 2567 inverseOrder: false, 2568 custom: undefined, 2569 fillSeriesColor: false, 2570 theme: 'light', 2571 style: { 2572 fontSize: '12px', 2573 fontFamily: undefined 2574 }, 2575 onDatasetHover: { 2576 highlightDataSeries: false 2577 }, 2578 x: { 2579 // x value 2580 show: true, 2581 format: 'dd MMM', 2582 // dd/MM, dd MMM yy, dd MMM yyyy 2583 formatter: undefined // a custom user supplied formatter function 2584 2585 }, 2586 y: { 2587 formatter: undefined, 2588 title: { 2589 formatter: function formatter(seriesName) { 2590 return seriesName; 2591 } 2592 } 2593 }, 2594 z: { 2595 formatter: undefined, 2596 title: 'Size: ' 2597 }, 2598 marker: { 2599 show: true 2600 }, 2601 items: { 2602 display: 'flex' 2603 }, 2604 fixed: { 2605 enabled: false, 2606 position: 'topRight', 2607 // topRight, topLeft, bottomRight, bottomLeft 2608 offsetX: 0, 2609 offsetY: 0 2610 } 2611 }, 2612 xaxis: { 2613 type: 'category', 2614 categories: [], 2615 offsetX: 0, 2616 offsetY: 0, 2617 labels: { 2618 show: true, 2619 rotate: -45, 2620 rotateAlways: false, 2621 hideOverlappingLabels: true, 2622 trim: true, 2623 minHeight: undefined, 2624 maxHeight: 120, 2625 showDuplicates: true, 2626 style: { 2627 colors: [], 2628 fontSize: '12px', 2629 fontFamily: undefined, 2630 cssClass: '' 2631 }, 2632 offsetX: 0, 2633 offsetY: 0, 2634 format: undefined, 2635 formatter: undefined, 2636 // custom formatter function which will override format 2637 datetimeFormatter: { 2638 year: 'yyyy', 2639 month: "MMM 'yy", 2640 day: 'dd MMM', 2641 hour: 'HH:mm', 2642 minute: 'HH:mm:ss' 2643 } 2644 }, 2645 axisBorder: { 2646 show: true, 2647 color: '#78909C', 2648 width: '100%', 2649 height: 1, 2650 offsetX: 0, 2651 offsetY: 0 2652 }, 2653 axisTicks: { 2654 show: true, 2655 color: '#78909C', 2656 height: 6, 2657 offsetX: 0, 2658 offsetY: 0 2659 }, 2660 tickAmount: undefined, 2661 tickPlacement: 'on', 2662 min: undefined, 2663 max: undefined, 2664 range: undefined, 2665 floating: false, 2666 position: 'bottom', 2667 title: { 2668 text: undefined, 2669 offsetX: 0, 2670 offsetY: 0, 2671 style: { 2672 color: undefined, 2673 fontSize: '12px', 2674 fontFamily: undefined, 2675 cssClass: '' 2676 } 2677 }, 2678 crosshairs: { 2679 show: true, 2680 width: 1, 2681 // tickWidth/barWidth or an integer 2682 position: 'back', 2683 opacity: 0.9, 2684 stroke: { 2685 color: '#b6b6b6', 2686 width: 1, 2687 dashArray: 3 2688 }, 2689 fill: { 2690 type: 'solid', 2691 // solid, gradient 2692 color: '#B1B9C4', 2693 gradient: { 2694 colorFrom: '#D8E3F0', 2695 colorTo: '#BED1E6', 2696 stops: [0, 100], 2697 opacityFrom: 0.4, 2698 opacityTo: 0.5 2699 } 2700 }, 2701 dropShadow: { 2702 enabled: false, 2703 left: 0, 2704 top: 0, 2705 blur: 1, 2706 opacity: 0.4 2707 } 2708 }, 2709 tooltip: { 2710 enabled: true, 2711 offsetY: 0, 2712 formatter: undefined, 2713 style: { 2714 fontSize: '12px', 2715 fontFamily: undefined 2716 } 2717 } 2718 }, 2719 yaxis: this.yAxis, 2720 theme: { 2721 mode: 'light', 2722 palette: 'palette1',
2723 // If defined, it will overwrite globals.colors variable 2724 monochrome: { 2725 // monochrome allows you to select just 1 color and fill out the rest with light/dark shade (intensity can be selected) 2726 enabled: false, 2727 color: '#008FFB', 2728 shadeTo: 'light', 2729 shadeIntensity: 0.65 2730 } 2731 } 2732 }; 2733 } 2734 }]); 2735 2736 return Options; 2737 }(); 2738 2739 /** 2740 * ApexCharts Annotations Class for drawing lines/rects on both xaxis and yaxis. 2741 * 2742 * @module Annotations 2743 **/ 2744 2745 var Annotations = 2746 /*#__PURE__*/ 2747 function () { 2748 function Annotations(ctx) { 2749 _classCallCheck(this, Annotations); 2750 2751 this.ctx = ctx; 2752 this.w = ctx.w; 2753 this.graphics = new Graphics(this.ctx); 2754 2755 if (this.w.globals.isBarHorizontal) { 2756 this.invertAxis = true; 2757 } 2758 2759 this.xDivision = this.w.globals.gridWidth / this.w.globals.dataPoints; 2760 } 2761 2762 _createClass(Annotations, [{ 2763 key: "drawAnnotations", 2764 value: function drawAnnotations() { 2765 var w = this.w; 2766 2767 if (w.globals.axisCharts) { 2768 var yAnnotations = this.drawYAxisAnnotations(); 2769 var xAnnotations = this.drawXAxisAnnotations(); 2770 var pointAnnotations = this.drawPointAnnotations(); 2771 var initialAnim = w.config.chart.animations.enabled; 2772 var annoArray = [yAnnotations, xAnnotations, pointAnnotations]; 2773 var annoElArray = [xAnnotations.node, yAnnotations.node, pointAnnotations.node]; 2774 2775 for (var i = 0; i < 3; i++) { 2776 w.globals.dom.elGraphical.add(annoArray[i]); 2777 2778 if (initialAnim && !w.globals.resized && !w.globals.dataChanged) { 2779 annoElArray[i].classList.add('hidden'); 2780 } 2781 2782 w.globals.delayedElements.push({ 2783 el: annoElArray[i], 2784 index: 0 2785 }); 2786 } // background sizes needs to be calculated after text is drawn, so calling them last 2787 2788 2789 this.annotationsBackground(); 2790 } 2791 } 2792 }, { 2793 key: "addXaxisAnnotation", 2794 value: function addXaxisAnnotation(anno, parent, index) { 2795 var w = this.w; 2796 var min = this.invertAxis ? w.globals.minY : w.globals.minX; 2797 var range = this.invertAxis ? w.globals.yRange[0] : w.globals.xRange; 2798 var x1 = (anno.x - min) / (range / w.globals.gridWidth); 2799 var text = anno.label.text; 2800 2801 if (w.config.xaxis.type === 'category' || w.config.xaxis.convertedCatToNumeric) { 2802 var catIndex = w.globals.labels.indexOf(anno.x); 2803 var xLabel = w.globals.dom.baseEl.querySelector('.apexcharts-xaxis-texts-g text:nth-child(' + (catIndex + 1) + ')'); 2804 2805 if (xLabel) { 2806 x1 = parseFloat(xLabel.getAttribute('x')); 2807 } 2808 } 2809 2810 var strokeDashArray = anno.strokeDashArray; 2811 if (x1 < 0 || x1 > w.globals.gridWidth) return; 2812 2813 if (anno.x2 === null) { 2814 var line = this.graphics.drawLine(x1 + anno.offsetX, // x1 2815 0 + anno.offsetY, // y1 2816 x1 + anno.offsetX, // x2 2817 w.globals.gridHeight + anno.offsetY, // y2 2818 anno.borderColor, // lineColor 2819 strokeDashArray //dashArray 2820 ); 2821 parent.appendChild(line.node); 2822 } else { 2823 var x2 = (anno.x2 - min) / (range / w.globals.gridWidth); 2824 2825 if (x2 < x1) { 2826 var temp = x1; 2827 x1 = x2; 2828 x2 = temp; 2829 } 2830 2831 if (text) { 2832 var rect = this.graphics.drawRect(x1 + anno.offsetX, // x1 2833 0 + anno.offsetY, // y1 2834 x2 - x1, // x2 2835 w.globals.gridHeight + anno.offsetY, // y2 2836 0, // radius 2837 anno.fillColor, // color 2838 anno.opacity, // opacity, 2839 1, // strokeWidth 2840 anno.borderColor, // strokeColor 2841 strokeDashArray // stokeDashArray 2842 ); 2843 parent.appendChild(rect.node); 2844 } 2845 } 2846 2847 var textY = anno.label.position === 'top' ? -3 : w.globals.gridHeight; 2848 var elText = this.graphics.drawText({ 2849 x: x1 + anno.label.offsetX, 2850 y: textY + anno.label.offsetY, 2851 text: text, 2852 textAnchor: anno.label.textAnchor, 2853 fontSize: anno.label.style.fontSize, 2854 fontFamily: anno.label.style.fontFamily, 2855 foreColor: anno.label.style.color, 2856 cssClass: 'apexcharts-xaxis-annotation-label ' + anno.label.style.cssClass 2857 }); 2858 elText.attr({ 2859 rel: index 2860 }); 2861 parent.appendChild(elText.node); // after placing the annotations on svg, set any vertically placed annotations 2862 2863 this.setOrientations(anno, index); 2864 } 2865 }, { 2866 key: "drawXAxisAnnotations", 2867 value: function drawXAxisAnnotations() { 2868 var _this = this; 2869 2870 var w = this.w; 2871 var elg = this.graphics.group({ 2872 class: 'apexcharts-xaxis-annotations' 2873 }); 2874 w.config.annotations.xaxis.map(function (anno, index) { 2875 _this.addXaxisAnnotation(anno, elg.node, index); 2876 }); 2877 return elg; 2878 } 2879 }, { 2880 key: "addYaxisAnnotation", 2881 value: function addYaxisAnnotation(anno, parent, index) { 2882 var w = this.w; 2883 var strokeDashArray = anno.strokeDashArray; 2884 var y1; 2885 var y2; 2886 2887 if (this.invertAxis) { 2888 var catIndex = w.globals.labels.indexOf(anno.y); 2889 var xLabel = w.globals.dom.baseEl.querySelector('.apexcharts-yaxis-texts-g text:nth-child(' + (catIndex + 1) + ')'); 2890 2891 if (xLabel) { 2892 y1 = parseFloat(xLabel.getAttribute('y')); 2893 } 2894 } else { 2895 y1 = w.globals.gridHeight - (anno.y - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 2896 2897 if (w.config.yaxis[anno.yAxisIndex] && w.config.yaxis[anno.yAxisIndex].reversed) { 2898 y1 = (anno.y - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 2899 } 2900 } 2901 2902 var text = anno.label.text; 2903 2904 if (anno.y2 === null) { 2905 var line = this.graphics.drawLine(0 + anno.offsetX, // x1 2906 y1 + anno.offsetY, // y1 2907 w.globals.gridWidth + anno.offsetX, // x2 2908 y1 + anno.offsetY, // y2 2909 anno.borderColor, // lineColor 2910 strokeDashArray // dashArray 2911 ); 2912 parent.appendChild(line.node); 2913 } else { 2914 if (this.invertAxis) { 2915 var _catIndex = w.globals.labels.indexOf(anno.y2); 2916 2917 var _xLabel = w.globals.dom.baseEl.querySelector('.apexcharts-yaxis-texts-g text:nth-child(' + (_catIndex + 1) + ')'); 2918 2919 if (_xLabel) { 2920 y2 = parseFloat(_xLabel.getAttribute('y')); 2921 } 2922 } else { 2923 y2 = w.globals.gridHeight - (anno.y2 - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 2924 2925 if (w.config.yaxis[anno.yAxisIndex] && w.config.yaxis[anno.yAxisIndex].reversed) { 2926 y2 = (anno.y2 - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 2927 } 2928 } 2929 2930 if (y2 > y1) { 2931 var temp = y1; 2932 y1 = y2; 2933 y2 = temp; 2934 } 2935 2936 if (text) { 2937 var rect = this.graphics.drawRect(0 + anno.offsetX, // x1 2938 y2 + anno.offsetY, // y1 2939 w.globals.gridWidth + anno.offsetX, // x2 2940 y1 - y2, // y2 2941 0, // radius 2942 anno.fillColor, // color 2943 anno.opacity, // opacity, 2944 1, // strokeWidth 2945 anno.borderColor, // strokeColor 2946 strokeDashArray // stokeDashArray 2947 ); 2948 parent.appendChild(rect.node); 2949 } 2950 } 2951 2952 var textX = anno.label.position === 'right' ? w.globals.gridWidth : 0; 2953 var elText = this.graphics.drawText({ 2954 x: textX + anno.label.offsetX, 2955 y: (y2 || y1) + anno.label.offsetY - 3, 2956 text: text, 2957 textAnchor: anno.label.textAnchor, 2958 fontSize: anno.label.style.fontSize, 2959 fontFamily: anno.label.style.fontFamily, 2960 foreColor: anno.label.style.color, 2961 cssClass: 'apexcharts-yaxis-annotation-label ' + anno.label.style.cssClass 2962 }); 2963 elText.attr({ 2964 rel: index 2965 }); 2966 parent.appendChild(elText.node); 2967 } 2968 }, { 2969 key: "drawYAxisAnnotations", 2970 value: function drawYAxisAnnotations() { 2971 var _this2 = this; 2972 2973 var w = this.w; 2974 var elg = this.graphics.group({ 2975 class: 'apexcharts-yaxis-annotations' 2976 }); 2977 w.config.annotations.yaxis.map(function (anno, index) { 2978 _this2.addYaxisAnnotation(anno, elg.node, index); 2979 }); 2980 return elg; 2981 } 2982 }, { 2983 key: "clearAnnotations", 2984 value: function clearAnnotations(ctx) { 2985 var w = ctx.w; 2986 var annos = w.globals.dom.baseEl.querySelectorAll('.apexcharts-yaxis-annotations, .apexcharts-xaxis-annotations, .apexcharts-point-annotations'); 2987 annos = Utils.listToArray(annos); 2988 annos.forEach(function (a) { 2989 while (a.firstChild) { 2990 a.removeChild(a.firstChild); 2991 } 2992 }); 2993 } 2994 }, { 2995 key: "addPointAnnotation", 2996 value: function addPointAnnotation(anno, parent, index) { 2997 var w = this.w; 2998 var x = 0; 2999 var y = 0; 3000 var pointY = 0; 3001 3002 if (this.invertAxis) { 3003 console.warn('Point annotation is not supported in horizontal bar charts.'); 3004 } 3005 3006 if (typeof anno.x === 'string') { 3007 var catIndex = w.globals.labels.indexOf(anno.x); 3008 var xLabel = w.globals.dom.baseEl.querySelector('.apexcharts-xaxis-texts-g text:nth-child(' + (catIndex + 1) + ')'); 3009 var xPos = parseFloat(xLabel.getAttribute('x')); 3010 x = xPos; 3011 var annoY = anno.y; 3012 3013 if (anno.y === null) { 3014 annoY = w.globals.series[anno.seriesIndex][catIndex]; 3015 } 3016 3017 y = w.globals.gridHeight - (annoY - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight) - parseInt(anno.label.style.fontSize) - anno.marker.size; 3018 pointY = w.globals.gridHeight - (annoY - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 3019 3020 if (w.config.yaxis[anno.yAxisIndex] && w.config.yaxis[anno.yAxisIndex].reversed) { 3021 y = (annoY - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight) + parseInt(anno.label.style.fontSize) + anno.marker.size; 3022 pointY = (annoY - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 3023 } 3024 } else { 3025 x = (anno.x - w.globals.minX) / (w.globals.xRange / w.globals.gridWidth); 3026 y = w.globals.gridHeight - (parseFloat(anno.y) - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight) - parseInt(anno.label.style.fontSize) - anno.marker.size; 3027 pointY = w.globals.gridHeight - (anno.y - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 3028 3029 if (w.config.yaxis[anno.yAxisIndex] && w.config.yaxis[anno.yAxisIndex].reversed) { 3030 y = (parseFloat(anno.y) - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight) - parseInt(anno.label.style.fontSize) - anno.marker.size; 3031 pointY = (anno.y - w.globals.minYArr[anno.yAxisIndex]) / (w.globals.yRange[anno.yAxisIndex] / w.globals.gridHeight); 3032 } 3033 } 3034 3035 if (x < 0 || x > w.globals.gridWidth) return; 3036 var optsPoints = { 3037 pSize: anno.marker.size, 3038 pWidth: anno.marker.strokeWidth, 3039 pointFillColor: anno.marker.fillColor, 3040 pointStrokeColor: anno.marker.strokeColor, 3041 shape: anno.marker.shape,
3042 radius: anno.marker.radius, 3043 class: 'apexcharts-point-annotation-marker ' + anno.marker.cssClass 3044 }; 3045 var point = this.graphics.drawMarker(x + anno.marker.offsetX, pointY + anno.marker.offsetY, optsPoints); 3046 parent.appendChild(point.node); 3047 var text = anno.label.text ? anno.label.text : ''; 3048 var elText = this.graphics.drawText({ 3049 x: x + anno.label.offsetX, 3050 y: y + anno.label.offsetY, 3051 text: text, 3052 textAnchor: anno.label.textAnchor, 3053 fontSize: anno.label.style.fontSize, 3054 fontFamily: anno.label.style.fontFamily, 3055 foreColor: anno.label.style.color, 3056 cssClass: 'apexcharts-point-annotation-label ' + anno.label.style.cssClass 3057 }); 3058 elText.attr({ 3059 rel: index 3060 }); 3061 parent.appendChild(elText.node); 3062 3063 if (anno.customSVG.SVG) { 3064 var g = this.graphics.group({ 3065 class: 'apexcharts-point-annotations-custom-svg ' + anno.customSVG.cssClass 3066 }); 3067 g.attr({ 3068 transform: "translate(".concat(x + anno.customSVG.offsetX, ", ").concat(y + anno.customSVG.offsetY, ")") 3069 }); 3070 g.node.innerHTML = anno.customSVG.SVG; 3071 parent.appendChild(g.node); 3072 } 3073 } 3074 }, { 3075 key: "drawPointAnnotations", 3076 value: function drawPointAnnotations() { 3077 var _this3 = this; 3078 3079 var w = this.w; 3080 var elg = this.graphics.group({ 3081 class: 'apexcharts-point-annotations' 3082 }); 3083 w.config.annotations.points.map(function (anno, index) { 3084 _this3.addPointAnnotation(anno, elg.node, index); 3085 }); 3086 return elg; 3087 } 3088 }, { 3089 key: "setOrientations", 3090 value: function setOrientations(anno) { 3091 var annoIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 3092 var w = this.w; 3093 3094 if (anno.label.orientation === 'vertical') { 3095 var i = annoIndex !== null ? annoIndex : 0; 3096 var xAnno = w.globals.dom.baseEl.querySelector(".apexcharts-xaxis-annotations .apexcharts-xaxis-annotation-label[rel='".concat(i, "']")); 3097 3098 if (xAnno !== null) { 3099 var xAnnoCoord = xAnno.getBoundingClientRect(); 3100 xAnno.setAttribute('x', parseFloat(xAnno.getAttribute('x')) - xAnnoCoord.height + 4); 3101 3102 if (anno.label.position === 'top') { 3103 xAnno.setAttribute('y', parseFloat(xAnno.getAttribute('y')) + xAnnoCoord.width); 3104 } else { 3105 xAnno.setAttribute('y', parseFloat(xAnno.getAttribute('y')) - xAnnoCoord.width); 3106 } 3107 3108 var annoRotatingCenter = this.graphics.rotateAroundCenter(xAnno); 3109 var x = annoRotatingCenter.x; 3110 var y = annoRotatingCenter.y; 3111 xAnno.setAttribute('transform', "rotate(-90 ".concat(x, " ").concat(y, ")")); 3112 } 3113 } 3114 } 3115 }, { 3116 key: "addBackgroundToAnno", 3117 value: function addBackgroundToAnno(annoEl, anno) { 3118 var w = this.w; 3119 if (!anno.label.text) return null; 3120 var elGridRect = w.globals.dom.baseEl.querySelector('.apexcharts-grid').getBoundingClientRect(); 3121 var coords = annoEl.getBoundingClientRect(); 3122 var pleft = anno.label.style.padding.left; 3123 var pright = anno.label.style.padding.right; 3124 var ptop = anno.label.style.padding.top; 3125 var pbottom = anno.label.style.padding.bottom; 3126 3127 if (anno.label.orientation === 'vertical') { 3128 ptop = anno.label.style.padding.left; 3129 pbottom = anno.label.style.padding.right; 3130 pleft = anno.label.style.padding.top; 3131 pright = anno.label.style.padding.bottom; 3132 } 3133 3134 var x1 = coords.left - elGridRect.left - pleft; 3135 var y1 = coords.top - elGridRect.top - ptop; 3136 var elRect = this.graphics.drawRect(x1, y1, coords.width + pleft + pright, coords.height + ptop + pbottom, 0, anno.label.style.background, 1, anno.label.borderWidth, anno.label.borderColor, 0); 3137 return elRect; 3138 } 3139 }, {
3140 key: "annotationsBackground", 3141 value: function annotationsBackground() { 3142 var _this4 = this; 3143 3144 var w = this.w; 3145 3146 var add = function add(anno, i, type) { 3147 var annoLabel = w.globals.dom.baseEl.querySelector(".apexcharts-".concat(type, "-annotations .apexcharts-").concat(type, "-annotation-label[rel='").concat(i, "']")); 3148 3149 if (annoLabel) { 3150 var parent = annoLabel.parentNode; 3151 3152 var elRect = _this4.addBackgroundToAnno(annoLabel, anno); 3153 3154 if (elRect) { 3155 parent.insertBefore(elRect.node, annoLabel); 3156 } 3157 } 3158 }; 3159 3160 w.config.annotations.xaxis.map(function (anno, i) { 3161 add(anno, i, 'xaxis'); 3162 }); 3163 w.config.annotations.yaxis.map(function (anno, i) { 3164 add(anno, i, 'yaxis'); 3165 }); 3166 w.config.annotations.points.map(function (anno, i) { 3167 add(anno, i, 'point'); 3168 }); 3169 } 3170 }, { 3171 key: "addText", 3172 value: function addText(params, pushToMemory, context) { 3173 var x = params.x, 3174 y = params.y, 3175 text = params.text, 3176 textAnchor = params.textAnchor, 3177 _params$appendTo = params.appendTo, 3178 appendTo = _params$appendTo === void 0 ? '.apexcharts-inner' : _params$appendTo, 3179 foreColor = params.foreColor, 3180 fontSize = params.fontSize, 3181 fontFamily = params.fontFamily, 3182 cssClass = params.cssClass, 3183 backgroundColor = params.backgroundColor, 3184 borderWidth = params.borderWidth, 3185 strokeDashArray = params.strokeDashArray, 3186 radius = params.radius, 3187 borderColor = params.borderColor, 3188 _params$paddingLeft = params.paddingLeft, 3189 paddingLeft = _params$paddingLeft === void 0 ? 4 : _params$paddingLeft, 3190 _params$paddingRight = params.paddingRight, 3191 paddingRight = _params$paddingRight === void 0 ? 4 : _params$paddingRight, 3192 _params$paddingBottom = params.paddingBottom, 3193 paddingBottom = _params$paddingBottom === void 0 ? 2 : _params$paddingBottom, 3194 _params$paddingTop = params.paddingTop, 3195 paddingTop = _params$paddingTop === void 0 ? 2 : _params$paddingTop; 3196 var me = context; 3197 var w = me.w; 3198 var parentNode = w.globals.dom.baseEl.querySelector(appendTo); 3199 var elText = this.graphics.drawText({ 3200 x: x, 3201 y: y, 3202 text: text, 3203 textAnchor: textAnchor || 'start', 3204 fontSize: fontSize || '12px', 3205 fontFamily: fontFamily || w.config.chart.fontFamily, 3206 foreColor: foreColor || w.config.chart.foreColor, 3207 cssClass: 'apexcharts-text ' + cssClass ? cssClass : '' 3208 }); 3209 parentNode.appendChild(elText.node); 3210 var textRect = elText.bbox(); 3211 3212 if (text) { 3213 var elRect = this.graphics.drawRect(textRect.x - paddingLeft, textRect.y - paddingTop, textRect.width + paddingLeft + paddingRight, textRect.height + paddingBottom + paddingTop, radius, backgroundColor, 1, borderWidth, borderColor, strokeDashArray);
3214 elText.before(elRect); 3215 } 3216 3217 if (pushToMemory) { 3218 w.globals.memory.methodsToExec.push({ 3219 context: me, 3220 method: me.addText, 3221 params: { 3222 x: x, 3223 y: y, 3224 text: text, 3225 textAnchor: textAnchor, 3226 appendTo: appendTo, 3227 foreColor: foreColor, 3228 fontSize: fontSize, 3229 cssClass: cssClass, 3230 backgroundColor: backgroundColor, 3231 borderWidth: borderWidth, 3232 strokeDashArray: strokeDashArray, 3233 radius: radius, 3234 borderColor: borderColor, 3235 paddingLeft: paddingLeft, 3236 paddingRight: paddingRight, 3237 paddingBottom: paddingBottom, 3238 paddingTop: paddingTop 3239 } 3240 }); 3241 } 3242 3243 return context; 3244 } 3245 }, { 3246 key: "addPointAnnotationExternal", 3247 value: function addPointAnnotationExternal(params, pushToMemory, context) { 3248 if (typeof this.invertAxis === 'undefined') { 3249 this.invertAxis = context.w.globals.isBarHorizontal; 3250 } 3251 3252 this.addAnnotationExternal({ 3253 params: params, 3254 pushToMemory: pushToMemory, 3255 context: context, 3256 type: 'point', 3257 contextMethod: context.addPointAnnotation 3258 }); 3259 return context; 3260 } 3261 }, { 3262 key: "addYaxisAnnotationExternal", 3263 value: function addYaxisAnnotationExternal(params, pushToMemory, context) { 3264 this.addAnnotationExternal({ 3265 params: params, 3266 pushToMemory: pushToMemory, 3267 context: context, 3268 type: 'yaxis', 3269 contextMethod: context.addYaxisAnnotation 3270 }); 3271 return context; 3272 } // The addXaxisAnnotation method requires a parent class, and user calling this method externally on the chart instance may not specify parent, hence a different method 3273 3274 }, { 3275 key: "addXaxisAnnotationExternal", 3276 value: function addXaxisAnnotationExternal(params, pushToMemory, context) { 3277 this.addAnnotationExternal({ 3278 params: params, 3279 pushToMemory: pushToMemory, 3280 context: context, 3281 type: 'xaxis', 3282 contextMethod: context.addXaxisAnnotation 3283 }); 3284 return context; 3285 } 3286 }, { 3287 key: "addAnnotationExternal", 3288 value: function addAnnotationExternal(_ref) { 3289 var params = _ref.params, 3290 pushToMemory = _ref.pushToMemory, 3291 context = _ref.context, 3292 type = _ref.type, 3293 contextMethod = _ref.contextMethod; 3294 var me = context; 3295 var w = me.w; 3296 var parent = w.globals.dom.baseEl.querySelector(".apexcharts-".concat(type, "-annotations")); 3297 var index = parent.childNodes.length + 1; 3298 var opt = new Options(); 3299 var axesAnno = Object.assign({}, type === 'xaxis' ? opt.xAxisAnnotation : type === 'yaxis' ? opt.yAxisAnnotation : opt.pointAnnotation); 3300 var anno = Utils.extend(axesAnno, params); 3301 3302 switch (type) { 3303 case 'xaxis': 3304 this.addXaxisAnnotation(anno, parent, index); 3305 break; 3306 3307 case 'yaxis': 3308 this.addYaxisAnnotation(anno, parent, index); 3309 break; 3310 3311 case 'point': 3312 this.addPointAnnotation(anno, parent, index); 3313 break; 3314 } // add background 3315 3316 3317 var axesAnnoLabel = w.globals.dom.baseEl.querySelector(".apexcharts-".concat(type, "-annotations .apexcharts-").concat(type, "-annotation-label[rel='").concat(index, "']")); 3318 var elRect = this.addBackgroundToAnno(axesAnnoLabel, anno); 3319 3320 if (elRect) { 3321 parent.insertBefore(elRect.node, axesAnnoLabel); 3322 } 3323 3324 if (pushToMemory) { 3325 w.globals.memory.methodsToExec.push({ 3326 context: me, 3327 method: contextMethod, 3328 params: params 3329 }); 3330 } 3331 3332 return context; 3333 } 3334 }]); 3335 3336 return Annotations; 3337 }(); 3338 3339 /** 3340 * DateTime Class to manipulate datetime values. 3341 * 3342 * @module DateTime 3343 **/ 3344 3345 var DateTime = 3346 /*#__PURE__*/ 3347 function () { 3348 function DateTime(ctx) { 3349 _classCallCheck(this, DateTime); 3350 3351 this.ctx = ctx; 3352 this.w = ctx.w; 3353 this.months31 = [1, 3, 5, 7, 8, 10, 12]; 3354 this.months30 = [2, 4, 6, 9, 11]; 3355 this.daysCntOfYear = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; 3356 } 3357 3358 _createClass(DateTime, [{ 3359 key: "isValidDate", 3360 value: function isValidDate(date) { 3361 return !isNaN(this.parseDate(date)); 3362 } 3363 }, { 3364 key: "getUTCTimeStamp", 3365 value: function getUTCTimeStamp(dateStr) { 3366 if (!Date.parse(dateStr)) { 3367 return dateStr; 3368 } 3369 3370 return new Date(new Date(dateStr).toISOString().substr(0, 25)).getTime(); 3371 } 3372 }, { 3373 key: "parseDate", 3374 value: function parseDate(dateStr) { 3375 var parsed = Date.parse(dateStr); 3376 3377 if (!isNaN(parsed)) { 3378 return this.getUTCTimeStamp(dateStr); 3379 } 3380 3381 var output = Date.parse(dateStr.replace(/-/g, '/').replace(/[a-z]+/gi, ' ')); 3382 output = this.getUTCTimeStamp(output); 3383 return output; 3384 } // https://stackoverflow.com/a/11252167/6495043 3385 3386 }, { 3387 key: "treatAsUtc", 3388 value: function treatAsUtc(dateStr) { 3389 var result = new Date(dateStr); 3390 result.setMinutes(result.getMinutes() - result.getTimezoneOffset()); 3391 return result; 3392 } // http://stackoverflow.com/questions/14638018/current-time-formatting-with-javascript#answer-14638191 3393 3394 }, { 3395 key: "formatDate", 3396 value: function formatDate(date, format) { 3397 var utc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; 3398 var convertToUTC = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; 3399 var locale = this.w.globals.locale; 3400 var MMMM = ['\x00'].concat(_toConsumableArray(locale.months)); 3401 var MMM = ['\x01'].concat(_toConsumableArray(locale.shortMonths)); 3402 var dddd = ['\x02'].concat(_toConsumableArray(locale.days)); 3403 var ddd = ['\x03'].concat(_toConsumableArray(locale.shortDays)); 3404 3405 function ii(i, len) { 3406 var s = i + ''; 3407 len = len || 2; 3408 3409 while (s.length < len) { 3410 s = '0' + s; 3411 } 3412 3413 return s; 3414 } 3415 3416 if (convertToUTC) { 3417 date = this.treatAsUtc(date); 3418 } 3419 3420 var y = utc ? date.getUTCFullYear() : date.getFullYear(); 3421 format = format.replace(/(^|[^\\])yyyy+/g, '$1' + y); 3422 format = format.replace(/(^|[^\\])yy/g, '$1' + y.toString().substr(2, 2)); 3423 format = format.replace(/(^|[^\\])y/g, '$1' + y); 3424 var M = (utc ? date.getUTCMonth() : date.getMonth()) + 1; 3425 format = format.replace(/(^|[^\\])MMMM+/g, '$1' + MMMM[0]); 3426 format = format.replace(/(^|[^\\])MMM/g, '$1' + MMM[0]); 3427 format = format.replace(/(^|[^\\])MM/g, '$1' + ii(M)); 3428 format = format.replace(/(^|[^\\])M/g, '$1' + M); 3429 var d = utc ? date.getUTCDate() : date.getDate(); 3430 format = format.replace(/(^|[^\\])dddd+/g, '$1' + dddd[0]); 3431 format = format.replace(/(^|[^\\])ddd/g, '$1' + ddd[0]); 3432 format = format.replace(/(^|[^\\])dd/g, '$1' + ii(d)); 3433 format = format.replace(/(^|[^\\])d/g, '$1' + d); 3434 var H = utc ? date.getUTCHours() : date.getHours(); 3435 format = format.replace(/(^|[^\\])HH+/g, '$1' + ii(H)); 3436 format = format.replace(/(^|[^\\])H/g, '$1' + H); 3437 var h = H > 12 ? H - 12 : H === 0 ? 12 : H; 3438 format = format.replace(/(^|[^\\])hh+/g, '$1' + ii(h)); 3439 format = format.replace(/(^|[^\\])h/g, '$1' + h); 3440 var m = utc ? date.getUTCMinutes() : date.getMinutes(); 3441 format = format.replace(/(^|[^\\])mm+/g, '$1' + ii(m)); 3442 format = format.replace(/(^|[^\\])m/g, '$1' + m); 3443 var s = utc ? date.getUTCSeconds() : date.getSeconds(); 3444 format = format.replace(/(^|[^\\])ss+/g, '$1' + ii(s)); 3445 format = format.replace(/(^|[^\\])s/g, '$1' + s); 3446 var f = utc ? date.getUTCMilliseconds() : date.getMilliseconds(); 3447 format = format.replace(/(^|[^\\])fff+/g, '$1' + ii(f, 3)); 3448 f = Math.round(f / 10); 3449 format = format.replace(/(^|[^\\])ff/g, '$1' + ii(f)); 3450 f = Math.round(f / 10); 3451 format = format.replace(/(^|[^\\])f/g, '$1' + f); 3452 var T = H < 12 ? 'AM' : 'PM'; 3453 format = format.replace(/(^|[^\\])TT+/g, '$1' + T); 3454 format = format.replace(/(^|[^\\])T/g, '$1' + T.charAt(0)); 3455 var t = T.toLowerCase(); 3456 format = format.replace(/(^|[^\\])tt+/g, '$1' + t); 3457 format = format.replace(/(^|[^\\])t/g, '$1' + t.charAt(0)); 3458 var tz = -date.getTimezoneOffset(); 3459 var K = utc || !tz ? 'Z' : tz > 0 ? '+' : '-'; 3460 3461 if (!utc) { 3462 tz = Math.abs(tz); 3463 var tzHrs = Math.floor(tz / 60); 3464 var tzMin = tz % 60; 3465 K += ii(tzHrs) + ':' + ii(tzMin); 3466 } 3467 3468 format = format.replace(/(^|[^\\])K/g, '$1' + K); 3469 var day = (utc ? date.getUTCDay() : date.getDay()) + 1; 3470 format = format.replace(new RegExp(dddd[0], 'g'), dddd[day]); 3471 format = format.replace(new RegExp(ddd[0], 'g'), ddd[day]); 3472 format = format.replace(new RegExp(MMMM[0], 'g'), MMMM[M]); 3473 format = format.replace(new RegExp(MMM[0], 'g'), MMM[M]); 3474 format = format.replace(/\\(.)/g, '$1'); 3475 return format; 3476 } 3477 }, { 3478 key: "getTimeUnitsfromTimestamp", 3479 value: function getTimeUnitsfromTimestamp(minX, maxX) { 3480 var w = this.w; 3481 3482 if (w.config.xaxis.min !== undefined) { 3483 minX = w.config.xaxis.min; 3484 } 3485 3486 if (w.config.xaxis.max !== undefined) { 3487 maxX = w.config.xaxis.max; 3488 } 3489 3490 var minYear = new Date(minX).getFullYear(); 3491 var maxYear = new Date(maxX).getFullYear(); 3492 var minMonth = new Date(minX).getMonth(); 3493 var maxMonth = new Date(maxX).getMonth(); 3494 var minDate = new Date(minX).getDate(); 3495 var maxDate = new Date(maxX).getDate(); 3496 var minHour = new Date(minX).getHours(); 3497 var maxHour = new Date(maxX).getHours(); 3498 var minMinute = new Date(minX).getMinutes(); 3499 var maxMinute = new Date(maxX).getMinutes(); 3500 return { 3501 minMinute: minMinute, 3502 maxMinute: maxMinute, 3503 minHour: minHour, 3504 maxHour: maxHour, 3505 minDate: minDate, 3506 maxDate: maxDate, 3507 minMonth: minMonth, 3508 maxMonth: maxMonth, 3509 minYear: minYear, 3510 maxYear: maxYear 3511 }; 3512 } 3513 }, { 3514 key: "isLeapYear",
3515 value: function isLeapYear(year) { 3516 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; 3517 } 3518 }, { 3519 key: "calculcateLastDaysOfMonth", 3520 value: function calculcateLastDaysOfMonth(month, year, subtract) { 3521 var days = this.determineDaysOfMonths(month, year); // whatever days we get, subtract the number of days asked 3522 3523 return days - subtract; 3524 } 3525 }, { 3526 key: "determineDaysOfYear", 3527 value: function determineDaysOfYear(year) { 3528 var days = 365; 3529 3530 if (this.isLeapYear(year)) { 3531 days = 366; 3532 } 3533 3534 return days; 3535 } 3536 }, { 3537 key: "determineRemainingDaysOfYear", 3538 value: function determineRemainingDaysOfYear(year, month, date) { 3539 var dayOfYear = this.daysCntOfYear[month] + date; 3540 if (month > 1 && this.isLeapYear()) dayOfYear++; 3541 return dayOfYear; 3542 } 3543 }, { 3544 key: "determineDaysOfMonths", 3545 value: function determineDaysOfMonths(month, year) { 3546 var days = 30; 3547 month = Utils.monthMod(month); 3548 3549 switch (true) { 3550 case this.months30.indexOf(month) > -1: 3551 if (month === 2) { 3552 if (this.isLeapYear(year)) { 3553 days = 29; 3554 } else { 3555 days = 28; 3556 } 3557 } 3558 3559 break; 3560 3561 case this.months31.indexOf(month) > -1: 3562 days = 31; 3563 break; 3564 3565 default: 3566 days = 31; 3567 break; 3568 } 3569 3570 return days; 3571 } 3572 }]); 3573 3574 return DateTime; 3575 }(); 3576 3577 /** 3578 * ApexCharts Default Class for setting default options for all chart types. 3579 * 3580 * @module Defaults 3581 **/ 3582 3583 var Defaults = 3584 /*#__PURE__*/ 3585 function () { 3586 function Defaults(opts) { 3587 _classCallCheck(this, Defaults); 3588 3589 this.opts = opts; 3590 } 3591 3592 _createClass(Defaults, [{ 3593 key: "line", 3594 value: function line() { 3595 return { 3596 chart: { 3597 animations: { 3598 easing: 'swing' 3599 } 3600 }, 3601 dataLabels: { 3602 enabled: false 3603 }, 3604 stroke: { 3605 width: 5, 3606 curve: 'straight' 3607 }, 3608 markers: { 3609 size: 0, 3610 hover: { 3611 sizeOffset: 6 3612 } 3613 }, 3614 xaxis: { 3615 crosshairs: { 3616 width: 1 3617 } 3618 } 3619 }; 3620 } 3621 }, { 3622 key: "sparkline", 3623 value: function sparkline(defaults) { 3624 this.opts.yaxis[0].labels.show = false; 3625 this.opts.yaxis[0].floating = true; 3626 var ret = { 3627 grid: { 3628 show: false, 3629 padding: { 3630 left: 0, 3631 right: 0, 3632 top: 0, 3633 bottom: 0 3634 } 3635 }, 3636 legend: { 3637 show: false 3638 }, 3639 xaxis: { 3640 labels: { 3641 show: false 3642 }, 3643 tooltip: { 3644 enabled: false 3645 }, 3646 axisBorder: { 3647 show: false 3648 } 3649 }, 3650 chart: { 3651 toolbar: { 3652 show: false 3653 }, 3654 zoom: { 3655 enabled: false 3656 } 3657 }, 3658 dataLabels: { 3659 enabled: false 3660 } 3661 }; 3662 return Utils.extend(defaults, ret); 3663 } 3664 }, { 3665 key: "bar", 3666 value: function bar() { 3667 return { 3668 chart: { 3669 stacked: false, 3670 animations: { 3671 easing: 'swing' 3672 } 3673 }, 3674 plotOptions: { 3675 bar: { 3676 dataLabels: { 3677 position: 'center' 3678 } 3679 } 3680 }, 3681 dataLabels: { 3682 style: { 3683 colors: ['#fff'] 3684 } 3685 }, 3686 stroke: { 3687 width: 0 3688 }, 3689 fill: { 3690 opacity: 0.85 3691 }, 3692 legend: { 3693 markers: {
3694 shape: 'square', 3695 radius: 2, 3696 size: 8 3697 } 3698 }, 3699 tooltip: { 3700 shared: false 3701 }, 3702 xaxis: { 3703 tooltip: { 3704 enabled: false 3705 }, 3706 crosshairs: { 3707 width: 'barWidth', 3708 position: 'back', 3709 fill: { 3710 type: 'gradient' 3711 }, 3712 dropShadow: { 3713 enabled: false 3714 }, 3715 stroke: { 3716 width: 0 3717 } 3718 } 3719 } 3720 }; 3721 } 3722 }, { 3723 key: "candlestick", 3724 value: function candlestick() { 3725 return { 3726 stroke: { 3727 width: 1, 3728 colors: ['#333'] 3729 }, 3730 dataLabels: { 3731 enabled: false 3732 }, 3733 tooltip: { 3734 shared: true, 3735 custom: function custom(_ref) { 3736 var seriesIndex = _ref.seriesIndex, 3737 dataPointIndex = _ref.dataPointIndex, 3738 w = _ref.w; 3739 var o = w.globals.seriesCandleO[seriesIndex][dataPointIndex]; 3740 var h = w.globals.seriesCandleH[seriesIndex][dataPointIndex]; 3741 var l = w.globals.seriesCandleL[seriesIndex][dataPointIndex]; 3742 var c = w.globals.seriesCandleC[seriesIndex][dataPointIndex]; 3743 return '<div class="apexcharts-tooltip-candlestick">' + '<div>Open: <span class="value">' + o + '</span></div>' + '<div>High: <span class="value">' + h + '</span></div>' + '<div>Low: <span class="value">' + l + '</span></div>' + '<div>Close: <span class="value">' + c + '</span></div>' + '</div>'; 3744 } 3745 }, 3746 states: { 3747 active: { 3748 filter: { 3749 type: 'none' 3750 } 3751 } 3752 }, 3753 xaxis: { 3754 crosshairs: { 3755 width: 1 3756 } 3757 } 3758 }; 3759 } 3760 }, { 3761 key: "rangeBar", 3762 value: function rangeBar() { 3763 return { 3764 stroke: { 3765 width: 0 3766 }, 3767 plotOptions: { 3768 bar: { 3769 dataLabels: { 3770 position: 'center' 3771 } 3772 } 3773 }, 3774 dataLabels: { 3775 enabled: false, 3776 formatter: function formatter(val, _ref2) { 3777 var ctx = _ref2.ctx, 3778 seriesIndex = _ref2.seriesIndex, 3779 dataPointIndex = _ref2.dataPointIndex, 3780 w = _ref2.w; 3781 var start = w.globals.seriesRangeStart[seriesIndex][dataPointIndex]; 3782 var end = w.globals.seriesRangeEnd[seriesIndex][dataPointIndex]; 3783 return end - start; 3784 }, 3785 style: { 3786 colors: ['#fff'] 3787 } 3788 }, 3789 tooltip: { 3790 shared: false, 3791 followCursor: true, 3792 custom: function custom(_ref3) { 3793 var ctx = _ref3.ctx, 3794 seriesIndex = _ref3.seriesIndex, 3795 dataPointIndex = _ref3.dataPointIndex, 3796 w = _ref3.w; 3797 var start = w.globals.seriesRangeStart[seriesIndex][dataPointIndex]; 3798 var end = w.globals.seriesRangeEnd[seriesIndex][dataPointIndex]; 3799 var startVal = ''; 3800 var endVal = ''; 3801 var color = w.globals.colors[seriesIndex]; 3802 3803 if (w.config.tooltip.x.formatter === undefined) { 3804 if (w.config.xaxis.type === 'datetime') { 3805 var datetimeObj = new DateTime(ctx); 3806 startVal = datetimeObj.formatDate(new Date(start), w.config.tooltip.x.format, true, true); 3807 endVal = datetimeObj.formatDate(new Date(end), w.config.tooltip.x.format, true, true); 3808 } else { 3809 startVal = start; 3810 endVal = end; 3811 } 3812 } else { 3813 startVal = w.config.tooltip.x.formatter(start); 3814 endVal = w.config.tooltip.x.formatter(end); 3815 } 3816 3817 var ylabel = w.globals.labels[dataPointIndex]; 3818 return '<div class="apexcharts-tooltip-rangebar">' + '<div> <span class="series-name" style="color: ' + color + '">' + (w.config.series[seriesIndex].name ? w.config.series[seriesIndex].name : '') + '</span></div>' + '<div> <span class="category">
3818' + ylabel + ': </span> <span class="value start-value">' + startVal + '</span> <span class="separator">-</span> <span class="value end-value">' + endVal + '</span></div>' + '</div>'; 3819 } 3820 }, 3821 xaxis: { 3822 tooltip: { 3823 enabled: false 3824 }, 3825 crosshairs: { 3826 stroke: { 3827 width: 0 3828 } 3829 } 3830 } 3831 }; 3832 } 3833 }, { 3834 key: "area", 3835 value: function area() { 3836 return { 3837 stroke: { 3838 width: 4 3839 }, 3840 fill: { 3841 type: 'gradient', 3842 gradient: { 3843 inverseColors: false, 3844 shade: 'light', 3845 type: 'vertical', 3846 opacityFrom: 0.65, 3847 opacityTo: 0.5, 3848 stops: [0, 100, 100] 3849 } 3850 }, 3851 markers: { 3852 size: 0, 3853 hover: { 3854 sizeOffset: 6 3855 } 3856 }, 3857 tooltip: { 3858 followCursor: false 3859 } 3860 }; 3861 } 3862 }, { 3863 key: "brush", 3864 value: function brush(defaults) { 3865 var ret = { 3866 chart: { 3867 toolbar: { 3868 autoSelected: 'selection', 3869 show: false 3870 }, 3871 zoom: { 3872 enabled: false 3873 } 3874 }, 3875 dataLabels: { 3876 enabled: false 3877 }, 3878 stroke: { 3879 width: 1 3880 }, 3881 tooltip: { 3882 enabled: false 3883 }, 3884 xaxis: { 3885 tooltip: { 3886 enabled: false 3887 } 3888 } 3889 }; 3890 return Utils.extend(defaults, ret); 3891 } 3892 }, { 3893 key: "stacked100", 3894 value: function stacked100() { 3895 var _this = this; 3896 3897 this.opts.dataLabels = this.opts.dataLabels || {}; 3898 this.opts.dataLabels.formatter = this.opts.dataLabels.formatter || undefined; 3899 var existingDataLabelFormatter = this.opts.dataLabels.formatter; 3900 this.opts.yaxis.forEach(function (yaxe, index) { 3901 _this.opts.yaxis[index].min = 0; 3902 _this.opts.yaxis[index].max = 100; 3903 }); 3904 var isBar = this.opts.chart.type === 'bar'; 3905 3906 if (isBar) { 3907 this.opts.dataLabels.formatter = existingDataLabelFormatter || function (val) { 3908 if (typeof val === 'number') { 3909 return val ? val.toFixed(0) + '%' : val; 3910 } 3911 3912 return val; 3913 }; 3914 } 3915 } // This function removes the left and right spacing in chart for line/area/scatter if xaxis type = category for those charts by converting xaxis = numeric. Numeric/Datetime xaxis prevents the unnecessary spacing in the left/right of the chart area 3916 3917 }, { 3918 key: "bubble", 3919 value: function bubble() { 3920 return { 3921 dataLabels: { 3922 style: { 3923 colors: ['#fff'] 3924 } 3925 }, 3926 tooltip: { 3927 shared: false, 3928 intersect: true 3929 }, 3930 xaxis: { 3931 crosshairs: { 3932 width: 0 3933 } 3934 }, 3935 fill: { 3936 type: 'solid', 3937 gradient: { 3938 shade: 'light', 3939 inverse: true, 3940 shadeIntensity: 0.55, 3941 opacityFrom: 0.4, 3942 opacityTo: 0.8 3943 } 3944 } 3945 }; 3946 } 3947 }, { 3948 key: "scatter", 3949 value: function scatter() { 3950 return { 3951 dataLabels: { 3952 enabled: false 3953 }, 3954 tooltip: { 3955 shared: false, 3956 intersect: true 3957 }, 3958 markers: { 3959 size: 6, 3960 strokeWidth: 2, 3961 hover: { 3962 sizeOffset: 2 3963 } 3964 } 3965 }; 3966 } 3967 }, { 3968 key: "heatmap", 3969 value: function heatmap() { 3970 return { 3971 chart: { 3972 stacked: false, 3973 zoom: { 3974 enabled: false 3975 } 3976 }, 3977 fill: { 3978 opacity: 1 3979 }, 3980 dataLabels: { 3981 style: { 3982 colors: ['#fff'] 3983 } 3984 }, 3985 stroke: { 3986 colors: ['#fff'] 3987 }, 3988 tooltip: { 3989 followCursor: true, 3990 marker: { 3991 show: false 3992 }, 3993 x: { 3994 show: false 3995 } 3996 }, 3997 legend: { 3998 position: 'top', 3999 markers: {
4000 shape: 'square', 4001 size: 10, 4002 offsetY: 2 4003 } 4004 }, 4005 grid: { 4006 padding: { 4007 right: 20 4008 } 4009 } 4010 }; 4011 } 4012 }, { 4013 key: "pie", 4014 value: function pie() { 4015 return { 4016 chart: { 4017 toolbar: { 4018 show: false 4019 } 4020 }, 4021 plotOptions: { 4022 pie: { 4023 donut: { 4024 labels: { 4025 show: false 4026 } 4027 } 4028 } 4029 }, 4030 dataLabels: { 4031 formatter: function formatter(val) { 4032 return val.toFixed(1) + '%'; 4033 }, 4034 style: { 4035 colors: ['#fff'] 4036 }, 4037 dropShadow: { 4038 enabled: true 4039 } 4040 }, 4041 stroke: { 4042 colors: ['#fff'] 4043 }, 4044 fill: { 4045 opacity: 1, 4046 gradient: { 4047 shade: 'dark', 4048 shadeIntensity: 0.35, 4049 inverseColors: false, 4050 stops: [0, 100, 100] 4051 } 4052 }, 4053 padding: { 4054 right: 0, 4055 left: 0 4056 }, 4057 tooltip: { 4058 theme: 'dark', 4059 fillSeriesColor: true 4060 }, 4061 legend: { 4062 position: 'right' 4063 } 4064 }; 4065 } 4066 }, { 4067 key: "donut", 4068 value: function donut() { 4069 return { 4070 chart: { 4071 toolbar: { 4072 show: false 4073 } 4074 }, 4075 dataLabels: { 4076 formatter: function formatter(val) { 4077 return val.toFixed(1) + '%'; 4078 }, 4079 style: { 4080 colors: ['#fff'] 4081 }, 4082 dropShadow: { 4083 enabled: true 4084 } 4085 }, 4086 stroke: { 4087 colors: ['#fff'] 4088 }, 4089 fill: { 4090 opacity: 1, 4091 gradient: { 4092 shade: 'dark', 4093 shadeIntensity: 0.4, 4094 inverseColors: false, 4095 type: 'vertical', 4096 opacityFrom: 1, 4097 opacityTo: 1, 4098 stops: [70, 98, 100] 4099 } 4100 }, 4101 padding: { 4102 right: 0, 4103 left: 0 4104 }, 4105 tooltip: { 4106 theme: 'dark', 4107 fillSeriesColor: true 4108 }, 4109 legend: { 4110 position: 'right' 4111 } 4112 }; 4113 } 4114 }, { 4115 key: "radar", 4116 value: function radar() { 4117 this.opts.yaxis[0].labels.style.fontSize = '13px'; 4118 this.opts.yaxis[0].labels.offsetY = 6; 4119 return { 4120 dataLabels: { 4121 enabled: true, 4122 style: { 4123 colors: ['#a8a8a8'], 4124 fontSize: '11px' 4125 } 4126 }, 4127 stroke: { 4128 width: 2 4129 }, 4130 markers: { 4131 size: 3, 4132 strokeWidth: 1, 4133 strokeOpacity: 1 4134 }, 4135 fill: { 4136 opacity: 0.2 4137 }, 4138 tooltip: { 4139 shared: false, 4140 intersect: true, 4141 followCursor: true 4142 }, 4143 grid: { 4144 show: false 4145 }, 4146 xaxis: { 4147 tooltip: { 4148 enabled: false 4149 }, 4150 crosshairs: { 4151 show: false 4152 } 4153 } 4154 }; 4155 } 4156 }, { 4157 key: "radialBar", 4158 value: function radialBar() { 4159 return { 4160 chart: { 4161 animations: { 4162 dynamicAnimation: { 4163 enabled: true, 4164 speed: 800 4165 } 4166 }, 4167 toolbar: { 4168 show: false 4169 } 4170 }, 4171 fill: { 4172 gradient: { 4173 shade: 'dark', 4174 shadeIntensity: 0.4, 4175 inverseColors: false, 4176 type: 'diagonal2', 4177 opacityFrom: 1, 4178 opacityTo: 1, 4179 stops: [70, 98, 100] 4180 } 4181 }, 4182 padding: { 4183 right: 0, 4184 left: 0 4185 }, 4186 legend: { 4187 show: false, 4188 position: 'right' 4189 }, 4190 tooltip: { 4191 enabled: false, 4192 fillSeriesColor: true 4193 } 4194 }; 4195 } 4196 }], [{ 4197 key: "convertCatToNumeric", 4198 value: function convertCatToNumeric(opts) { 4199 opts.xaxis.type = 'numeric'; 4200 opts.xaxis.convertedCatToNumeric = true; 4201 opts.xaxis.labels = opts.xaxis.labels || {}; 4202 4203 opts.xaxis.labels.formatter = opts.xaxis.labels.formatter || function (val) { 4204 return val; 4205 }; 4206 4207 opts.chart = opts.chart || {}; 4208 opts.chart.zoom = opts.chart.zoom || window.Apex.chart && window.Apex.chart.zoom || {}; 4209 var defaultFormatter = opts.xaxis.labels.formatter; 4210 var labels = opts.xaxis.categories && opts.xaxis.categories.length ? opts.xaxis.categories : opts.labels; 4211 4212 if (labels && labels.length) { 4213 opts.xaxis.labels.formatter = function (val) { 4214 return defaultFormatter(labels[val - 1]); 4215 }; 4216 } 4217 4218 opts.xaxis.categories = []; 4219 opts.labels = []; 4220 opts.chart.zoom.enabled = opts.chart.zoom.enabled || false; 4221 return opts; 4222 } 4223 }]); 4224 4225 return Defaults; 4226 }(); 4227 4228 /* 4229 ** Util functions which are dependent on ApexCharts instance 4230 */ 4231 var CoreUtils = 4232 /*#__PURE__*/ 4233 function () { 4234 function CoreUtils(ctx) { 4235 _classCallCheck(this, CoreUtils); 4236 4237 this.ctx = ctx; 4238 this.w = ctx.w; 4239 } 4240 4241 _createClass(CoreUtils, [{ 4242 key: "getStackedSeriesTotals", 4243 4244 /** 4245 * @memberof CoreUtils 4246 * returns the sum of all individual values in a multiple stacked series 4247 * Eg. w.globals.series = [[32,33,43,12], [2,3,5,1]] 4248 * @return [34,36,48,13] 4249 **/ 4250 value: function getStackedSeriesTotals() { 4251 var w = this.w; 4252 var total = []; 4253 4254 for (var i = 0; i < w.globals.series[w.globals.maxValsInArrayIndex].length; i++) { 4255 var t = 0; 4256 4257 for (var j = 0; j < w.globals.series.length; j++) { 4258 t += w.globals.series[j][i]; 4259 } 4260 4261 total.push(t); 4262 } 4263 4264 w.globals.stackedSeriesTotals = total; 4265 return total; 4266 } // get total of the all values inside all series 4267 4268 }, { 4269 key: "getSeriesTotalByIndex", 4270 value: function getSeriesTotalByIndex() { 4271 var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 4272 4273 if (index === null) { 4274 // non-plot chart types - pie / donut / circle 4275 return this.w.config.series.reduce(function (acc, cur) { 4276 return acc + cur; 4277 }, 0); 4278 } else { 4279 // axis charts - supporting multiple series 4280 return this.w.globals.series[index].reduce(function (acc, cur) { 4281 return acc + cur; 4282 }, 0); 4283 } 4284 } 4285 }, { 4286 key: "isSeriesNull", 4287 value: function isSeriesNull() { 4288 var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 4289 var r = []; 4290 4291 if (index === null) { 4292 // non-plot chart types - pie / donut / circle 4293 r = this.w.config.series.filter(function (d) { 4294 return d !== null; 4295 }); 4296 } else { 4297 // axis charts - supporting multiple series 4298 r = this.w.globals.series[index].filter(function (d) { 4299 return d !== null; 4300 }); 4301 } 4302 4303 return r.length === 0; 4304 } 4305 }, { 4306 key: "seriesHaveSameValues", 4307 value: function seriesHaveSameValues(index) { 4308 return this.w.globals.series[index].every(function (val, i, arr) { 4309 return val === arr[0]; 4310 }); 4311 } // maxValsInArrayIndex is the index of series[] which has the largest number of items 4312 4313 }, { 4314 key: "getLargestSeries", 4315 value: function getLargestSeries() { 4316 var w = this.w; 4317 w.globals.maxValsInArrayIndex = w.globals.series.map(function (a) { 4318 return a.length; 4319 }).indexOf(Math.max.apply(Math, w.globals.series.map(function (a) { 4320 return a.length; 4321 }))); 4322 } 4323 }, { 4324 key: "getLargestMarkerSize", 4325 value: function getLargestMarkerSize() { 4326 var w = this.w; 4327 var size = 0; 4328 w.globals.markers.size.forEach(function (m) { 4329 size = Math.max(size, m); 4330 }); 4331 w.globals.markers.largestSize = size; 4332 return size; 4333 } 4334 /** 4335 * @memberof Core 4336 * returns the sum of all values in a series 4337 * Eg. w.globals.series = [[32,33,43,12], [2,3,5,1]] 4338 * @return [120, 11] 4339 **/ 4340 4341 }, { 4342 key: "getSeriesTotals", 4343 value: function getSeriesTotals() { 4344 var w = this.w; 4345 w.globals.seriesTotals = w.globals.series.map(function (ser, index) { 4346 var total = 0; 4347 4348 if (Array.isArray(ser)) { 4349 for (var j = 0; j < ser.length; j++) { 4350 total += ser[j]; 4351 } 4352 } else { 4353 // for pie/donuts/gauges 4354 total += ser; 4355 } 4356 4357 return total; 4358 }); 4359 } 4360 }, { 4361 key: "getSeriesTotalsXRange", 4362 value: function getSeriesTotalsXRange(minX, maxX) { 4363 var w = this.w; 4364 var seriesTotalsXRange = w.globals.series.map(function (ser, index) { 4365 var total = 0; 4366 4367 for (var j = 0; j < ser.length; j++) { 4368 if (w.globals.seriesX[index][j] > minX && w.globals.seriesX[index][j] < maxX) { 4369 total += ser[j]; 4370 } 4371 } 4372 4373 return total; 4374 }); 4375 return seriesTotalsXRange; 4376 } 4377 /** 4378 * @memberof CoreUtils 4379 * returns the percentage value of all individual values which can be used in a 100% stacked series 4380 * Eg. w.globals.series = [[32, 33, 43, 12], [2, 3, 5, 1]] 4381 * @return [[94.11, 91.66, 89.58, 92.30], [5.88, 8.33, 10.41, 7.7
4381]] 4382 **/ 4383 4384 }, { 4385 key: "getPercentSeries", 4386 value: function getPercentSeries() { 4387 var w = this.w; 4388 w.globals.seriesPercent = w.globals.series.map(function (ser, index) { 4389 var seriesPercent = []; 4390 4391 if (Array.isArray(ser)) { 4392 for (var j = 0; j < ser.length; j++) { 4393 var total = w.globals.stackedSeriesTotals[j]; 4394 var percent = 100 * ser[j] / total; 4395 seriesPercent.push(percent); 4396 } 4397 } else { 4398 var _total = w.globals.seriesTotals.reduce(function (acc, val) { 4399 return acc + val; 4400 }, 0); 4401 4402 var _percent = 100 * ser / _total; 4403 4404 seriesPercent.push(_percent); 4405 } 4406 4407 return seriesPercent; 4408 }); 4409 } 4410 }, { 4411 key: "getCalculatedRatios", 4412 value: function getCalculatedRatios() { 4413 var gl = this.w.globals; 4414 var yRatio = []; 4415 var invertedYRatio = 0; 4416 var xRatio = 0; 4417 var initialXRatio = 0; 4418 var invertedXRatio = 0; 4419 var zRatio = 0; 4420 var baseLineY = []; 4421 var baseLineInvertedY = 0.1; 4422 var baseLineX = 0; 4423 gl.yRange = []; 4424 4425 if (gl.isMultipleYAxis) { 4426 for (var i = 0; i < gl.minYArr.length; i++) { 4427 gl.yRange.push(Math.abs(gl.minYArr[i] - gl.maxYArr[i])); 4428 baseLineY.push(0); 4429 } 4430 } else { 4431 gl.yRange.push(Math.abs(gl.minY - gl.maxY)); 4432 } 4433 4434 gl.xRange = Math.abs(gl.maxX - gl.minX); 4435 gl.zRange = Math.abs(gl.maxZ - gl.minZ); // multiple y axis 4436 4437 for (var _i = 0; _i < gl.yRange.length; _i++) { 4438 yRatio.push(gl.yRange[_i] / gl.gridHeight); 4439 } 4440 4441 xRatio = gl.xRange / gl.gridWidth; 4442 initialXRatio = Math.abs(gl.initialmaxX - gl.initialminX) / gl.gridWidth; 4443 invertedYRatio = gl.yRange / gl.gridWidth; 4444 invertedXRatio = gl.xRange / gl.gridHeight; 4445 zRatio = gl.zRange / gl.gridHeight * 16; 4446 4447 if (gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0) { 4448 // Negative numbers present in series 4449 gl.hasNegs = true; 4450 } 4451 4452 if (gl.isMultipleYAxis) { 4453 baseLineY = []; // baseline variables is the 0 of the yaxis which will be needed when there are negatives 4454 4455 for (var _i2 = 0; _i2 < yRatio.length; _i2++) { 4456 baseLineY.push(-gl.minYArr[_i2] / yRatio[_i2]); 4457 } 4458 } else { 4459 baseLineY.push(-gl.minY / yRatio[0]); 4460 4461 if (gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0) { 4462 baseLineInvertedY = -gl.minY / invertedYRatio; // this is for bar chart 4463 4464 baseLineX = gl.minX / xRatio; 4465 } 4466 } 4467 4468 return { 4469 yRatio: yRatio, 4470 invertedYRatio: invertedYRatio, 4471 zRatio: zRatio, 4472 xRatio: xRatio, 4473 initialXRatio: initialXRatio, 4474 invertedXRatio: invertedXRatio, 4475 baseLineInvertedY: baseLineInvertedY, 4476 baseLineY: baseLineY, 4477 baseLineX: baseLineX 4478 }; 4479 } 4480 }, { 4481 key: "getLogSeries", 4482 value: function getLogSeries(series) { 4483 var w = this.w; 4484 w.globals.seriesLog = series.map(function (s, i) { 4485 if (w.config.yaxis[i] && w.config.yaxis[i].logarithmic) { 4486 return s.map(function (d) { 4487 if (d === null) return null; 4488 var logVal = (Math.log(d) - Math.log(w.globals.minYArr[i])) / (Math.log(w.globals.maxYArr[i]) - Math.log(w.globals.minYArr[i])); 4489 return logVal; 4490 }); 4491 } else { 4492 return s; 4493 } 4494 }); 4495 return w.globals.seriesLog; 4496 } 4497 }, { 4498 key: "getLogYRatios", 4499 value: function getLogYRatios(yRatio) { 4500 var _this = this; 4501 4502 var w = this.w; 4503 var gl = this.w.globals; 4504 gl.yLogRatio = yRatio.slice(); 4505 gl.logYRange = gl.yRange.map(function (yRange, i) { 4506 if (w.config.yaxis[i] && _this.w.config.yaxis[i].logarithmic) { 4507 var maxY = -Number.MAX_VALUE; 4508 var minY = Number.MIN_VALUE; 4509 var range = 1; 4510 gl.seriesLog.forEach(function (s, si) {
4511 s.forEach(function (v) { 4512 if (w.config.yaxis[si] && w.config.yaxis[si].logarithmic) { 4513 maxY = Math.max(v, maxY); 4514 minY = Math.min(v, minY); 4515 } 4516 }); 4517 }); 4518 range = Math.pow(gl.yRange[i], Math.abs(minY - maxY) / gl.yRange[i]); 4519 gl.yLogRatio[i] = range / gl.gridHeight; 4520 return range; 4521 } 4522 }); 4523 return gl.yLogRatio; 4524 } // Some config objects can be array - and we need to extend them correctly 4525 4526 }], [{ 4527 key: "checkComboSeries", 4528 value: function checkComboSeries(series) { 4529 var comboCharts = false; 4530 var comboChartsHasBars = false; // if user specified a type in series too, turn on comboCharts flag 4531 4532 if (series.length && typeof series[0].type !== 'undefined') { 4533 comboCharts = true; 4534 series.forEach(function (s) { 4535 if (s.type === 'bar' || s.type === 'column') { 4536 comboChartsHasBars = true; 4537 } 4538 }); 4539 } 4540 4541 return { 4542 comboCharts: comboCharts, 4543 comboChartsHasBars: comboChartsHasBars 4544 }; 4545 } 4546 }, { 4547 key: "extendArrayProps", 4548 value: function extendArrayProps(configInstance, options) { 4549 if (options.yaxis) { 4550 options = configInstance.extendYAxis(options); 4551 } 4552 4553 if (options.annotations) { 4554 if (options.annotations.yaxis) { 4555 options = configInstance.extendYAxisAnnotations(options); 4556 } 4557 4558 if (options.annotations.xaxis) { 4559 options = configInstance.extendXAxisAnnotations(options); 4560 } 4561 4562 if (options.annotations.points) { 4563 options = configInstance.extendPointAnnotations(options); 4564 } 4565 } 4566 4567 return options; 4568 } 4569 }]); 4570 4571 return CoreUtils; 4572 }(); 4573 4574 /** 4575 * ApexCharts Config Class for extending user options with pre-defined ApexCharts config. 4576 * 4577 * @module Config 4578 **/ 4579 4580 var Config = 4581 /*#__PURE__*/ 4582 function () { 4583 function Config(opts) { 4584 _classCallCheck(this, Config); 4585 4586 this.opts = opts; 4587 } 4588 4589 _createClass(Config, [{ 4590 key: "init", 4591 value: function init() { 4592 var opts = this.opts; 4593 var options = new Options(); 4594 var defaults = new Defaults(opts); 4595 this.chartType = opts.chart.type; 4596 4597 if (this.chartType === 'histogram') { 4598 // technically, a histogram can be drawn by a column chart with no spaces in between 4599 opts.chart.type = 'bar'; 4600 opts = Utils.extend({ 4601 plotOptions: { 4602 bar: { 4603 columnWidth: '99.99%' 4604 } 4605 } 4606 }, opts); 4607 } 4608 4609 opts.series = this.checkEmptySeries(opts.series); 4610 opts = this.extendYAxis(opts); 4611 opts = this.extendAnnotations(opts); 4612 var config = options.init(); 4613 var newDefaults = {}; 4614 4615 if (opts && _typeof(opts) === 'object') { 4616 var chartDefaults = {}; 4617 4618 switch (this.chartType) { 4619 case 'line': 4620 chartDefaults = defaults.line(); 4621 break; 4622 4623 case 'area': 4624 chartDefaults = defaults.area(); 4625 break; 4626 4627 case 'bar': 4628 chartDefaults = defaults.bar(); 4629 break; 4630 4631 case 'candlestick': 4632 chartDefaults = defaults.candlestick(); 4633 break; 4634 4635 case 'rangeBar': 4636 chartDefaults = defaults.rangeBar(); 4637 break; 4638 4639 case 'histogram': 4640 chartDefaults = defaults.bar(); 4641 break; 4642 4643 case 'bubble': 4644 chartDefaults = defaults.bubble(); 4645 break; 4646 4647 case 'scatter': 4648 chartDefaults = defaults.scatter(); 4649 break; 4650 4651 case 'heatmap': 4652 chartDefaults = defaults.heatmap(); 4653 break; 4654 4655 case 'pie': 4656 chartDefaults = defaults.pie(); 4657 break; 4658 4659 case 'donut': 4660 chartDefaults = defaults.donut(); 4661 break; 4662 4663 case 'radar': 4664 chartDefaults = defaults.radar(); 4665 break; 4666 4667 case 'radialBar': 4668 chartDefaults = defaults.radialBar(); 4669 break; 4670 4671 default: 4672 chartDefaults = defaults.line(); 4673 } 4674 4675 if (opts.chart.brush && opts.chart.brush.enabled) { 4676 chartDefaults = defaults.brush(chartDefaults); 4677 } 4678 4679 if (opts.chart.stacked && opts.chart.stackType === '100%') { 4680 defaults.stacked100(); 4681 } // If user has specified a dark theme, make the tooltip dark too 4682 4683 4684 this.checkForDarkTheme(window.Apex); // check global window Apex options 4685 4686 this.checkForDarkTheme(opts); // check locally passed options 4687 4688 opts.xaxis = opts.xaxis || window.Apex.xaxis || {}; 4689 var combo = CoreUtils.checkComboSeries(opts.series); 4690 4691 if ((opts.chart.type === 'line' || opts.chart.type === 'area' || opts.chart.type === 'scatter') && !combo.comboChartsHasBars && opts.xaxis.type !== 'datetime' && opts.xaxis.type !== 'numeric' && opts.xaxis.tickPlacement !== 'between') { 4692 opts = Defaults.convertCatToNumeric(opts); 4693 } 4694 4695 if (opts.chart.sparkline && opts.chart.sparkline.enabled || window.Apex.chart && window.Apex.chart.sparkline && window.Apex.chart.sparkline.enabled) { 4696 chartDefaults = defaults.sparkline(chartDefaults); 4697 } 4698 4699 newDefaults = Utils.extend(config, chartDefaults); 4700 } // config should cascade in this fashion 4701 // default-config < global-apex-variable-config < user-defined-config 4702 // get GLOBALLY defined options and merge with the default config 4703 4704 4705 var mergedWithDefaultConfig = Utils.extend(newDefaults, window.Apex); // get the merged config and extend with user defined config 4706 4707 config = Utils.extend(mergedWithDefaultConfig, opts); // some features are not supported. those mismatches should be handled 4708 4709 config = this.handleUserInputErrors(config); 4710 return config; 4711 } 4712 }, { 4713 key: "extendYAxis", 4714 value: function extendYAxis(opts) { 4715 var options = new Options(); 4716 4717 if (typeof opts.yaxis === 'undefined') { 4718 opts.yaxis = {}; 4719 } // extend global yaxis config (only if object is provided / not an array) 4720 4721
4722 if (opts.yaxis.constructor !== Array && window.Apex.yaxis && window.Apex.yaxis.constructor !== Array) { 4723 opts.yaxis = Utils.extend(opts.yaxis, window.Apex.yaxis); 4724 } // as we can't extend nested object's array with extend, we need to do it first 4725 // user can provide either an array or object in yaxis config 4726 4727 4728 if (opts.yaxis.constructor !== Array) { 4729 // convert the yaxis to array if user supplied object 4730 opts.yaxis = [Utils.extend(options.yAxis, opts.yaxis)]; 4731 } else { 4732 opts.yaxis = Utils.extendArray(opts.yaxis, options.yAxis); 4733 } 4734 4735 return opts; 4736 } // annotations also accepts array, so we need to extend them manually 4737 4738 }, { 4739 key: "extendAnnotations", 4740 value: function extendAnnotations(opts) { 4741 if (typeof opts.annotations === 'undefined') { 4742 opts.annotations = {}; 4743 opts.annotations.yaxis = []; 4744 opts.annotations.xaxis = []; 4745 opts.annotations.points = []; 4746 } 4747 4748 opts = this.extendYAxisAnnotations(opts); 4749 opts = this.extendXAxisAnnotations(opts); 4750 opts = this.extendPointAnnotations(opts); 4751 return opts; 4752 } 4753 }, { 4754 key: "extendYAxisAnnotations", 4755 value: function extendYAxisAnnotations(opts) { 4756 var options = new Options(); 4757 opts.annotations.yaxis = Utils.extendArray(typeof opts.annotations.yaxis !== 'undefined' ? opts.annotations.yaxis : [], options.yAxisAnnotation); 4758 return opts; 4759 } 4760 }, { 4761 key: "extendXAxisAnnotations", 4762 value: function extendXAxisAnnotations(opts) { 4763 var options = new Options(); 4764 opts.annotations.xaxis = Utils.extendArray(typeof opts.annotations.xaxis !== 'undefined' ? opts.annotations.xaxis : [], options.xAxisAnnotation); 4765 return opts; 4766 } 4767 }, { 4768 key: "extendPointAnnotations", 4769 value: function extendPointAnnotations(opts) { 4770 var options = new Options(); 4771 opts.annotations.points = Utils.extendArray(typeof opts.annotations.points !== 'undefined' ? opts.annotations.points : [], options.pointAnnotation); 4772 return opts; 4773 } 4774 }, { 4775 key: "checkForDarkTheme", 4776 value: function checkForDarkTheme(opts) { 4777 if (opts.theme && opts.theme.mode === 'dark') { 4778 if (!opts.tooltip) { 4779 opts.tooltip = {}; 4780 } 4781 4782 if (opts.tooltip.theme !== 'light') { 4783 opts.tooltip.theme = 'dark'; 4784 } 4785 4786 if (!opts.chart.foreColor) { 4787 opts.chart.foreColor = '#f6f7f8'; 4788 } 4789 4790 if (!opts.theme.palette) { 4791 opts.theme.palette = 'palette4'; 4792 } 4793 } 4794 } 4795 }, { 4796 key: "checkEmptySeries", 4797 value: function checkEmptySeries(ser) { 4798 if (ser.length === 0) { 4799 return [{ 4800 data: [] 4801 }]; 4802 } 4803 4804 return ser; 4805 } 4806 }, { 4807 key: "handleUserInputErrors", 4808 value: function handleUserInputErrors(opts) { 4809 var config = opts; // conflicting tooltip option. intersect makes sure to focus on 1 point at a time. Shared cannot be used along with it 4810 4811 if (config.tooltip.shared && config.tooltip.intersect) { 4812 throw new Error('tooltip.shared cannot be enabled when tooltip.intersect is true. Turn off any other option by setting it to false.'); 4813 } 4814 4815 if (config.chart.scroller) { 4816 console.warn('Scroller has been deprecated since v2.0.0. Please remove the configuration for chart.scroller'); 4817 } 4818 4819 if ((config.chart.type === 'bar' || config.chart.type === 'rangeBar') && config.plotOptions.bar.horizontal) { 4820 // No multiple yaxis for bars 4821 if (config.yaxis.length > 1) { 4822 throw new Error('Multiple Y Axis for bars are not supported. Switch to column chart by setting plotOptions.bar.horizontal=false'); 4823 } // if yaxis is reversed in horizontal bar chart, you should draw the y-axis on right side 4824 4825 4826 if (config.yaxis[0].reversed) { 4827 config.yaxis[0].opposite = true; 4828 } 4829 4830 config.xaxis.tooltip.enabled = false; // no xaxis tooltip for horizontal bar 4831 4832 config.yaxis[0].tooltip.enabled = false; // no xaxis tooltip for horizontal bar 4833 4834 config.chart.zoom.enabled = false; // no zooming for horz bars 4835 } 4836 4837 if (config.chart.type === 'bar' || config.chart.type === 'rangeBar') { 4838 if (config.tooltip.shared) { 4839 if (config.xaxis.crosshairs.width === 'barWidth' && config.series.length > 1) { 4840 console.warn('crosshairs.width = "barWidth" is only supported in single series, not in a multi-series barChart.'); 4841 config.xaxis.crosshairs.width = 'tickWidth'; 4842 } 4843 4844 if (config.plotOptions.bar.horizontal) { 4845 config.states.hover.type = 'none'; 4846 config.tooltip.shared = false; 4847 } 4848 4849 if (!config.tooltip.followCursor) { 4850 console.warn('followCursor option in shared columns cannot be turned off. Please set %ctooltip.followCursor: true', 'color: blue;'); 4851 config.tooltip.followCursor = true; 4852 } 4853 } 4854 } 4855 4856 if (config.chart.type === 'candlestick') { 4857 if (config.yaxis[0].reversed) {
4858 console.warn('Reversed y-axis in candlestick chart is not supported.'); 4859 config.yaxis[0].reversed = false; 4860 } 4861 } 4862 4863 if (config.chart.group && config.yaxis[0].labels.minWidth === 0) { 4864 console.warn('It looks like you have multiple charts in synchronization. You must provide yaxis.labels.minWidth which must be EQUAL for all grouped charts to prevent incorrect behaviour.'); 4865 } // if user supplied array for stroke width, it will only be applicable to line/area charts, for any other charts, revert back to Number 4866 4867 4868 if (Array.isArray(config.stroke.width)) { 4869 if (config.chart.type !== 'line' && config.chart.type !== 'area') { 4870 console.warn('stroke.width option accepts array only for line and area charts. Reverted back to Number'); 4871 config.stroke.width = config.stroke.width[0]; 4872 } 4873 } 4874 4875 return config; 4876 } 4877 }]); 4878 4879 return Config; 4880 }(); 4881 4882 var Globals = 4883 /*#__PURE__*/ 4884 function () { 4885 function Globals() { 4886 _classCallCheck(this, Globals); 4887 } 4888 4889 _createClass(Globals, [{ 4890 key: "globalVars", 4891 value: function globalVars(config) { 4892 return { 4893 chartID: null, 4894 // chart ID - apexcharts-cuid 4895 cuid: null, 4896 // chart ID - random numbers excluding "apexcharts" part 4897 events: { 4898 beforeMount: [], 4899 mounted: [], 4900 updated: [], 4901 clicked: [], 4902 selection: [], 4903 dataPointSelection: [], 4904 zoomed: [], 4905 scrolled: [] 4906 }, 4907 colors: [], 4908 clientX: null, 4909 clientY: null, 4910 fill: { 4911 colors: [] 4912 }, 4913 stroke: { 4914 colors: [] 4915 }, 4916 dataLabels: { 4917 style: { 4918 colors: [] 4919 } 4920 }, 4921 radarPolygons: { 4922 fill: { 4923 colors: [] 4924 } 4925 }, 4926 markers: { 4927 colors: [], 4928 size: config.markers.size, 4929 largestSize: 0 4930 }, 4931 animationEnded: false, 4932 isTouchDevice: 'ontouchstart' in window || navigator.msMaxTouchPoints, 4933 isDirty: false, 4934 // chart has been updated after the initial render. This is different than dataChanged property. isDirty means user manually called some method to update 4935 initialConfig: null, 4936 // we will store the first config user has set to go back when user finishes interactions like zooming and come out of it 4937 lastXAxis: [], 4938 lastYAxis: [], 4939 series: [], 4940 // the MAIN series array (y values) 4941 seriesRangeStart: [], 4942 // the clone of series becomes the start in range 4943 seriesRangeEnd: [], 4944 // the end values in range chart 4945 seriesPercent: [], 4946 // the percentage values of the given series 4947 seriesTotals: [], 4948 stackedSeriesTotals: [], 4949 seriesX: [], 4950 // store the numeric x values in this array (x values) 4951 seriesZ: [], 4952 // The 3rd "Z" dimension for bubbles chart (z values) 4953 labels: [], 4954 // store the text to draw on x axis 4955 // Don't mutate the labels, many things including tooltips depends on it! 4956 timelineLabels: [], 4957 // store the timeline Labels in another variable 4958 invertedTimelineLabels: [], 4959 // for rangebar timeline 4960 seriesNames: [], 4961 // same as labels, used in non axis charts 4962 noLabelsProvided: false, 4963 // if user didn't provide any categories/labels or x values, fallback to 1,2,3,4... 4964 allSeriesCollapsed: false, 4965 collapsedSeries: [], 4966 // when user collapses a series, it goes into this array 4967 collapsedSeriesIndices: [], 4968 // this stores the index of the collapsedSeries instead of whole object for quick access 4969 ancillaryCollapsedSeries: [], 4970 // when user collapses an "alwaysVisible" series, it goes into this array 4971 ancillaryCollapsedSeriesIndices: [], 4972 // this stores the index of the ancillaryCollapsedSeries whose y-axis is always visible 4973 risingSeries: [],
4974 // when user re-opens a collapsed series, it goes here 4975 dataFormatXNumeric: false, 4976 // boolean value to indicate user has passed numeric x values 4977 selectedDataPoints: [], 4978 ignoreYAxisIndexes: [], 4979 // when series are being collapsed in multiple y axes, ignore certain index 4980 padHorizontal: 0, 4981 maxValsInArrayIndex: 0, 4982 zoomEnabled: config.chart.toolbar.autoSelected === 'zoom' && config.chart.toolbar.tools.zoom && config.chart.zoom.enabled, 4983 panEnabled: config.chart.toolbar.autoSelected === 'pan' && config.chart.toolbar.tools.pan, 4984 selectionEnabled: config.chart.toolbar.autoSelected === 'selection' && config.chart.toolbar.tools.selection, 4985 yaxis: null, 4986 minY: Number.MIN_VALUE, 4987 // is 5e-324, i.e. the smallest positive number 4988 // NOTE: If there are multiple y axis, the first yaxis array element will be considered for all y values calculations. Rest all will be calculated based on that 4989 maxY: -Number.MAX_VALUE, 4990 // is -1.7976931348623157e+308 4991 // NOTE: The above note for minY applies here as well 4992 minYArr: [], 4993 maxYArr: [], 4994 maxX: -Number.MAX_VALUE, 4995 // is -1.7976931348623157e+308 4996 initialmaxX: -Number.MAX_VALUE, 4997 minX: Number.MIN_VALUE, 4998 // is 5e-324, i.e. the smallest positive number 4999 initialminX: Number.MIN_VALUE, 5000 minZ: Number.MIN_VALUE, 5001 // Max Z value in charts with Z axis 5002 maxZ: -Number.MAX_VALUE, 5003 // Max Z value in charts with Z axis 5004 minXDiff: Number.MAX_VALUE, 5005 mousedown: false, 5006 lastClientPosition: {}, 5007 // don't reset this variable this the chart is destroyed. It is used to detect right or left mousemove in panning 5008 visibleXRange: undefined, 5009 yRange: [], 5010 // this property is the absolute sum of positive and negative values [eg (-100 + 200 = 300)] - yAxis 5011 zRange: 0, 5012 // zAxis Range (for bubble charts) 5013 xRange: 0, 5014 // xAxis range 5015 yValueDecimal: 0, 5016 // are there floating numbers in the series. If yes, this represent the len of the decimals 5017 total: 0, 5018 SVGNS: 'http://www.w3.org/2000/svg', 5019 // svg namespace 5020 svgWidth: 0, 5021 // the whole svg width 5022 svgHeight: 0, 5023 // the whole svg height 5024 noData: false, 5025 // whether there is any data to display or not 5026 locale: {}, 5027 // the current locale values will be preserved here for global access 5028 dom: {}, 5029 // for storing all dom nodes in this particular property 5030 // elWrap: null, // the element that wraps everything 5031 // elGraphical: null, // this contains lines/areas/bars/pies 5032 // elGridRect: null, // paths going outside this area will be clipped 5033 // elGridRectMask: null, // clipping will happen with this mask 5034 // elGridRectMarkerMask: null, // clipping will happen with this mask 5035 // elLegendWrap: null, // the whole legend area 5036 // elDefs: null, // [defs] element 5037 memory: { 5038 methodsToExec: [] 5039 }, 5040 shouldAnimate: true, 5041 skipLastTimelinelabel: false, 5042 // when last label is cropped, skip drawing it 5043 delayedElements: [], 5044 // element which appear after animation has finished 5045 axisCharts: true, 5046 // chart type = line or area or bar 5047 // (refer them also as plot charts in the code) 5048 isXNumeric: false, 5049 // bool: data was provided in a {[x,y], [x,y]} pattern 5050 isDataXYZ: false, 5051 // bool: data was provided in a {[x,y,z]} pattern 5052 resized: false, 5053 // bool: user has resized 5054 resizeTimer: null, 5055 // timeout function to make a small delay before 5056 // drawing when user resized 5057 comboCharts: false, 5058 // bool: whether it's a combination of line/column 5059 comboChartsHasBars: false, 5060 // bool: whether it's a combination of line/column 5061 dataChanged: false, 5062 // bool: has data changed dynamically 5063 previousPaths: [], 5064 // array: when data is changed, it will animate from 5065 // previous paths 5066 seriesXvalues: [], 5067 // we will need this in tooltip (it's x position) 5068 // when we will have unequal x values, we will need 5069 // some way to get x value depending on mouse pointer 5070 seriesYvalues: [], 5071 // we will need this when deciding which series 5072 // user hovered on 5073 seriesCandleO: [], 5074 // candle stick open values 5075 seriesCandleH: [], 5076 // candle stick high values 5077 seriesCandleL: [], 5078 // candle stick low values 5079 seriesCandleC: [], 5080 // candle stick close values 5081 allSeriesHasEqualX: true, 5082 dataPoints: 0, 5083 // the longest series length 5084 pointsArray: [], 5085 // store the points positions here to draw later on hover 5086 // format is - [[x,y],[x,y]... [x,y]] 5087 dataLabelsRects: [], 5088 // store the positions of datalabels to prevent collision 5089 lastDrawnDataLabelsIndexes: [], 5090 hasNullValues: false,
5091 // bool: whether series contains null values 5092 easing: null, 5093 // function: animation effect to apply 5094 zoomed: false, 5095 // whether user has zoomed or not 5096 gridWidth: 0, 5097 // drawable width of actual graphs (series paths) 5098 gridHeight: 0, 5099 // drawable height of actual graphs (series paths) 5100 yAxisScale: [], 5101 xAxisScale: null, 5102 xAxisTicksPositions: [], 5103 timescaleTicks: [], 5104 rotateXLabels: false, 5105 defaultLabels: false, 5106 xLabelFormatter: undefined, 5107 // formatter for x axis labels 5108 yLabelFormatters: [], 5109 xaxisTooltipFormatter: undefined, 5110 // formatter for x axis tooltip 5111 ttKeyFormatter: undefined, 5112 ttVal: undefined, 5113 ttZFormatter: undefined, 5114 LINE_HEIGHT_RATIO: 1.618, 5115 xAxisLabelsHeight: 0, 5116 yAxisLabelsWidth: 0, 5117 scaleX: 1, 5118 scaleY: 1, 5119 translateX: 0, 5120 translateY: 0, 5121 translateYAxisX: [], 5122 yLabelsCoords: [], 5123 yTitleCoords: [], 5124 yAxisWidths: [], 5125 translateXAxisY: 0, 5126 translateXAxisX: 0, 5127 tooltip: null, 5128 tooltipOpts: null 5129 }; 5130 } 5131 }, { 5132 key: "init", 5133 value: function init(config) { 5134 var globals = this.globalVars(config); 5135 globals.initialConfig = Utils.extend({}, config); 5136 globals.initialSeries = JSON.parse(JSON.stringify(globals.initialConfig.series)); 5137 globals.lastXAxis = JSON.parse(JSON.stringify(globals.initialConfig.xaxis)); 5138 globals.lastYAxis = JSON.parse(JSON.stringify(globals.initialConfig.yaxis)); 5139 return globals; 5140 } 5141 }]); 5142 5143 return Globals; 5144 }(); 5145 5146 /** 5147 * ApexCharts Base Class for extending user options with pre-defined ApexCharts config. 5148 * 5149 * @module Base 5150 **/ 5151 5152 var Base = 5153 /*#__PURE__*/ 5154 function () { 5155 function Base(opts) { 5156 _classCallCheck(this, Base); 5157 5158 this.opts = opts; 5159 } 5160 5161 _createClass(Base, [{ 5162 key: "init", 5163 value: function init() { 5164 var config = new Config(this.opts).init(); 5165 var globals = new Globals().init(config); 5166 var w = { 5167 config: config, 5168 globals: globals 5169 }; 5170 return w; 5171 } 5172 }]); 5173 5174 return Base; 5175 }(); 5176 5177 /** 5178 * ApexCharts Fill Class for setting fill options of the paths. 5179 * 5180 * @module Fill 5181 **/ 5182 5183 var Fill = 5184 /*#__PURE__*/ 5185 function () { 5186 function Fill(ctx) { 5187 _classCallCheck(this, Fill); 5188 5189 this.ctx = ctx; 5190 this.w = ctx.w; 5191 this.opts = null; 5192 this.seriesIndex = 0; 5193 } 5194 5195 _createClass(Fill, [{ 5196 key: "clippedImgArea", 5197 value: function clippedImgArea(params) { 5198 var w = this.w; 5199 var cnf = w.config; 5200 var svgW = parseInt(w.globals.gridWidth); 5201 var svgH = parseInt(w.globals.gridHeight); 5202 var size = svgW > svgH ? svgW : svgH; 5203 var fillImg = params.image; 5204 var imgWidth = 0; 5205 var imgHeight = 0; 5206 5207 if (typeof params.width === 'undefined' && typeof params.height === 'undefined') { 5208 if (cnf.fill.image.width !== undefined && cnf.fill.image.height !== undefined) { 5209 imgWidth = cnf.fill.image.width + 1; 5210 imgHeight = cnf.fill.image.height; 5211 } else { 5212 imgWidth = size + 1; 5213 imgHeight = size; 5214 } 5215 } else { 5216 imgWidth = params.width; 5217 imgHeight = params.height; 5218 } 5219 5220 var elPattern = document.createElementNS(w.globals.SVGNS, 'pattern'); 5221 Graphics.setAttrs(elPattern, { 5222 id: params.patternID, 5223 patternUnits: params.patternUnits ? params.patternUnits : 'userSpaceOnUse', 5224 width: imgWidth + 'px', 5225 height: imgHeight + 'px' 5226 }); 5227 var elImage = document.createElementNS(w.globals.SVGNS, 'image'); 5228 elPattern.appendChild(elImage); 5229 elImage.setAttributeNS('http://www.w3.org/1999/xlink', 'href', fillImg); 5230 Graphics.setAttrs(elImage, { 5231 x: 0, 5232 y: 0, 5233 preserveAspectRatio: 'none', 5234 width: imgWidth + 'px', 5235 height: imgHeight + 'px' 5236 }); 5237 elImage.style.opacity = params.opacity; 5238 w.globals.dom.elDefs.node.appendChild(elPattern); 5239 } 5240 }, { 5241 key: "getSeriesIndex", 5242 value: function getSeriesIndex(opts) { 5243 var w = this.w; 5244 5245 if (w.config.chart.type === 'bar' && w.config.plotOptions.bar.distributed || w.config.chart.type === 'heatmap') { 5246 this.seriesIndex = opts.seriesNumber; 5247 } else { 5248 this.seriesIndex = opts.seriesNumber % w.globals.series.length; 5249 } 5250 5251 return this.seriesIndex; 5252 } 5253 }, { 5254 key: "fillPath", 5255 value: function fillPath(opts) { 5256 var w = this.w; 5257 this.opts = opts; 5258 var cnf = this.w.config; 5259 var pathFill; 5260 var patternFill, gradientFill;
5261 this.seriesIndex = this.getSeriesIndex(opts); 5262 var fillColors = this.getFillColors(); 5263 var fillColor = fillColors[this.seriesIndex]; 5264 5265 if (typeof fillColor === 'function') { 5266 fillColor = fillColor({ 5267 seriesIndex: this.seriesIndex, 5268 value: opts.value, 5269 w: w 5270 }); 5271 } 5272 5273 var fillType = this.getFillType(this.seriesIndex); 5274 var fillOpacity = Array.isArray(cnf.fill.opacity) ? cnf.fill.opacity[this.seriesIndex] : cnf.fill.opacity; 5275 var defaultColor = fillColor; 5276 5277 if (opts.color) { 5278 fillColor = opts.color; 5279 } 5280 5281 if (fillColor.indexOf('rgb') === -1) { 5282 defaultColor = Utils.hexToRgba(fillColor, fillOpacity); 5283 } else { 5284 if (fillColor.indexOf('rgba') > -1) { 5285 fillOpacity = 0 + '.' + Utils.getOpacityFromRGBA(fillColors[this.seriesIndex]); 5286 } 5287 } 5288 5289 if (fillType === 'pattern') { 5290 patternFill = this.handlePatternFill(patternFill, fillColor, fillOpacity, defaultColor); 5291 } 5292 5293 if (fillType === 'gradient') { 5294 gradientFill = this.handleGradientFill(gradientFill, fillColor, fillOpacity, this.seriesIndex); 5295 } 5296 5297 if (cnf.fill.image.src.length > 0 && fillType === 'image') { 5298 if (opts.seriesNumber < cnf.fill.image.src.length) { 5299 this.clippedImgArea({ 5300 opacity: fillOpacity, 5301 image: cnf.fill.image.src[opts.seriesNumber], 5302 patternUnits: opts.patternUnits, 5303 patternID: "pattern".concat(w.globals.cuid).concat(opts.seriesNumber + 1) 5304 }); 5305 pathFill = "url(#pattern".concat(w.globals.cuid).concat(opts.seriesNumber + 1, ")"); 5306 } else { 5307 pathFill = defaultColor; 5308 } 5309 } else if (fillType === 'gradient') { 5310 pathFill = gradientFill; 5311 } else if (fillType === 'pattern') { 5312 pathFill = patternFill; 5313 } else { 5314 pathFill = defaultColor; 5315 } // override pattern/gradient if opts.solid is true 5316 5317 5318 if (opts.solid) { 5319 pathFill = defaultColor; 5320 } 5321 5322 return pathFill; 5323 } 5324 }, { 5325 key: "getFillType", 5326 value: function getFillType(seriesIndex) { 5327 var w = this.w; 5328 5329 if (Array.isArray(w.config.fill.type)) { 5330 return w.config.fill.type[seriesIndex]; 5331 } else { 5332 return w.config.fill.type; 5333 } 5334 } 5335 }, { 5336 key: "getFillColors", 5337 value: function getFillColors() { 5338 var w = this.w; 5339 var cnf = w.config; 5340 var opts = this.opts; 5341 var fillColors = []; 5342 5343 if (w.globals.comboCharts) { 5344 if (w.config.series[this.seriesIndex].type === 'line') { 5345 if (w.globals.stroke.colors instanceof Array) { 5346 fillColors = w.globals.stroke.colors; 5347 } else { 5348 fillColors.push(w.globals.stroke.colors); 5349 } 5350 } else { 5351 if (w.globals.fill.colors instanceof Array) { 5352 fillColors = w.globals.fill.colors; 5353 } else { 5354 fillColors.push(w.globals.fill.colors); 5355 } 5356 } 5357 } else { 5358 if (cnf.chart.type === 'line') { 5359 if (w.globals.stroke.colors instanceof Array) { 5360 fillColors = w.globals.stroke.colors; 5361 } else { 5362 fillColors.push(w.globals.stroke.colors); 5363 } 5364 } else { 5365 if (w.globals.fill.colors instanceof Array) { 5366 fillColors = w.globals.fill.colors; 5367 } else { 5368 fillColors.push(w.globals.fill.colors); 5369 } 5370 } 5371 } // colors passed in arguments 5372 5373 5374 if (typeof opts.fillColors !== 'undefined') { 5375 fillColors = []; 5376 5377 if (opts.fillColors instanceof Array) { 5378 fillColors = opts.fillColors.slice(); 5379 } else { 5380 fillColors.push(opts.fillColors); 5381 } 5382 } 5383 5384 return fillColors; 5385 } 5386 }, { 5387 key: "handlePatternFill", 5388 value: function handlePatternFill(patternFill, fillColor, fillOpacity, defaultColor) { 5389 var cnf = this.w.config; 5390 var opts = this.opts; 5391 var graphics = new Graphics(this.ctx); 5392 var patternStrokeWidth = cnf.fill.pattern.strokeWidth === undefined ? Array.isArray(cnf.stroke.width) ? cnf.stroke.width[this.seriesIndex] : cnf.stroke.width : Array.isArray(cnf.fill.pattern.strokeWidth) ? cnf.fill.pattern.strokeWidth[this.seriesIndex] : cnf.fill.pattern.strokeWidth; 5393 var patternLineColor = fillColor; 5394 5395 if (cnf.fill.pattern.style instanceof Array) { 5396 if (typeof cnf.fill.pattern.style[opts.seriesNumber] !== 'undefined') { 5397 var pf = graphics.drawPattern(cnf.fill.pattern.style[opts.seriesNumber], cnf.fill.pattern.width, cnf.fill.pattern.height, patternLineColor, patternStrokeWidth, fillOpacity); 5398 patternFill = pf; 5399 } else { 5400 patternFill = defaultColor; 5401 } 5402 } else { 5403 patternFill = graphics.drawPattern(cnf.fill.pattern.style, cnf.fill.pattern.width, cnf.fill.pattern.height, patternLineColor, patternStrokeWidth, fillOpacity); 5404 } 5405 5406 return patternFill; 5407 } 5408 }, { 5409 key: "handleGradientFill", 5410 value: function handleGradientFill(gradientFill, fillColor, fillOpacity, i) { 5411 var cnf = this.w.config; 5412 var opts = this.opts; 5413 var graphics = new Graphics(this.ctx); 5414 var utils = new Utils(); 5415 var type = cnf.fill.gradient.type; 5416 var gradientFrom, gradientTo; 5417 var opacityFrom = cnf.fill.gradient.opacityFrom === undefined ? fillOpacity : Array.isArray(cnf.fill.gradient.opacityFrom) ? cnf.fill.gradient.opacityFrom[i] : cnf.fill.gradient.opacityFrom; 5418 var opacityTo = cnf.fill.gradient.opacityTo === undefined ? fillOpacity : Array.isArray(cnf.fill.gradient.opacityTo) ? cnf.fill.gradient.opacityTo[i] : cnf.fill.gradient.opacityTo; 5419 gradientFrom = fillColor; 5420 5421 if (cnf.fill.gradient.gradientToColors === undefined || cnf.fill.gradient.gradientToColors.length === 0) { 5422 if (cnf.fill.gradient.shade === 'dark') { 5423 gradientTo = utils.shadeColor(parseFloat(cnf.fill.gradient.shadeIntensity) * -1, fillColor); 5424 } else { 5425 gradientTo = utils.shadeColor(parseFloat(cnf.fill.gradient.shadeIntensity), fillColor); 5426 } 5427 } else { 5428 gradientTo = cnf.fill.gradient.gradientToColors[opts.seriesNumber]; 5429 } 5430 5431 if (cnf.fill.gradient.inverseColors) { 5432 var t = gradientFrom; 5433 gradientFrom = gradientTo; 5434 gradientTo = t; 5435 } 5436 5437 gradientFill = graphics.drawGradient(type, gradientFrom, gradientTo, opacityFrom, opacityTo, opts.size, cnf.fill.gradient.stops, cnf.fill.gradient.colorStops, i); 5438 return gradientFill; 5439 } 5440 }]); 5441 5442 return Fill; 5443 }(); 5444 5445 /** 5446 * ApexCharts Markers Class for drawing points on y values in axes charts. 5447 * 5448 * @module Markers 5449 **/ 5450 5451 var Markers = 5452 /*#__PURE__*/ 5453 function () { 5454 function Markers(ctx, opts) { 5455 _classCallCheck(this, Markers); 5456 5457 this.ctx = ctx; 5458 this.w = ctx.w; 5459 } 5460 5461 _createClass(Markers, [{ 5462 key: "setGlobalMarkerSize", 5463 value: function setGlobalMarkerSize() { 5464 var w = this.w; 5465 w.globals.markers.size = Array.isArray(w.config.markers.size) ? w.config.markers.size : [w.config.markers.size]; 5466 5467 if (w.globals.markers.size.length > 0) { 5468 if (w.globals.markers.size.length < w.globals.series.length + 1) { 5469 for (var i = 0; i <= w.globals.series.length; i++) { 5470 if (typeof w.globals.markers.size[i] === 'undefined') { 5471 w.globals.markers.size.push(w.globals.markers.size[0]); 5472 } 5473 } 5474 } 5475 } else { 5476 w.globals.markers.size = w.config.series.map(function (s) { 5477 return w.config.markers.size; 5478 }); 5479 } 5480 } 5481 }, { 5482 key: "plotChartMarkers", 5483 value: function plotChartMarkers(pointsPos, seriesIndex, j) { 5484 var _this = this; 5485 5486 var w = this.w; 5487 var i = seriesIndex; 5488 var p = pointsPos; 5489 var elPointsWrap = null; 5490 var graphics = new Graphics(this.ctx); 5491 var point; 5492 5493 if (w.globals.markers.size[seriesIndex] > 0) { 5494 elPointsWrap = graphics.group({ 5495 class: 'apexcharts-series-markers' 5496 }); 5497 elPointsWrap.attr('clip-path', "url(#gridRectMarkerMask".concat(w.globals.cuid, ")")); 5498 } 5499 5500 if (p.x instanceof Array) { 5501 var _loop = function _loop(q) { 5502 var dataPointIndex = j; // a small hack as we have 2 points for the first val to connect it 5503 5504 if (j === 1 && q === 0) dataPointIndex = 0; 5505 if (j === 1 && q === 1) dataPointIndex = 1; 5506 var PointClasses = 'apexcharts-marker'; 5507 5508 if ((w.config.chart.type === 'line' || w.config.chart.type === 'area') && !w.globals.comboCharts && !w.config.tooltip.intersect) { 5509 PointClasses += ' no-pointer-events'; 5510 } 5511 5512 var shouldMarkerDraw = Array.isArray(w.config.markers.size) ? w.globals.markers.size[seriesIndex] > 0 : w.config.markers.size > 0; 5513 5514 if (shouldMarkerDraw) { 5515 if (Utils.isNumber(p.y[q])) { 5516 PointClasses += " w".concat((Math.random() + 1).toString(36).substring(4)); 5517 } else { 5518 PointClasses = 'apexcharts-nullpoint'; 5519 } 5520 5521 var opts = _this.getMarkerConfig(PointClasses, seriesIndex); // discrete markers is an option where user can specify a particular marker with different size and color 5522 5523 5524 w.config.markers.discrete.map(function (marker) { 5525 if (marker.seriesIndex === seriesIndex && marker.dataPointIndex === dataPointIndex) { 5526 opts.pointStrokeColor = marker.strokeColor; 5527 opts.pointFillColor = marker.fillColor; 5528 opts.pSize = marker.size; 5529 } 5530 }); 5531 5532 if (w.config.series[i].data[j]) { 5533 if (w.config.series[i].data[j].fillColor) { 5534 opts.pointFillColor = w.config.series[i].data[j].fillColor; 5535 } 5536 5537 if (w.config.series[i].data[j].strokeColor) { 5538 opts.pointStrokeColor = w.config.series[i].data[j].strokeColor; 5539 } 5540 } 5541 5542 point = graphics.drawMarker(p.x[q], p.y[q], opts); 5543 point.attr('rel', dataPointIndex); 5544 point.attr('j', dataPointIndex); 5545 point.attr('index', seriesIndex); 5546 point.node.setAttribute('default-marker-size', opts.pSize); 5547 var filters = new Filters(_this.ctx); 5548 filters.setSelectionFilter(point, seriesIndex, dataPointIndex); 5549 5550 _this.addEvents(point); 5551 5552 if (elPointsWrap) { 5553 elPointsWrap.add(point); 5554 } 5555 } else { 5556 // dynamic array creation - multidimensional 5557 if (typeof w.globals.pointsArray[seriesIndex] === 'undefined') w.globals.pointsArray[seriesIndex] = []; 5558 w.globals.pointsArray[seriesIndex].push([p.x[q], p.y[q]]); 5559 } 5560 }; 5561 5562 for (var q = 0; q < p.x.length; q++) { 5563 _loop(q); 5564 } 5565 } 5566 5567 return elPointsWrap; 5568 } 5569 }, { 5570 key: "getMarkerConfig", 5571 value: function getMarkerConfig(cssClass, seriesIndex) { 5572 var w = this.w; 5573 var pStyle = this.getMarkerStyle(seriesIndex); 5574 var pSize = w.globals.markers.size[seriesIndex]; 5575 return { 5576 pSize: pSize, 5577 pRadius: w.config.markers.radius, 5578 pWidth: w.config.markers.strokeWidth, 5579 pointStrokeColor: pStyle.pointStrokeColor, 5580 pointFillColor: pStyle.pointFillColor, 5581 shape: w.config.markers.shape instanceof Array ? w.config.markers.shape[seriesIndex] : w.config.markers.shape, 5582 class: cssClass, 5583 pointStrokeOpacity: w.config.markers.strokeOpacity, 5584 pointFillOpacity: w.config.markers.fillOpacity, 5585 seriesIndex: seriesIndex 5586 }; 5587 } 5588 }, { 5589 key: "addEvents", 5590 value: function addEvents(circle) { 5591 var graphics = new Graphics(this.ctx);
5592 circle.node.addEventListener('mouseenter', graphics.pathMouseEnter.bind(this.ctx, circle)); 5593 circle.node.addEventListener('mouseleave', graphics.pathMouseLeave.bind(this.ctx, circle)); 5594 circle.node.addEventListener('mousedown', graphics.pathMouseDown.bind(this.ctx, circle)); 5595 circle.node.addEventListener('touchstart', graphics.pathMouseDown.bind(this.ctx, circle), { 5596 passive: true 5597 }); 5598 } 5599 }, { 5600 key: "getMarkerStyle", 5601 value: function getMarkerStyle(seriesIndex) { 5602 var w = this.w; 5603 var colors = w.globals.markers.colors; 5604 var strokeColors = w.config.markers.strokeColor || w.config.markers.strokeColors; 5605 var pointStrokeColor = strokeColors instanceof Array ? strokeColors[seriesIndex] : strokeColors; 5606 var pointFillColor = colors instanceof Array ? colors[seriesIndex] : colors; 5607 return { 5608 pointStrokeColor: pointStrokeColor, 5609 pointFillColor: pointFillColor 5610 }; 5611 } 5612 }]); 5613 5614 return Markers; 5615 }(); 5616 5617 /** 5618 * ApexCharts Scatter Class. 5619 * This Class also handles bubbles chart as currently there is no major difference in drawing them, 5620 * @module Scatter 5621 **/ 5622 5623 var Scatter = 5624 /*#__PURE__*/ 5625 function () { 5626 function Scatter(ctx) { 5627 _classCallCheck(this, Scatter); 5628 5629 this.ctx = ctx; 5630 this.w = ctx.w; 5631 this.initialAnim = this.w.config.chart.animations.enabled; 5632 this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled; // this array will help in centering the label in bubbles 5633 5634 this.radiusSizes = []; 5635 } 5636 5637 _createClass(Scatter, [{ 5638 key: "draw", 5639 value: function draw(elSeries, j, opts) { 5640 var w = this.w; 5641 var graphics = new Graphics(this.ctx); 5642 var realIndex = opts.realIndex; 5643 var pointsPos = opts.pointsPos; 5644 var zRatio = opts.zRatio; 5645 var elPointsMain = opts.elParent; 5646 var elPointsWrap = graphics.group({ 5647 class: "apexcharts-series-markers apexcharts-series-".concat(w.config.chart.type) 5648 }); 5649 elPointsWrap.attr('clip-path', "url(#gridRectMarkerMask".concat(w.globals.cuid, ")")); 5650 5651 if (pointsPos.x instanceof Array) { 5652 for (var q = 0; q < pointsPos.x.length; q++) { 5653 var dataPointIndex = j + 1; 5654 var shouldDraw = true; // a small hack as we have 2 points for the first val to connect it 5655 5656 if (j === 0 && q === 0) dataPointIndex = 0; 5657 if (j === 0 && q === 1) dataPointIndex = 1; 5658 var radius = 0; 5659 var finishRadius = w.globals.markers.size[realIndex]; 5660 5661 if (zRatio !== Infinity) { 5662 // means we have a bubble 5663 finishRadius = w.globals.seriesZ[realIndex][dataPointIndex] / zRatio; 5664 5665 if (typeof this.radiusSizes[realIndex] === 'undefined') { 5666 this.radiusSizes.push([]); 5667 } 5668 5669 this.radiusSizes[realIndex].push(finishRadius); 5670 } 5671 5672 if (!w.config.chart.animations.enabled) { 5673 radius = finishRadius; 5674 } 5675 5676 var x = pointsPos.x[q]; 5677 var y = pointsPos.y[q]; 5678 radius = radius || 0; 5679 5680 if (x === 0 && y === 0 || y === null || typeof w.globals.series[realIndex][dataPointIndex] === 'undefined') { 5681 shouldDraw = false; 5682 } 5683 5684 if (shouldDraw) { 5685 var circle = this.drawPoint(x, y, radius, finishRadius, realIndex, dataPointIndex, j); 5686 elPointsWrap.add(circle); 5687 } 5688 5689 elPointsMain.add(elPointsWrap); 5690 } 5691 } 5692 } 5693 }, { 5694 key: "drawPoint", 5695 value: function drawPoint(x, y, radius, finishRadius, realIndex, dataPointIndex, j) { 5696 var w = this.w; 5697 var i = realIndex; 5698 var anim = new Animations(this.ctx); 5699 var filters = new Filters(this.ctx); 5700 var fill = new Fill(this.ctx); 5701 var markers = new Markers(this.ctx); 5702 var graphics = new Graphics(this.ctx); 5703 var markerConfig = markers.getMarkerConfig('apexcharts-marker', i); 5704 var pathFillCircle = fill.fillPath({ 5705 seriesNumber: realIndex, 5706 patternUnits: 'objectBoundingBox', 5707 value: w.globals.series[realIndex][j] 5708 }); 5709 var circle = graphics.drawCircle(radius); 5710 5711 if (w.config.series[i].data[dataPointIndex]) { 5712 if (w.config.series[i].data[dataPointIndex].fillColor) { 5713 pathFillCircle = w.config.series[i].data[dataPointIndex].fillColor; 5714 } 5715 } 5716 5717 circle.attr({ 5718 cx: x, 5719 cy: y, 5720 fill: pathFillCircle, 5721 stroke: markerConfig.pointStrokeColor, 5722 strokeWidth: markerConfig.pWidth 5723 }); 5724 5725 if (w.config.chart.dropShadow.enabled) { 5726 var dropShadow = w.config.chart.dropShadow; 5727 filters.dropShadow(circle, dropShadow, realIndex); 5728 } 5729 5730 if (this.initialAnim && !w.globals.dataChanged) { 5731 var speed = 1; 5732 5733 if (!w.globals.resized) { 5734 speed = w.config.chart.animations.speed; 5735 } 5736 5737 anim.animateCircleRadius(circle, 0, finishRadius, speed, w.globals.easing); 5738 } 5739 5740 if (w.globals.dataChanged) { 5741 if (this.dynamicAnim) { 5742 var _speed = w.config.chart.animations.dynamicAnimation.speed; 5743 var prevX, prevY, prevR; 5744 var prevPathJ = null; 5745 prevPathJ = w.globals.previousPaths[realIndex] && w.globals.previousPaths[realIndex][j]; 5746 5747 if (typeof prevPathJ !== 'undefined' && prevPathJ !== null) { 5748 // series containing less elements will ignore these values and revert to 0 5749 prevX = prevPathJ.x; 5750 prevY = prevPathJ.y; 5751 prevR = typeof prevPathJ.r !== 'undefined' ? prevPathJ.r : finishRadius; 5752 } 5753 5754 for (var cs = 0; cs < w.globals.collapsedSeries.length; cs++) { 5755 if (w.globals.collapsedSeries[cs].index === realIndex) { 5756 _speed = 1; 5757 finishRadius = 0; 5758 } 5759 } 5760 5761 if (x === 0 && y === 0) finishRadius = 0; 5762 anim.animateCircle(circle, { 5763 cx: prevX, 5764 cy: prevY, 5765 r: prevR 5766 }, { 5767 cx: x, 5768 cy: y, 5769 r: finishRadius 5770 }, _speed, w.globals.easing); 5771 } else { 5772 circle.attr({ 5773 r: finishRadius 5774 }); 5775 } 5776 } 5777 5778 circle.attr({ 5779 rel: dataPointIndex, 5780 j: dataPointIndex, 5781 index: realIndex, 5782 'default-marker-size': finishRadius 5783 }); 5784 filters.setSelectionFilter(circle, realIndex, dataPointIndex); 5785 markers.addEvents(circle);
5786 circle.node.classList.add('apexcharts-marker'); 5787 return circle; 5788 } 5789 }, { 5790 key: "centerTextInBubble", 5791 value: function centerTextInBubble(y) { 5792 var w = this.w; 5793 y = y + parseInt(w.config.dataLabels.style.fontSize) / 4; 5794 return { 5795 y: y 5796 }; 5797 } 5798 }]); 5799 5800 return Scatter; 5801 }(); 5802 5803 /** 5804 * ApexCharts DataLabels Class for drawing dataLabels on Axes based Charts. 5805 * 5806 * @module DataLabels 5807 **/ 5808 5809 var DataLabels = 5810 /*#__PURE__*/ 5811 function () { 5812 function DataLabels(ctx) { 5813 _classCallCheck(this, DataLabels); 5814 5815 this.ctx = ctx; 5816 this.w = ctx.w; 5817 } // When there are many datalabels to be printed, and some of them overlaps each other in the same series, this method will take care of that 5818 // Also, when datalabels exceeds the drawable area and get clipped off, we need to adjust and move some pixels to make them visible again 5819 5820 5821 _createClass(DataLabels, [{ 5822 key: "dataLabelsCorrection", 5823 value: function dataLabelsCorrection(x, y, val, i, dataPointIndex, alwaysDrawDataLabel, fontSize) { 5824 var w = this.w; 5825 var graphics = new Graphics(this.ctx); 5826 var drawnextLabel = false; // 5827 5828 var textRects = graphics.getTextRects(val, fontSize); 5829 var width = textRects.width; 5830 var height = textRects.height; // first value in series, so push an empty array 5831 5832 if (typeof w.globals.dataLabelsRects[i] === 'undefined') w.globals.dataLabelsRects[i] = []; // then start pushing actual rects in that sub-array 5833 5834 w.globals.dataLabelsRects[i].push({ 5835 x: x, 5836 y: y, 5837 width: width, 5838 height: height 5839 }); 5840 var len = w.globals.dataLabelsRects[i].length - 2; 5841 var lastDrawnIndex = typeof w.globals.lastDrawnDataLabelsIndexes[i] !== 'undefined' ? w.globals.lastDrawnDataLabelsIndexes[i][w.globals.lastDrawnDataLabelsIndexes[i].length - 1] : 0; 5842 5843 if (typeof w.globals.dataLabelsRects[i][len] !== 'undefined') { 5844 var lastDataLabelRect = w.globals.dataLabelsRects[i][lastDrawnIndex]; 5845 5846 if ( // next label forward and x not intersecting 5847 x > lastDataLabelRect.x + lastDataLabelRect.width + 2 || y > lastDataLabelRect.y + lastDataLabelRect.height + 2 || x + width < lastDataLabelRect.x // next label is going to be drawn backwards 5848 ) { 5849 // the 2 indexes don't override, so OK to draw next label 5850 drawnextLabel = true; 5851 } 5852 } 5853 5854 if (dataPointIndex === 0 || alwaysDrawDataLabel) { 5855 drawnextLabel = true; 5856 } 5857 5858 return { 5859 x: x, 5860 y: y, 5861 drawnextLabel: drawnextLabel 5862 }; 5863 } 5864 }, { 5865 key: "drawDataLabel", 5866 value: function drawDataLabel(pos, i, j) { 5867 var align = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'top'; 5868 // this method handles line, area, bubble, scatter charts as those charts contains markers/points which have pre-defined x/y positions 5869 // all other charts like bars / heatmaps will define their own drawDataLabel routine 5870 var w = this.w; 5871 var graphics = new Graphics(this.ctx); 5872 var dataLabelsConfig = w.config.dataLabels; 5873 var x = 0; 5874 var y = 0; 5875 var dataPointIndex = j; 5876 var elDataLabelsWrap = null; 5877 5878 if (!dataLabelsConfig.enabled || pos.x instanceof Array !== true) { 5879 return elDataLabelsWrap; 5880 } 5881 5882 elDataLabelsWrap = graphics.group({ 5883 class: 'apexcharts-data-labels' 5884 }); 5885 elDataLabelsWrap.attr('clip-path', "url(#gridRectMarkerMask".concat(w.globals.cuid, ")")); 5886 5887 for (var q = 0; q < pos.x.length; q++) { 5888 x = pos.x[q] + dataLabelsConfig.offsetX; 5889 y = pos.y[q] + dataLabelsConfig.offsetY - w.globals.markers.size[i] - 5; 5890 5891 if (align === 'bottom') { 5892 y = y + w.globals.markers.size[i] * 2 + parseInt(dataLabelsConfig.style.fontSize) * 1.4; 5893 } 5894 5895 if (!isNaN(x)) { 5896 // a small hack as we have 2 points for the first val to connect it 5897 if (j === 1 && q === 0) dataPointIndex = 0; 5898 if (j === 1 && q === 1) dataPointIndex = 1; 5899 var val = w.globals.series[i][dataPointIndex]; 5900 var text = ''; 5901 5902 if (w.config.chart.type === 'bubble') { 5903 text = w.globals.seriesZ[i][dataPointIndex]; 5904 y = pos.y[q] + w.config.dataLabels.offsetY; 5905 var scatter = new Scatter(this.ctx); 5906 var centerTextInBubbleCoords = scatter.centerTextInBubble(y, i, dataPointIndex); 5907 y = centerTextInBubbleCoords.y; 5908 } else { 5909 if (typeof val !== 'undefined' && val !== null) { 5910 text = w.config.dataLabels.formatter(val, { 5911 ctx: this.ctx, 5912 seriesIndex: i, 5913 dataPointIndex: dataPointIndex, 5914 w: w 5915 }); 5916 } 5917 } 5918 5919 this.plotDataLabelsText({ 5920 x: x, 5921 y: y, 5922 text: text, 5923 i: i, 5924 j: dataPointIndex, 5925 parent: elDataLabelsWrap, 5926 offsetCorrection: true, 5927 dataLabelsConfig: w.config.dataLabels 5928 }); 5929 } 5930 } 5931 5932 return elDataLabelsWrap; 5933 } 5934 }, { 5935 key: "plotDataLabelsText", 5936 value: function plotDataLabelsText(opts) { 5937 var w = this.w; 5938 var graphics = new Graphics(this.ctx); 5939 var x = opts.x, 5940 y = opts.y, 5941 i = opts.i, 5942 j = opts.j, 5943 text = opts.text, 5944 textAnchor = opts.textAnchor, 5945 parent = opts.parent, 5946 dataLabelsConfig = opts.dataLabelsConfig, 5947 alwaysDrawDataLabel = opts.alwaysDrawDataLabel, 5948 offsetCorrection = opts.offsetCorrection; 5949 5950 if (Array.isArray(w.config.dataLabels.enabledOnSeries)) { 5951 if (w.config.dataLabels.enabledOnSeries.indexOf(i) > -1) { 5952 return; 5953 } 5954 } 5955 5956 var correctedLabels = { 5957 x: x, 5958 y: y, 5959 drawnextLabel: true 5960 }; 5961 5962 if (offsetCorrection) { 5963 correctedLabels = this.dataLabelsCorrection(x, y, text, i, j, alwaysDrawDataLabel, parseInt(dataLabelsConfig.style.fontSize)); 5964 } // when zoomed, we don't need to correct labels offsets, 5965 // but if normally, labels get cropped, correct them 5966 5967 5968 if (!w.globals.zoomed) { 5969 x = correctedLabels.x; 5970 y = correctedLabels.y; 5971 } 5972 5973 if (correctedLabels.drawnextLabel) { 5974 var dataLabelText = graphics.drawText({ 5975 width: 100, 5976 height: parseInt(dataLabelsConfig.style.fontSize), 5977 x: x, 5978 y: y, 5979 foreColor: w.globals.dataLabels.style.colors[i], 5980 textAnchor: textAnchor || dataLabelsConfig.textAnchor, 5981 text: text, 5982 fontSize: dataLabelsConfig.style.fontSize, 5983 fontFamily: dataLabelsConfig.style.fontFamily 5984 }); 5985 dataLabelText.attr({ 5986 class: 'apexcharts-datalabel', 5987 cx: x, 5988 cy: y 5989 }); 5990 5991 if (dataLabelsConfig.dropShadow.enabled) { 5992 var textShadow = dataLabelsConfig.dropShadow; 5993 var filters = new Filters(this.ctx); 5994 filters.dropShadow(dataLabelText, textShadow); 5995 } 5996 5997 parent.add(dataLabelText); 5998 5999 if (typeof w.globals.lastDrawnDataLabelsIndexes[i] === 'undefined') { 6000 w.globals.lastDrawnDataLabelsIndexes[i] = []; 6001 } 6002 6003 w.globals.lastDrawnDataLabelsIndexes[i].push(j); 6004 } 6005 } 6006 }]); 6007 6008 return DataLabels; 6009 }(); 6010 6011 /** 6012 * ApexCharts Bar Class responsible for drawing both Columns and Bars. 6013 * 6014 * @module Bar 6015 **/ 6016 6017 var Bar = 6018 /*#__PURE__*/ 6019 function () { 6020 function Bar(ctx, xyRatios) { 6021 _classCallCheck(this, Bar); 6022 6023 this.ctx = ctx; 6024 this.w = ctx.w; 6025 var w = this.w; 6026 this.barOptions = w.config.plotOptions.bar; 6027 this.isHorizontal = this.barOptions.horizontal; 6028 this.strokeWidth = w.config.stroke.width; 6029 this.isNullValue = false; 6030 this.xyRatios = xyRatios; 6031 6032 if (this.xyRatios !== null) { 6033 this.xRatio = xyRatios.xRatio; 6034 this.yRatio = xyRatios.yRatio; 6035 this.invertedXRatio = xyRatios.invertedXRatio; 6036 this.invertedYRatio = xyRatios.invertedYRatio; 6037 this.baseLineY = xyRatios.baseLineY; 6038 this.baseLineInvertedY = xyRatios.baseLineInvertedY; 6039 } 6040 6041 this.yaxisIndex = 0; 6042 this.seriesLen = 0; 6043 } 6044 /** primary draw method which is called on bar object 6045 * @memberof Bar 6046 * @param {array} series - user supplied series values 6047 * @param {int} seriesIndex - the index by which series will be drawn on the svg 6048 * @return {node} element which is supplied to parent chart draw method for appending 6049 **/ 6050 6051 6052 _createClass(Bar, [{ 6053 key: "draw", 6054 value: function draw(series, seriesIndex) { 6055 var w = this.w; 6056 var graphics = new Graphics(this.ctx); 6057 var coreUtils = new CoreUtils(this.ctx, w);
6058 series = coreUtils.getLogSeries(series); 6059 this.series = series; 6060 this.yRatio = coreUtils.getLogYRatios(this.yRatio); 6061 this.initVariables(series); 6062 var ret = graphics.group({ 6063 class: 'apexcharts-bar-series apexcharts-plot-series' 6064 }); 6065 6066 if (w.config.dataLabels.enabled) { 6067 if (this.totalItems > w.config.plotOptions.bar.dataLabels.maxItems) { 6068 console.warn('WARNING: DataLabels are enabled but there are too many to display. This may cause performance issue when rendering.'); 6069 } 6070 } 6071 6072 for (var i = 0, bc = 0; i < series.length; i++, bc++) { 6073 var pathTo = void 0, 6074 pathFrom = void 0; 6075 var x = void 0, 6076 y = void 0, 6077 xDivision = void 0, 6078 // xDivision is the GRIDWIDTH divided by number of datapoints (columns) 6079 yDivision = void 0, 6080 // yDivision is the GRIDHEIGHT divided by number of datapoints (bars) 6081 zeroH = void 0, 6082 // zeroH is the baseline where 0 meets y axis 6083 zeroW = void 0; // zeroW is the baseline where 0 meets x axis 6084 6085 var yArrj = []; // hold y values of current iterating series 6086 6087 var xArrj = []; // hold x values of current iterating series 6088 6089 var realIndex = w.globals.comboCharts ? seriesIndex[i] : i; // el to which series will be drawn 6090 6091 var elSeries = graphics.group({ 6092 class: "apexcharts-series", 6093 rel: i + 1, 6094 seriesName: Utils.escapeString(w.globals.seriesNames[realIndex]), 6095 'data:realIndex': realIndex 6096 }); 6097 this.ctx.series.addCollapsedClassToSeries(elSeries, realIndex); 6098 6099 if (series[i].length > 0) { 6100 this.visibleI = this.visibleI + 1; 6101 } 6102 6103 var strokeWidth = 0; 6104 var barHeight = 0; 6105 var barWidth = 0; 6106 6107 if (this.yRatio.length > 1) { 6108 this.yaxisIndex = realIndex; 6109 } 6110 6111 this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed; 6112 var initPositions = this.initialPositions(); 6113 y = initPositions.y; 6114 barHeight = initPositions.barHeight; 6115 yDivision = initPositions.yDivision; 6116 zeroW = initPositions.zeroW; 6117 x = initPositions.x; 6118 barWidth = initPositions.barWidth; 6119 xDivision = initPositions.xDivision; 6120 zeroH = initPositions.zeroH; 6121 6122 if (!this.horizontal) { 6123 xArrj.push(x + barWidth / 2); 6124 } // eldatalabels 6125 6126 6127 var elDataLabelsWrap = graphics.group({ 6128 class: 'apexcharts-datalabels' 6129 }); 6130 6131 for (var j = 0, tj = w.globals.dataPoints; j < w.globals.dataPoints; j++, tj--) { 6132 if (typeof this.series[i][j] === 'undefined' || series[i][j] === null) { 6133 this.isNullValue = true; 6134 } else { 6135 this.isNullValue = false; 6136 } 6137 6138 if (w.config.stroke.show) { 6139 if (this.isNullValue) { 6140 strokeWidth = 0; 6141 } else { 6142 strokeWidth = Array.isArray(this.strokeWidth) ? this.strokeWidth[realIndex] : this.strokeWidth; 6143 } 6144 } 6145 6146 var paths = null; 6147 6148 if (this.isHorizontal) { 6149 paths = this.drawBarPaths({ 6150 indexes: { 6151 i: i, 6152 j: j, 6153 realIndex: realIndex, 6154 bc: bc 6155 }, 6156 barHeight: barHeight, 6157 strokeWidth: strokeWidth, 6158 pathTo: pathTo, 6159 pathFrom: pathFrom, 6160 zeroW: zeroW, 6161 x: x, 6162 y: y, 6163 yDivision: yDivision, 6164 elSeries: elSeries 6165 }); 6166 barWidth = this.series[i][j] / this.invertedYRatio; 6167 } else { 6168 paths = this.drawColumnPaths({ 6169 indexes: { 6170 i: i, 6171 j: j, 6172 realIndex: realIndex, 6173 bc: bc 6174 }, 6175 x: x, 6176 y: y, 6177 xDivision: xDivision, 6178 pathTo: pathTo, 6179 pathFrom: pathFrom, 6180 barWidth: barWidth, 6181 zeroH: zeroH, 6182 strokeWidth: strokeWidth, 6183 elSeries: elSeries 6184 }); 6185 barHeight = this.series[i][j] / this.yRatio[this.yaxisIndex]; 6186 } 6187 6188 pathTo = paths.pathTo; 6189 pathFrom = paths.pathFrom; 6190 y = paths.y; 6191 x = paths.x; // push current X 6192 6193 if (j > 0) { 6194 xArrj.push(x + barWidth / 2); 6195 } 6196 6197 yArrj.push(y);
6198 var pathFill = this.getPathFillColor(series, i, j, realIndex); 6199 elSeries = this.renderSeries({ 6200 realIndex: realIndex, 6201 pathFill: pathFill, 6202 j: j, 6203 i: i, 6204 pathFrom: pathFrom, 6205 pathTo: pathTo, 6206 strokeWidth: strokeWidth, 6207 elSeries: elSeries, 6208 x: x, 6209 y: y, 6210 series: series, 6211 barHeight: barHeight, 6212 barWidth: barWidth, 6213 elDataLabelsWrap: elDataLabelsWrap, 6214 visibleSeries: this.visibleI, 6215 type: 'bar' 6216 }); 6217 } // push all x val arrays into main xArr 6218 6219 6220 w.globals.seriesXvalues[realIndex] = xArrj; 6221 w.globals.seriesYvalues[realIndex] = yArrj; 6222 ret.add(elSeries); 6223 } 6224 6225 return ret; 6226 } 6227 }, { 6228 key: "getPathFillColor", 6229 value: function getPathFillColor(series, i, j, realIndex) { 6230 var w = this.w; 6231 var fill = new Fill(this.ctx); 6232 var fillColor = null; 6233 var seriesNumber = this.barOptions.distributed ? j : i; 6234 6235 if (this.barOptions.colors.ranges.length > 0) { 6236 var colorRange = this.barOptions.colors.ranges; 6237 colorRange.map(function (range) { 6238 if (series[i][j] >= range.from && series[i][j] <= range.to) { 6239 fillColor = range.color; 6240 } 6241 }); 6242 } 6243 6244 if (w.config.series[i].data[j] && w.config.series[i].data[j].fillColor) { 6245 fillColor = w.config.series[i].data[j].fillColor; 6246 } 6247 6248 var pathFill = fill.fillPath({ 6249 seriesNumber: this.barOptions.distributed ? seriesNumber : realIndex, 6250 color: fillColor, 6251 value: series[i][j] 6252 }); 6253 return pathFill; 6254 } 6255 }, { 6256 key: "renderSeries",
6257 value: function renderSeries(_ref) { 6258 var realIndex = _ref.realIndex, 6259 pathFill = _ref.pathFill, 6260 lineFill = _ref.lineFill, 6261 j = _ref.j, 6262 i = _ref.i, 6263 pathFrom = _ref.pathFrom, 6264 pathTo = _ref.pathTo, 6265 strokeWidth = _ref.strokeWidth, 6266 elSeries = _ref.elSeries, 6267 x = _ref.x, 6268 y = _ref.y, 6269 series = _ref.series, 6270 barHeight = _ref.barHeight, 6271 barWidth = _ref.barWidth, 6272 elDataLabelsWrap = _ref.elDataLabelsWrap, 6273 visibleSeries = _ref.visibleSeries, 6274 type = _ref.type; 6275 var w = this.w; 6276 var graphics = new Graphics(this.ctx); 6277 6278 if (!lineFill) { 6279 /* fix apexcharts#341 */ 6280 lineFill = this.barOptions.distributed ? w.globals.stroke.colors[j] : w.globals.stroke.colors[realIndex]; 6281 } 6282 6283 if (w.config.series[i].data[j] && w.config.series[i].data[j].strokeColor) { 6284 lineFill = w.config.series[i].data[j].strokeColor; 6285 } 6286 6287 if (this.isNullValue) { 6288 pathFill = 'none'; 6289 } 6290 6291 var delay = j / w.config.chart.animations.animateGradually.delay * (w.config.chart.animations.speed / w.globals.dataPoints) / 2.4; 6292 var renderedPath = graphics.renderPaths({ 6293 i: i, 6294 j: j, 6295 realIndex: realIndex, 6296 pathFrom: pathFrom, 6297 pathTo: pathTo, 6298 stroke: lineFill, 6299 strokeWidth: strokeWidth, 6300 strokeLineCap: w.config.stroke.lineCap, 6301 fill: pathFill, 6302 animationDelay: delay, 6303 initialSpeed: w.config.chart.animations.speed, 6304 dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed, 6305 className: "apexcharts-".concat(type, "-area"), 6306 id: "apexcharts-".concat(type, "-area") 6307 }); 6308 renderedPath.attr('clip-path', "url(#gridRectMask".concat(w.globals.cuid, ")")); 6309 var filters = new Filters(this.ctx); 6310 filters.setSelectionFilter(renderedPath, realIndex, j); 6311 elSeries.add(renderedPath); 6312 var dataLabels = this.calculateDataLabelsPos({ 6313 x: x, 6314 y: y, 6315 i: i, 6316 j: j, 6317 series: series, 6318 realIndex: realIndex, 6319 barHeight: barHeight, 6320 barWidth: barWidth, 6321 renderedPath: renderedPath, 6322 visibleSeries: visibleSeries 6323 }); 6324 6325 if (dataLabels !== null) { 6326 elDataLabelsWrap.add(dataLabels); 6327 } 6328 6329 elSeries.add(elDataLabelsWrap); 6330 return elSeries; 6331 } 6332 }, { 6333 key: "initVariables", 6334 value: function initVariables(series) { 6335 var w = this.w; 6336 this.series = series; 6337 this.totalItems = 0; 6338 this.seriesLen = 0; 6339 this.visibleI = -1; 6340 this.visibleItems = 1; // number of visible bars after user zoomed in/out 6341 6342 for (var sl = 0; sl < series.length; sl++) { 6343 if (series[sl].length > 0) { 6344 this.seriesLen = this.seriesLen + 1; 6345 this.totalItems += series[sl].length; 6346 } 6347 6348 if (w.globals.isXNumeric) { 6349 // get max visible items 6350 for (var j = 0; j < series[sl].length; j++) { 6351 if (w.globals.seriesX[sl][j] > w.globals.minX && w.globals.seriesX[sl][j] < w.globals.maxX) { 6352 this.visibleItems++; 6353 } 6354 } 6355 } else { 6356 this.visibleItems = w.globals.dataPoints; 6357 } 6358 } 6359 6360 if (this.seriesLen === 0) { 6361 // A small adjustment when combo charts are used 6362 this.seriesLen = 1; 6363 } 6364 } 6365 }, { 6366 key: "initialPositions", 6367 value: function initialPositions() { 6368 var w = this.w; 6369 var x, y, yDivision, xDivision, barHeight, barWidth, zeroH, zeroW; 6370 6371 if (this.isHorizontal) { 6372 // height divided into equal parts 6373 yDivision = w.globals.gridHeight / w.globals.dataPoints; 6374 barHeight = yDivision / this.seriesLen; 6375 6376 if (w.globals.isXNumeric) { 6377 yDivision = w.globals.gridHeight / this.totalItems; 6378 barHeight = yDivision / this.seriesLen; 6379 } 6380 6381 barHeight = barHeight * parseInt(this.barOptions.barHeight) / 100; 6382 zeroW = this.baseLineInvertedY + w.globals.padHorizontal + (this.isReversed ? w.globals.gridWidth : 0) - (this.isReversed ? this.baseLineInvertedY * 2 : 0);
6383 y = (yDivision - barHeight * this.seriesLen) / 2; 6384 } else { 6385 // width divided into equal parts 6386 xDivision = w.globals.gridWidth / this.visibleItems; 6387 barWidth = xDivision / this.seriesLen * parseInt(this.barOptions.columnWidth) / 100; 6388 6389 if (w.globals.isXNumeric) { 6390 // max barwidth should be equal to minXDiff to avoid overlap 6391 xDivision = w.globals.minXDiff / this.xRatio; 6392 barWidth = xDivision / this.seriesLen * parseInt(this.barOptions.columnWidth) / 100; 6393 } 6394 6395 zeroH = w.globals.gridHeight - this.baseLineY[this.yaxisIndex] - (this.isReversed ? w.globals.gridHeight : 0) + (this.isReversed ? this.baseLineY[this.yaxisIndex] * 2 : 0); 6396 x = w.globals.padHorizontal + (xDivision - barWidth * this.seriesLen) / 2; 6397 } 6398 6399 return { 6400 x: x, 6401 y: y, 6402 yDivision: yDivision, 6403 xDivision: xDivision, 6404 barHeight: barHeight, 6405 barWidth: barWidth, 6406 zeroH: zeroH, 6407 zeroW: zeroW 6408 }; 6409 } 6410 }, { 6411 key: "drawBarPaths", 6412 value: function drawBarPaths(_ref2) { 6413 var indexes = _ref2.indexes, 6414 barHeight = _ref2.barHeight, 6415 strokeWidth = _ref2.strokeWidth, 6416 pathTo = _ref2.pathTo, 6417 pathFrom = _ref2.pathFrom, 6418 zeroW = _ref2.zeroW, 6419 x = _ref2.x, 6420 y = _ref2.y, 6421 yDivision = _ref2.yDivision, 6422 elSeries = _ref2.elSeries; 6423 var w = this.w; 6424 var graphics = new Graphics(this.ctx); 6425 var i = indexes.i; 6426 var j = indexes.j; 6427 var realIndex = indexes.realIndex; 6428 var bc = indexes.bc; 6429 6430 if (w.globals.isXNumeric) { 6431 y = (w.globals.seriesX[i][j] - w.globals.minX) / this.invertedXRatio - barHeight; 6432 } 6433 6434 var barYPosition = y + barHeight * this.visibleI; 6435 pathTo = graphics.move(zeroW, barYPosition); 6436 pathFrom = graphics.move(zeroW, barYPosition); 6437 6438 if (w.globals.previousPaths.length > 0) { 6439 pathFrom = this.getPathFrom(realIndex, j); 6440 } 6441 6442 if (typeof this.series[i][j] === 'undefined' || this.series[i][j] === null) { 6443 x = zeroW; 6444 } else { 6445 x = zeroW + this.series[i][j] / this.invertedYRatio - (this.isReversed ? this.series[i][j] / this.invertedYRatio : 0) * 2; 6446 } 6447 6448 var endingShapeOpts = { 6449 barHeight: barHeight, 6450 strokeWidth: strokeWidth, 6451 barYPosition: barYPosition, 6452 x: x, 6453 zeroW: zeroW 6454 }; 6455 var endingShape = this.barEndingShape(w, endingShapeOpts, this.series, i, j); 6456 pathTo = pathTo + graphics.line(endingShape.newX, barYPosition) + endingShape.path + graphics.line(zeroW, barYPosition + barHeight - strokeWidth) + graphics.line(zeroW, barYPosition); 6457 pathFrom = pathFrom + graphics.line(zeroW, barYPosition) + endingShape.ending_p_from + graphics.line(zeroW, barYPosition + barHeight - strokeWidth) + graphics.line(zeroW, barYPosition + barHeight - strokeWidth) + graphics.line(zeroW, barYPosition); 6458 6459 if (!w.globals.isXNumeric) { 6460 y = y + yDivision; 6461 } 6462 6463 if (this.barOptions.colors.backgroundBarColors.length > 0 && i === 0) { 6464 if (bc >= this.barOptions.colors.backgroundBarColors.length) { 6465 bc = 0; 6466 } 6467 6468 var bcolor = this.barOptions.colors.backgroundBarColors[bc]; 6469 var rect = graphics.drawRect(0, barYPosition - barHeight * this.visibleI, w.globals.gridWidth, barHeight * this.seriesLen, 0, bcolor, this.barOptions.colors.backgroundBarOpacity); 6470 elSeries.add(rect); 6471 rect.node.classList.add('apexcharts-backgroundBar'); 6472 } 6473 6474 return { 6475 pathTo: pathTo, 6476 pathFrom: pathFrom, 6477 x: x, 6478 y: y, 6479 barYPosition: barYPosition 6480 }; 6481 } 6482 }, { 6483 key: "drawColumnPaths", 6484 value: function drawColumnPaths(_ref3) { 6485 var indexes = _ref3.indexes, 6486 x = _ref3.x, 6487 y = _ref3.y, 6488 xDivision = _ref3.xDivision, 6489 pathTo = _ref3.pathTo, 6490 pathFrom = _ref3.pathFrom, 6491 barWidth = _ref3.barWidth, 6492 zeroH = _ref3.zeroH, 6493 strokeWidth = _ref3.strokeWidth, 6494 elSeries = _ref3.elSeries; 6495 var w = this.w; 6496 var graphics = new Graphics(this.ctx); 6497 var i = indexes.i; 6498 var j = indexes.j; 6499 var realIndex = indexes.realIndex; 6500 var bc = indexes.bc; 6501 6502 if (w.globals.isXNumeric) { 6503 x = (w.globals.seriesX[i][j] - w.globals.minX) / this.xRatio - barWidth / 2; 6504 } 6505 6506 var barXPosition = x + barWidth * this.visibleI; 6507 pathTo = graphics.move(barXPosition, zeroH); 6508 pathFrom = graphics.move(barXPosition, zeroH); 6509 6510 if (w.globals.previousPaths.length > 0) { 6511 pathFrom = this.getPathFrom(realIndex, j); 6512 } 6513 6514 if (typeof this.series[i][j] === 'undefined' || this.series[i][j] === null) { 6515 y = zeroH; 6516 } else { 6517 y = zeroH - this.series[i][j] / this.yRatio[this.yaxisIndex] + (this.isReversed ? this.series[i][j] / this.yRatio[this.yaxisIndex] : 0) * 2; 6518 } 6519 6520 var endingShapeOpts = { 6521 barWidth: barWidth, 6522 strokeWidth: strokeWidth, 6523 barXPosition: barXPosition, 6524 y: y, 6525 zeroH: zeroH 6526 }; 6527 var endingShape = this.barEndingShape(w, endingShapeOpts, this.series, i, j); 6528 pathTo = pathTo + graphics.line(barXPosition, endingShape.newY) + endingShape.path + graphics.line(barXPosition + barWidth - strokeWidth, zeroH) + graphics.line(barXPosition - strokeWidth / 2, zeroH); 6529 pathFrom = pathFrom + graphics.line(barXPosition, zeroH) + endingShape.ending_p_from + graphics.line(barXPosition + barWidth - strokeWidth, zeroH) + graphics.line(barXPosition + barWidth - strokeWidth, zeroH) + graphics.line(barXPosition - strokeWidth / 2, zeroH); 6530 6531 if (!w.globals.isXNumeric) { 6532 x = x + xDivision; 6533 } 6534 6535 if (this.barOptions.colors.backgroundBarColors.length > 0 && i === 0) { 6536 if (bc >= this.barOptions.colors.backgroundBarColors.length) { 6537 bc = 0; 6538 } 6539 6540 var bcolor = this.barOptions.colors.backgroundBarColors[bc]; 6541 var rect = graphics.drawRect(barXPosition - barWidth * this.visibleI, 0, barWidth * this.seriesLen, w.globals.gridHeight, 0, bcolor, this.barOptions.colors.backgroundBarOpacity); 6542 elSeries.add(rect); 6543 rect.node.classList.add('apexcharts-backgroundBar'); 6544 } 6545 6546 return { 6547 pathTo: pathTo, 6548 pathFrom: pathFrom, 6549 x: x, 6550 y: y, 6551 barXPosition: barXPosition 6552 }; 6553 } 6554 /** getPathFrom is a common function for bars/columns which is used to get previous paths when data changes. 6555 * @memberof Bar 6556 * @param {int} realIndex - current iterating i 6557 * @param {int} j - current iterating series's j index 6558 * @return {string} pathFrom is the string which will be appended in animations 6559 **/ 6560 6561 }, { 6562 key: "getPathFrom", 6563 value: function getPathFrom(realIndex, j) { 6564 var w = this.w; 6565 var pathFrom; 6566 6567 for (var pp = 0; pp < w.globals.previousPaths.length; pp++) { 6568 var gpp = w.globals.previousPaths[pp]; 6569 6570 if (gpp.paths.length > 0 && parseInt(gpp.realIndex) === parseInt(realIndex)) { 6571 if (typeof w.globals.previousPaths[pp].paths[j] !== 'undefined') { 6572 pathFrom = w.globals.previousPaths[pp].paths[j].d; 6573 } 6574 } 6575 } 6576 6577 return pathFrom; 6578 } 6579 /** calculateBarDataLabels is used to calculate the positions for the data-labels 6580 * It also sets the element's data attr for bars and calls drawCalculatedBarDataLabels() 6581 * @memberof Bar 6582 * @param {object} {barProps}
6582 most of the bar properties used throughout the bar 6583 * drawing function 6584 * @return {object} dataLabels node-element which you can append later 6585 **/ 6586 6587 }, { 6588 key: "calculateDataLabelsPos", 6589 value: function calculateDataLabelsPos(_ref4) { 6590 var x = _ref4.x, 6591 y = _ref4.y, 6592 i = _ref4.i, 6593 j = _ref4.j, 6594 realIndex = _ref4.realIndex, 6595 series = _ref4.series, 6596 barHeight = _ref4.barHeight, 6597 barWidth = _ref4.barWidth, 6598 visibleSeries = _ref4.visibleSeries, 6599 renderedPath = _ref4.renderedPath; 6600 var w = this.w; 6601 var graphics = new Graphics(this.ctx); 6602 var strokeWidth = Array.isArray(this.strokeWidth) ? this.strokeWidth[realIndex] : this.strokeWidth; 6603 var bcx = x + parseFloat(barWidth * visibleSeries); 6604 var bcy = y + parseFloat(barHeight * visibleSeries); 6605 6606 if (w.globals.isXNumeric && !w.globals.isBarHorizontal) { 6607 bcx = x + parseFloat(barWidth * (visibleSeries + 1)) - strokeWidth; 6608 bcy = y + parseFloat(barHeight * (visibleSeries + 1)) - strokeWidth; 6609 } 6610 6611 var dataLabels = null; 6612 var dataLabelsX = x; 6613 var dataLabelsY = y; 6614 var dataLabelsPos = {}; 6615 var dataLabelsConfig = w.config.dataLabels; 6616 var barDataLabelsConfig = this.barOptions.dataLabels; 6617 var offX = dataLabelsConfig.offsetX; 6618 var offY = dataLabelsConfig.offsetY; 6619 var textRects = { 6620 width: 0, 6621 height: 0 6622 }; 6623 6624 if (w.config.dataLabels.enabled) { 6625 textRects = graphics.getTextRects(w.globals.yLabelFormatters[0](w.globals.maxY), parseInt(dataLabelsConfig.style.fontSize)); 6626 } 6627 6628 if (this.isHorizontal) { 6629 dataLabelsPos = this.calculateBarsDataLabelsPosition({ 6630 x: x, 6631 y: y, 6632 i: i, 6633 j: j, 6634 renderedPath: renderedPath, 6635 bcy: bcy, 6636 barHeight: barHeight, 6637 barWidth: barWidth, 6638 textRects: textRects, 6639 strokeWidth: strokeWidth, 6640 dataLabelsX: dataLabelsX, 6641 dataLabelsY: dataLabelsY, 6642 barDataLabelsConfig: barDataLabelsConfig, 6643 offX: offX, 6644 offY: offY 6645 }); 6646 } else { 6647 dataLabelsPos = this.calculateColumnsDataLabelsPosition({ 6648 x: x, 6649 y: y, 6650 i: i, 6651 j: j, 6652 renderedPath: renderedPath, 6653 realIndex: realIndex, 6654 bcx: bcx, 6655 bcy: bcy, 6656 barHeight: barHeight, 6657 barWidth: barWidth, 6658 textRects: textRects, 6659 strokeWidth: strokeWidth, 6660 dataLabelsY: dataLabelsY, 6661 barDataLabelsConfig: barDataLabelsConfig, 6662 offX: offX, 6663 offY: offY 6664 }); 6665 } 6666 6667 renderedPath.attr({ 6668 cy: dataLabelsPos.bcy, 6669 cx: dataLabelsPos.bcx, 6670 j: j, 6671 val: series[i][j], 6672 barHeight: barHeight, 6673 barWidth: barWidth 6674 }); 6675 dataLabels = this.drawCalculatedDataLabels({ 6676 x: dataLabelsPos.dataLabelsX, 6677 y: dataLabelsPos.dataLabelsY, 6678 val: series[i][j], 6679 i: realIndex, 6680 j: j, 6681 barWidth: barWidth, 6682 barHeight: barHeight, 6683 textRects: textRects, 6684 dataLabelsConfig: dataLabelsConfig 6685 }); 6686 return dataLabels; 6687 } 6688 }, { 6689 key: "calculateColumnsDataLabelsPosition", 6690 value: function calculateColumnsDataLabelsPosition(opts) { 6691 var w = this.w; 6692 var i = opts.i, 6693 j = opts.j, 6694 y = opts.y, 6695 bcx = opts.bcx, 6696 barWidth = opts.barWidth, 6697 barHeight = opts.barHeight, 6698 textRects = opts.textRects, 6699 dataLabelsY = opts.dataLabelsY, 6700 barDataLabelsConfig = opts.barDataLabelsConfig, 6701 strokeWidth = opts.strokeWidth, 6702 offX = opts.offX, 6703 offY = opts.offY; 6704 var dataLabelsX; 6705 var dataPointsDividedWidth = w.globals.gridWidth / w.globals.dataPoints; 6706 bcx = bcx - strokeWidth / 2; 6707 6708 if (w.globals.isXNumeric) {
6709 dataLabelsX = bcx - barWidth / 2 + offX; 6710 } else { 6711 dataLabelsX = bcx - dataPointsDividedWidth + barWidth / 2 + offX; 6712 } 6713 6714 var valIsNegative = this.series[i][j] <= 0; 6715 6716 if (this.isReversed) { 6717 y = y - barHeight; 6718 } 6719 6720 switch (barDataLabelsConfig.position) { 6721 case 'center': 6722 if (valIsNegative) { 6723 dataLabelsY = y + barHeight / 2 + textRects.height / 2 + offY; 6724 } else { 6725 dataLabelsY = y + barHeight / 2 + textRects.height / 2 - offY; 6726 } 6727 6728 break; 6729 6730 case 'bottom': 6731 if (valIsNegative) { 6732 dataLabelsY = y + barHeight + textRects.height + strokeWidth + offY; 6733 } else { 6734 dataLabelsY = y + barHeight - textRects.height / 2 + strokeWidth - offY; 6735 } 6736 6737 break; 6738 6739 case 'top': 6740 if (valIsNegative) { 6741 dataLabelsY = y - textRects.height / 2 - offY; 6742 } else { 6743 dataLabelsY = y + textRects.height + offY; 6744 } 6745 6746 break; 6747 } 6748 6749 if (!w.config.chart.stacked) { 6750 if (dataLabelsY < 0) { 6751 dataLabelsY = 0 + strokeWidth; 6752 } else if (dataLabelsY + textRects.height / 3 > w.globals.gridHeight) { 6753 dataLabelsY = w.globals.gridHeight - strokeWidth; 6754 } 6755 } 6756 6757 return { 6758 bcx: bcx, 6759 bcy: y, 6760 dataLabelsX: dataLabelsX, 6761 dataLabelsY: dataLabelsY 6762 }; 6763 } 6764 }, { 6765 key: "calculateBarsDataLabelsPosition", 6766 value: function calculateBarsDataLabelsPosition(opts) { 6767 var w = this.w; 6768 var x = opts.x, 6769 i = opts.i, 6770 j = opts.j, 6771 bcy = opts.bcy, 6772 barHeight = opts.barHeight, 6773 barWidth = opts.barWidth, 6774 textRects = opts.textRects, 6775 dataLabelsX = opts.dataLabelsX, 6776 strokeWidth = opts.strokeWidth, 6777 barDataLabelsConfig = opts.barDataLabelsConfig, 6778 offX = opts.offX, 6779 offY = opts.offY; 6780 var dataPointsDividedHeight = w.globals.gridHeight / w.globals.dataPoints; 6781 var dataLabelsY = bcy - dataPointsDividedHeight + barHeight / 2 + textRects.height / 2 + offY - 3; 6782 var valIsNegative = this.series[i][j] <= 0; 6783 6784 if (this.isReversed) { 6785 x = x + barWidth; 6786 } 6787 6788 switch (barDataLabelsConfig.position) { 6789 case 'center': 6790 if (valIsNegative) { 6791 dataLabelsX = x - barWidth / 2 - offX; 6792 } else { 6793 dataLabelsX = x - barWidth / 2 + offX; 6794 } 6795 6796 break; 6797 6798 case 'bottom': 6799 if (valIsNegative) { 6800 dataLabelsX = x - barWidth - strokeWidth - Math.round(textRects.width / 2) - offX; 6801 } else { 6802 dataLabelsX = x - barWidth + strokeWidth + Math.round(textRects.width / 2) + offX; 6803 } 6804 6805 break; 6806 6807 case 'top': 6808 if (valIsNegative) { 6809 dataLabelsX = x - strokeWidth + Math.round(textRects.width / 2) - offX; 6810 } else { 6811 dataLabelsX = x - strokeWidth - Math.round(textRects.width / 2) + offX; 6812 } 6813 6814 break; 6815 } 6816 6817 if (!w.config.chart.stacked) { 6818 if (dataLabelsX < 0) { 6819 dataLabelsX = dataLabelsX + textRects.width + strokeWidth; 6820 } else if (dataLabelsX + textRects.width / 2 > w.globals.gridWidth) { 6821 dataLabelsX = w.globals.gridWidth - textRects.width - strokeWidth; 6822 } 6823 } 6824 6825 return { 6826 bcx: x, 6827 bcy: bcy, 6828 dataLabelsX: dataLabelsX, 6829 dataLabelsY: dataLabelsY 6830 }; 6831 } 6832 }, { 6833 key: "drawCalculatedDataLabels", 6834 value: function drawCalculatedDataLabels(_ref5) { 6835 var x = _ref5.x, 6836 y = _ref5.y, 6837 val = _ref5.val, 6838 i = _ref5.i, 6839 j = _ref5.j, 6840 textRects = _ref5.textRects, 6841 barHeight = _ref5.barHeight, 6842 barWidth = _ref5.barWidth, 6843 dataLabelsConfig = _ref5.dataLabelsConfig; 6844 var w = this.w; 6845 var dataLabels = new DataLabels(this.ctx); 6846 var graphics = new Graphics(this.ctx); 6847 var formatter = dataLabelsConfig.formatter; 6848 var elDataLabelsWrap = null; 6849 var isSeriesNotCollapsed = w.globals.collapsedSeriesIndices.indexOf(i) > -1; 6850 6851 if (dataLabelsConfig.enabled && !isSeriesNotCollapsed) { 6852 elDataLabelsWrap = graphics.group({ 6853 class: 'apexcharts-data-labels' 6854 }); 6855 var text = ''; 6856 6857 if (typeof val !== 'undefined' && val !== null) { 6858 text = formatter(val, { 6859 seriesIndex: i, 6860 dataPointIndex: j, 6861 w: w 6862 }); 6863 } 6864 6865 if (val === 0 && w.config.chart.stacked) { 6866 // in a stacked bar/column chart, 0 value should be neglected as it will overlap on the next element 6867 text = ''; 6868 } 6869 6870 if (w.config.chart.stacked && this.barOptions.dataLabels.hideOverflowingLabels) { 6871 // if there is not enough space to draw the label in the bar/column rect, check hideOverflowingLabels property to prevent overflowing on wrong rect 6872 // Note: This issue is only seen in stacked charts 6873 if (this.isHorizontal) { 6874 barWidth = this.series[i][j] / this.yRatio[this.yaxisIndex]; 6875 6876 if (textRects.width / 1.6 > barWidth) { 6877 text = ''; 6878 } 6879 } else { 6880 barHeight = this.series[i][j] / this.yRatio[this.yaxisIndex]; 6881 6882 if (textRects.height / 1.6 > barHeight) { 6883 text = ''; 6884 } 6885 } 6886 } 6887 6888 dataLabels.plotDataLabelsText({ 6889 x: x, 6890 y: y, 6891 text: text, 6892 i: i, 6893 j: j, 6894 parent: elDataLabelsWrap, 6895 dataLabelsConfig: dataLabelsConfig, 6896 alwaysDrawDataLabel: true, 6897 offsetCorrection: true 6898 }); 6899 } 6900 6901 return elDataLabelsWrap; 6902 } 6903 /** barEndingShape draws the various shapes on top of bars/columns 6904 * @memberof Bar 6905 * @param {object} w - chart context 6906 * @param {object} opts - consists several properties like barHeight/barWidth 6907 * @param {array} series - global primary series 6908 * @param {int} i - current iterating series's index 6909 * @param {int} j - series's j of i 6910 * @return {object} path - ending shape whether round/arrow 6911 * ending_p_from - similar to pathFrom 6912 * newY - which is calculated from existing y and new shape's top 6913 **/ 6914 6915 }, { 6916 key: "barEndingShape", 6917 value: function barEndingShape(w, opts, series, i, j) { 6918 var graphics = new Graphics(this.ctx); 6919 6920 if (this.isHorizontal) { 6921 var endingShape = null; 6922 var endingShapeFrom = ''; 6923 var x = opts.x; 6924 6925 if (typeof series[i][j] !== 'undefined' || series[i][j] !== null) { 6926 var inverse = series[i][j] < 0; 6927 var eX = opts.barHeight / 2 - opts.strokeWidth; 6928 if (inverse) eX = -opts.barHeight / 2 - opts.strokeWidth; 6929 6930 if (!w.config.chart.stacked) { 6931 if (this.barOptions.endingShape === 'rounded') { 6932 x = opts.x - eX / 2; 6933 } 6934 } 6935 6936 switch (this.barOptions.endingShape) { 6937 case 'flat': 6938 endingShape = graphics.line(x, opts.barYPosition + opts.barHeight - opts.strokeWidth);
6939 break; 6940 6941 case 'rounded': 6942 endingShape = graphics.quadraticCurve(x + eX, opts.barYPosition + (opts.barHeight - opts.strokeWidth) / 2, x, opts.barYPosition + opts.barHeight - opts.strokeWidth); 6943 break; 6944 } 6945 } 6946 6947 return { 6948 path: endingShape, 6949 ending_p_from: endingShapeFrom, 6950 newX: x 6951 }; 6952 } else { 6953 var _endingShape = null; 6954 var _endingShapeFrom = ''; 6955 var y = opts.y; 6956 6957 if (typeof series[i][j] !== 'undefined' || series[i][j] !== null) { 6958 var _inverse = series[i][j] < 0; 6959 6960 var eY = opts.barWidth / 2 - opts.strokeWidth; 6961 if (_inverse) eY = -opts.barWidth / 2 - opts.strokeWidth; 6962 6963 if (!w.config.chart.stacked) { 6964 // the shape exceeds the chart height, hence reduce y 6965 if (this.barOptions.endingShape === 'rounded') { 6966 y = y + eY / 2; 6967 } 6968 } 6969 6970 switch (this.barOptions.endingShape) { 6971 case 'flat': 6972 _endingShape = graphics.line(opts.barXPosition + opts.barWidth - opts.strokeWidth, y); 6973 break; 6974 6975 case 'rounded': 6976 _endingShape = graphics.quadraticCurve(opts.barXPosition + (opts.barWidth - opts.strokeWidth) / 2, y - eY, opts.barXPosition + opts.barWidth - opts.strokeWidth, y); 6977 break; 6978 } 6979 } 6980 6981 return { 6982 path: _endingShape, 6983 ending_p_from: _endingShapeFrom, 6984 newY: y 6985 }; 6986 } 6987 } 6988 }]); 6989 6990 return Bar; 6991 }(); 6992 6993 /** 6994 * ApexCharts BarStacked Class responsible for drawing both Stacked Columns and Bars. 6995 * 6996 * @module BarStacked 6997 * The whole calculation for stacked bar/column is different from normal bar/column, 6998 * hence it makes sense to derive a new class for it extending most of the props of Parent Bar 6999 **/ 7000 7001 var BarStacked = 7002 /*#__PURE__*/ 7003 function (_Bar) { 7004 _inherits(BarStacked, _Bar); 7005 7006 function BarStacked() { 7007 _classCallCheck(this, BarStacked); 7008 7009 return _possibleConstructorReturn(this, _getPrototypeOf(BarStacked).apply(this, arguments)); 7010 } 7011 7012 _createClass(BarStacked, [{ 7013 key: "draw", 7014 value: function draw(series, seriesIndex) { 7015 var w = this.w; 7016 this.graphics = new Graphics(this.ctx); 7017 this.fill = new Fill(this.ctx); 7018 this.bar = new Bar(this.ctx, this.xyRatios); 7019 var coreUtils = new CoreUtils(this.ctx, w); 7020 series = coreUtils.getLogSeries(series); 7021 this.yRatio = coreUtils.getLogYRatios(this.yRatio); 7022 this.initVariables(series); 7023 7024 if (w.config.chart.stackType === '100%') { 7025 series = w.globals.seriesPercent.slice(); 7026 } 7027 7028 this.series = series; 7029 this.totalItems = 0; 7030 this.prevY = []; // y position on chart 7031 7032 this.prevX = []; // x position on chart 7033 7034 this.prevYF = []; // y position including shapes on chart 7035 7036 this.prevXF = []; // x position including shapes on chart 7037 7038 this.prevYVal = []; // y values (series[i][j]) in columns 7039 7040 this.prevXVal = []; // x values (series[i][j]) in bars 7041 7042 this.xArrj = []; // xj indicates x position on graph in bars 7043 7044 this.xArrjF = []; // xjF indicates bar's x position + endingshape's positions in bars 7045 7046 this.xArrjVal = []; // x val means the actual series's y values in horizontal/bars 7047 7048 this.yArrj = []; // yj indicates y position on graph in columns 7049 7050 this.yArrjF = []; // yjF indicates bar's y position + endingshape's positions in columns 7051 7052 this.yArrjVal = []; // y val means the actual series's y values in columns 7053 7054 for (var sl = 0; sl < series.length; sl++) { 7055 if (series[sl].length > 0) { 7056 this.totalItems += series[sl].length; 7057 } 7058 } 7059 7060 var ret = this.graphics.group({ 7061 class: 'apexcharts-bar-series apexcharts-plot-series' 7062 }); 7063 var x = 0; 7064 var y = 0; 7065 7066 for (var i = 0, bc = 0; i < series.length; i++, bc++) { 7067 var pathTo = void 0, 7068 pathFrom = void 0; 7069 var xDivision = void 0; // xDivision is the GRIDWIDTH divided by number of datapoints (columns) 7070 7071 var yDivision = void 0; // yDivision is the GRIDHEIGHT divided by number of datapoints (bars) 7072 7073 var zeroH = void 0; // zeroH is the baseline where 0 meets y axis 7074 7075 var zeroW = void 0; // zeroW is the baseline where 0 meets x axis 7076 7077 var xArrValues = []; 7078 var yArrValues = []; 7079 var realIndex = w.globals.comboCharts ? seriesIndex[i] : i; 7080 7081 if (this.yRatio.length > 1) { 7082 this.yaxisIndex = realIndex; 7083 } 7084 7085 this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed; // el to which series will be drawn 7086 7087 var elSeries = this.graphics.group({ 7088 class: "apexcharts-series", 7089 seriesName: Utils.escapeString(w.globals.seriesNames[realIndex]), 7090 rel: i + 1, 7091 'data:realIndex': realIndex 7092 }); // eldatalabels 7093 7094 var elDataLabelsWrap = this.graphics.group({ 7095 class: 'apexcharts-datalabels' 7096 }); 7097 var strokeWidth = 0; 7098 var barHeight = 0; 7099 var barWidth = 0; 7100 var initPositions = this.initialPositions(x, y, xDivision, yDivision, zeroH, zeroW); 7101 y = initPositions.y;
7102 barHeight = initPositions.barHeight; 7103 yDivision = initPositions.yDivision; 7104 zeroW = initPositions.zeroW; 7105 x = initPositions.x; 7106 barWidth = initPositions.barWidth; 7107 xDivision = initPositions.xDivision; 7108 zeroH = initPositions.zeroH; 7109 this.yArrj = []; 7110 this.yArrjF = []; 7111 this.yArrjVal = []; 7112 this.xArrj = []; 7113 this.xArrjF = []; 7114 this.xArrjVal = []; // if (!this.horizontal) { 7115 // this.xArrj.push(x + barWidth / 2) 7116 // } 7117 7118 for (var j = 0; j < w.globals.dataPoints; j++) { 7119 if (w.config.stroke.show) { 7120 if (this.isNullValue) { 7121 strokeWidth = 0; 7122 } else { 7123 strokeWidth = Array.isArray(this.strokeWidth) ? this.strokeWidth[realIndex] : this.strokeWidth; 7124 } 7125 } 7126 7127 var paths = null; 7128 7129 if (this.isHorizontal) { 7130 paths = this.drawBarPaths({ 7131 indexes: { 7132 i: i, 7133 j: j, 7134 realIndex: realIndex, 7135 bc: bc 7136 }, 7137 barHeight: barHeight, 7138 strokeWidth: strokeWidth, 7139 pathTo: pathTo, 7140 pathFrom: pathFrom, 7141 zeroW: zeroW, 7142 x: x, 7143 y: y, 7144 yDivision: yDivision, 7145 elSeries: elSeries 7146 }); 7147 barWidth = this.series[i][j] / this.invertedYRatio; 7148 } else { 7149 paths = this.drawColumnPaths({ 7150 indexes: { 7151 i: i, 7152 j: j, 7153 realIndex: realIndex, 7154 bc: bc 7155 }, 7156 x: x, 7157 y: y, 7158 xDivision: xDivision, 7159 pathTo: pathTo, 7160 pathFrom: pathFrom, 7161 barWidth: barWidth, 7162 zeroH: zeroH, 7163 strokeWidth: strokeWidth, 7164 elSeries: elSeries 7165 }); 7166 barHeight = this.series[i][j] / this.yRatio[this.yaxisIndex]; 7167 } 7168 7169 pathTo = paths.pathTo; 7170 pathFrom = paths.pathFrom; 7171 y = paths.y; 7172 x = paths.x; 7173 xArrValues.push(x); 7174 yArrValues.push(y); 7175 var pathFill = this.bar.getPathFillColor(series, i, j, realIndex); 7176 elSeries = this.renderSeries({ 7177 realIndex: realIndex, 7178 pathFill: pathFill, 7179 j: j, 7180 i: i, 7181 pathFrom: pathFrom, 7182 pathTo: pathTo, 7183 strokeWidth: strokeWidth, 7184 elSeries: elSeries, 7185 x: x, 7186 y: y, 7187 series: series, 7188 barHeight: barHeight, 7189 barWidth: barWidth, 7190 elDataLabelsWrap: elDataLabelsWrap, 7191 type: 'bar', 7192 visibleSeries: 0 7193 }); 7194 } // push all x val arrays into main xArr 7195 7196 7197 w.globals.seriesXvalues[realIndex] = xArrValues; 7198 w.globals.seriesYvalues[realIndex] = yArrValues; // push all current y values array to main PrevY Array 7199 7200 this.prevY.push(this.yArrj); 7201 this.prevYF.push(this.yArrjF); 7202 this.prevYVal.push(this.yArrjVal); 7203 this.prevX.push(this.xArrj); 7204 this.prevXF.push(this.xArrjF); 7205 this.prevXVal.push(this.xArrjVal); 7206 ret.add(elSeries); 7207 } 7208 7209 return ret; 7210 } 7211 }, { 7212 key: "initialPositions", 7213 value: function initialPositions(x, y, xDivision, yDivision, zeroH, zeroW) { 7214 var w = this.w; 7215 var barHeight, barWidth; 7216 7217 if (this.isHorizontal) { 7218 // height divided into equal parts 7219 yDivision = w.globals.gridHeight / w.globals.dataPoints; 7220 barHeight = yDivision; 7221 barHeight = barHeight * parseInt(w.config.plotOptions.bar.barHeight) / 100; 7222 zeroW = this.baseLineInvertedY + w.globals.padHorizontal + (this.isReversed ? w.globals.gridWidth : 0) - (this.isReversed ? this.baseLineInvertedY * 2 : 0); // initial y position is half of barHeight * half of number of Bars 7223
7224 y = (yDivision - barHeight) / 2; 7225 } else { 7226 // width divided into equal parts 7227 xDivision = w.globals.gridWidth / w.globals.dataPoints; 7228 barWidth = xDivision; 7229 7230 if (w.globals.isXNumeric) { 7231 xDivision = w.globals.minXDiff / this.xRatio; 7232 barWidth = xDivision * parseInt(this.barOptions.columnWidth) / 100; 7233 } else { 7234 barWidth = barWidth * parseInt(w.config.plotOptions.bar.columnWidth) / 100; 7235 } 7236 7237 zeroH = this.baseLineY[this.yaxisIndex] + (this.isReversed ? w.globals.gridHeight : 0) - (this.isReversed ? this.baseLineY[this.yaxisIndex] * 2 : 0); // initial x position is one third of barWidth 7238 7239 x = w.globals.padHorizontal + (xDivision - barWidth) / 2; 7240 } 7241 7242 return { 7243 x: x, 7244 y: y, 7245 yDivision: yDivision, 7246 xDivision: xDivision, 7247 barHeight: barHeight, 7248 barWidth: barWidth, 7249 zeroH: zeroH, 7250 zeroW: zeroW 7251 }; 7252 } 7253 }, { 7254 key: "drawBarPaths", 7255 value: function drawBarPaths(_ref) { 7256 var indexes = _ref.indexes, 7257 barHeight = _ref.barHeight, 7258 strokeWidth = _ref.strokeWidth, 7259 pathTo = _ref.pathTo, 7260 pathFrom = _ref.pathFrom, 7261 zeroW = _ref.zeroW, 7262 x = _ref.x, 7263 y = _ref.y, 7264 yDivision = _ref.yDivision, 7265 elSeries = _ref.elSeries; 7266 var w = this.w; 7267 var barYPosition = y; 7268 var barXPosition; 7269 var i = indexes.i; 7270 var j = indexes.j; 7271 var realIndex = indexes.realIndex; 7272 var bc = indexes.bc; 7273 var prevBarW = 0; 7274 7275 for (var k = 0; k < this.prevXF.length; k++) { 7276 prevBarW = prevBarW + this.prevXF[k][j]; 7277 } 7278 7279 if (i > 0) { 7280 var bXP = zeroW; 7281 7282 if (this.prevXVal[i - 1][j] < 0) { 7283 if (this.series[i][j] >= 0) { 7284 bXP = this.prevX[i - 1][j] + prevBarW - (this.isReversed ? prevBarW : 0) * 2; 7285 } else { 7286 bXP = this.prevX[i - 1][j]; 7287 } 7288 } else if (this.prevXVal[i - 1][j] >= 0) { 7289 if (this.series[i][j] >= 0) { 7290 bXP = this.prevX[i - 1][j]; 7291 } else { 7292 bXP = this.prevX[i - 1][j] - prevBarW + (this.isReversed ? prevBarW : 0) * 2; 7293 } 7294 } 7295 7296 barXPosition = bXP; 7297 } else { 7298 // the first series will not have prevX values 7299 barXPosition = zeroW; 7300 } 7301 7302 if (this.series[i][j] === null) { 7303 x = barXPosition; 7304 } else { 7305 x = barXPosition + this.series[i][j] / this.invertedYRatio - (this.isReversed ? this.series[i][j] / this.invertedYRatio : 0) * 2; 7306 } 7307 7308 var endingShapeOpts = { 7309 barHeight: barHeight, 7310 strokeWidth: strokeWidth, 7311 invertedYRatio: this.invertedYRatio, 7312 barYPosition: barYPosition, 7313 x: x 7314 }; 7315 var endingShape = this.bar.barEndingShape(w, endingShapeOpts, this.series, i, j); 7316 7317 if (this.series.length > 1 && i !== this.endingShapeOnSeriesNumber) { 7318 // revert back to flat shape if not last series 7319 endingShape.path = this.graphics.line(endingShape.newX, barYPosition + barHeight - strokeWidth); 7320 } 7321 7322 this.xArrj.push(endingShape.newX); 7323 this.xArrjF.push(Math.abs(barXPosition - endingShape.newX)); 7324 this.xArrjVal.push(this.series[i][j]); 7325 pathTo = this.graphics.move(barXPosition, barYPosition); 7326 pathFrom = this.graphics.move(barXPosition, barYPosition); 7327 7328 if (w.globals.previousPaths.length > 0) { 7329 pathFrom = this.bar.getPathFrom(realIndex, j, false); 7330 } 7331 7332 pathTo = pathTo + this.graphics.line(endingShape.newX, barYPosition) + endingShape.path + this.graphics.line(barXPosition, barYPosition + barHeight - strokeWidth) + this.graphics.line(barXPosition, barYPosition); 7333 pathFrom = pathFrom + this.graphics.line(barXPosition, barYPosition) + this.graphics.line(barXPosition, barYPosition + barHeight - strokeWidth) + this.graphics.line(barXPosition, barYPosition + barHeight - strokeWidth) + this.graphics.line(barXPosition, barYPosition + barHeight - strokeWidth) + this.graphics.line(barXPosition, barYPosition); 7334 7335 if (w.config.plotOptions.bar.colors.backgroundBarColors.length > 0 && i === 0) { 7336 if (bc >= w.config.plotOptions.bar.colors.backgroundBarColors.length) { 7337 bc = 0; 7338 } 7339 7340 var bcolor = w.config.plotOptions.bar.colors.backgroundBarColors[bc]; 7341 var rect = this.graphics.drawRect(0, barYPosition, w.globals.gridWidth, barHeight, 0, bcolor, w.config.plotOptions.bar.colors.backgroundBarOpacity); 7342 elSeries.add(rect); 7343 rect.node.classList.add('apexcharts-backgroundBar'); 7344 } 7345
7346 y = y + yDivision; 7347 return { 7348 pathTo: pathTo, 7349 pathFrom: pathFrom, 7350 x: x, 7351 y: y 7352 }; 7353 } 7354 }, { 7355 key: "drawColumnPaths", 7356 value: function drawColumnPaths(_ref2) { 7357 var indexes = _ref2.indexes, 7358 x = _ref2.x, 7359 y = _ref2.y, 7360 xDivision = _ref2.xDivision, 7361 pathTo = _ref2.pathTo, 7362 pathFrom = _ref2.pathFrom, 7363 barWidth = _ref2.barWidth, 7364 zeroH = _ref2.zeroH, 7365 strokeWidth = _ref2.strokeWidth, 7366 elSeries = _ref2.elSeries; 7367 var w = this.w; 7368 var i = indexes.i; 7369 var j = indexes.j; 7370 var realIndex = indexes.realIndex; 7371 var bc = indexes.bc; 7372 7373 if (w.globals.isXNumeric) { 7374 var seriesVal = w.globals.seriesX[i][j]; 7375 if (!seriesVal) seriesVal = 0; 7376 x = (seriesVal - w.globals.minX) / this.xRatio - barWidth / 2; 7377 } 7378 7379 var barXPosition = x; 7380 var barYPosition; 7381 var prevBarH = 0; 7382 7383 for (var k = 0; k < this.prevYF.length; k++) { 7384 prevBarH = prevBarH + this.prevYF[k][j]; 7385 } 7386 7387 if (i > 0 && !w.globals.isXNumeric || i > 0 && w.globals.isXNumeric && w.globals.seriesX[i - 1][j] === w.globals.seriesX[i][j]) { 7388 var bYP; 7389 var prevYValue = this.prevY[i - 1][j]; 7390 7391 if (this.prevYVal[i - 1][j] < 0) { 7392 if (this.series[i][j] >= 0) { 7393 bYP = prevYValue - prevBarH + (this.isReversed ? prevBarH : 0) * 2; 7394 } else { 7395 bYP = prevYValue; 7396 } 7397 } else { 7398 if (this.series[i][j] >= 0) { 7399 bYP = prevYValue; 7400 } else { 7401 bYP = prevYValue + prevBarH - (this.isReversed ? prevBarH : 0) * 2; 7402 } 7403 } 7404 7405 barYPosition = bYP; 7406 } else { 7407 // the first series will not have prevY values, also if the prev index's series X doesn't matches the current index's series X, then start from zero 7408 barYPosition = w.globals.gridHeight - zeroH; 7409 } 7410 7411 y = barYPosition - this.series[i][j] / this.yRatio[this.yaxisIndex] + (this.isReversed ? this.series[i][j] / this.yRatio[this.yaxisIndex] : 0) * 2; 7412 var endingShapeOpts = { 7413 barWidth: barWidth, 7414 strokeWidth: strokeWidth, 7415 yRatio: this.yRatio[this.yaxisIndex], 7416 barXPosition: barXPosition, 7417 y: y 7418 }; 7419 var endingShape = this.bar.barEndingShape(w, endingShapeOpts, this.series, i, j); 7420 this.yArrj.push(endingShape.newY); 7421 this.yArrjF.push(Math.abs(barYPosition - endingShape.newY)); 7422 this.yArrjVal.push(this.series[i][j]); 7423 pathTo = this.graphics.move(barXPosition, barYPosition); 7424 pathFrom = this.graphics.move(barXPosition, barYPosition); 7425 7426 if (w.globals.previousPaths.length > 0) { 7427 pathFrom = this.bar.getPathFrom(realIndex, j, false); 7428 } 7429 7430 pathTo = pathTo + this.graphics.line(barXPosition, endingShape.newY) + endingShape.path + this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) + this.graphics.line(barXPosition - strokeWidth / 2, barYPosition); 7431 pathFrom = pathFrom + this.graphics.line(barXPosition, barYPosition) + this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) + this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) + this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) + this.graphics.line(barXPosition - strokeWidth / 2, barYPosition); 7432 7433 if (w.config.plotOptions.bar.colors.backgroundBarColors.length > 0 && i === 0) { 7434 if (bc >= w.config.plotOptions.bar.colors.backgroundBarColors.length) { 7435 bc = 0; 7436 } 7437 7438 var bcolor = w.config.plotOptions.bar.colors.backgroundBarColors[bc]; 7439 var rect = this.graphics.drawRect(barXPosition, 0, barWidth, w.globals.gridHeight, 0, bcolor, w.config.plotOptions.bar.colors.backgroundBarOpacity); 7440 elSeries.add(rect); 7441 rect.node.classList.add('apexcharts-backgroundBar'); 7442 } 7443 7444 x = x + xDivision; 7445 return { 7446 pathTo: pathTo, 7447 pathFrom: pathFrom, 7448 x: w.globals.isXNumeric ? x - xDivision : x, 7449 y: y 7450 }; 7451 } 7452 /*
7453 * When user clicks on legends, the collapsed series will be filled with [0,0,0,...,0] 7454 * We need to make sure, that the last series is not [0,0,0,...,0] 7455 * as we need to draw shapes on the last series (for stacked bars/columns only) 7456 * Hence, we are collecting all inner arrays in series which has [0,0,0...,0] 7457 **/ 7458 7459 }, { 7460 key: "checkZeroSeries", 7461 value: function checkZeroSeries(_ref3) { 7462 var series = _ref3.series; 7463 var w = this.w; 7464 7465 for (var zs = 0; zs < series.length; zs++) { 7466 var total = 0; 7467 7468 for (var zsj = 0; zsj < series[w.globals.maxValsInArrayIndex].length; zsj++) { 7469 total += series[zs][zsj]; 7470 } 7471 7472 if (total === 0) { 7473 this.zeroSerieses.push(zs); 7474 } 7475 } // After getting all zeroserieses, we need to ensure whether endingshapeonSeries is not in that zeroseries array 7476 7477 7478 for (var s = series.length - 1; s >= 0; s--) { 7479 if (this.zeroSerieses.indexOf(s) > -1 && s === this.endingShapeOnSeriesNumber) { 7480 this.endingShapeOnSeriesNumber -= 1; 7481 } 7482 } 7483 } 7484 }]); 7485 7486 return BarStacked; 7487 }(Bar); 7488 7489 /** 7490 * ApexCharts CandleStick Class responsible for drawing both Stacked Columns and Bars. 7491 * 7492 * @module CandleStick 7493 **/ 7494 7495 var CandleStick = 7496 /*#__PURE__*/ 7497 function (_Bar) { 7498 _inherits(CandleStick, _Bar); 7499 7500 function CandleStick() { 7501 _classCallCheck(this, CandleStick); 7502 7503 return _possibleConstructorReturn(this, _getPrototypeOf(CandleStick).apply(this, arguments)); 7504 } 7505 7506 _createClass(CandleStick, [{ 7507 key: "draw", 7508 value: function draw(series, seriesIndex) { 7509 var w = this.w; 7510 var graphics = new Graphics(this.ctx); 7511 var fill = new Fill(this.ctx); 7512 this.candlestickOptions = this.w.config.plotOptions.candlestick; 7513 var coreUtils = new CoreUtils(this.ctx, w); 7514 series = coreUtils.getLogSeries(series); 7515 this.series = series; 7516 this.yRatio = coreUtils.getLogYRatios(this.yRatio); 7517 this.initVariables(series); 7518 var ret = graphics.group({ 7519 class: 'apexcharts-candlestick-series apexcharts-plot-series' 7520 }); 7521 7522 for (var i = 0, bc = 0; i < series.length; i++, bc++) { 7523 var pathTo = void 0, 7524 pathFrom = void 0; 7525 var x = void 0, 7526 y = void 0, 7527 xDivision = void 0, 7528 // xDivision is the GRIDWIDTH divided by number of datapoints (columns) 7529 zeroH = void 0; // zeroH is the baseline where 0 meets y axis 7530 7531 var yArrj = []; // hold y values of current iterating series 7532 7533 var xArrj = []; // hold x values of current iterating series 7534 7535 var realIndex = w.globals.comboCharts ? seriesIndex[i] : i; // el to which series will be drawn 7536 7537 var elSeries = graphics.group({ 7538 class: "apexcharts-series", 7539 seriesName: Utils.escapeString(w.globals.seriesNames[realIndex]), 7540 rel: i + 1, 7541 'data:realIndex': realIndex 7542 }); 7543 7544 if (series[i].length > 0) { 7545 this.visibleI = this.visibleI + 1; 7546 } 7547 7548 var strokeWidth = 0; 7549 var barHeight = 0; 7550 var barWidth = 0; 7551 7552 if (this.yRatio.length > 1) { 7553 this.yaxisIndex = realIndex; 7554 } 7555 7556 var initPositions = this.initialPositions(); 7557 y = initPositions.y; 7558 barHeight = initPositions.barHeight; 7559 x = initPositions.x; 7560 barWidth = initPositions.barWidth; 7561 xDivision = initPositions.xDivision; 7562 zeroH = initPositions.zeroH; 7563 xArrj.push(x + barWidth / 2); // eldatalabels 7564 7565 var elDataLabelsWrap = graphics.group({ 7566 class: 'apexcharts-datalabels' 7567 }); 7568 7569 for (var j = 0, tj = w.globals.dataPoints; j < w.globals.dataPoints; j++, tj--) { 7570 if (typeof this.series[i][j] === 'undefined' || series[i][j] === null) { 7571 this.isNullValue = true; 7572 } else { 7573 this.isNullValue = false; 7574 } 7575 7576 if (w.config.stroke.show) { 7577 if (this.isNullValue) { 7578 strokeWidth = 0; 7579 } else { 7580 strokeWidth = Array.isArray(this.strokeWidth) ? this.strokeWidth[realIndex] : this.strokeWidth; 7581 } 7582 } 7583 7584 var color = void 0; 7585 var paths = this.drawCandleStickPaths({ 7586 indexes: { 7587 i: i, 7588 j: j, 7589 realIndex: realIndex, 7590 bc: bc 7591 }, 7592 x: x, 7593 y: y, 7594 xDivision: xDivision, 7595 pathTo: pathTo, 7596 pathFrom: pathFrom, 7597 barWidth: barWidth, 7598 zeroH: zeroH, 7599 strokeWidth: strokeWidth, 7600 elSeries: elSeries 7601 }); 7602 pathTo = paths.pathTo; 7603 pathFrom = paths.pathFrom; 7604 y = paths.y; 7605 x = paths.x; 7606 color = paths.color; // push current X 7607 7608 if (j > 0) { 7609 xArrj.push(x + barWidth / 2); 7610 } 7611 7612 yArrj.push(y);
7613 var pathFill = fill.fillPath({ 7614 seriesNumber: realIndex, 7615 color: color, 7616 value: series[i][j] 7617 }); 7618 var lineFill = this.candlestickOptions.wick.useFillColor ? color : undefined; 7619 elSeries = this.renderSeries({ 7620 realIndex: realIndex, 7621 pathFill: pathFill, 7622 lineFill: lineFill, 7623 j: j, 7624 i: i, 7625 pathFrom: pathFrom, 7626 pathTo: pathTo, 7627 strokeWidth: strokeWidth, 7628 elSeries: elSeries, 7629 x: x, 7630 y: y, 7631 series: series, 7632 barHeight: barHeight, 7633 barWidth: barWidth, 7634 elDataLabelsWrap: elDataLabelsWrap, 7635 visibleSeries: this.visibleI, 7636 type: 'candlestick' 7637 }); 7638 } // push all x val arrays into main xArr 7639 7640 7641 w.globals.seriesXvalues[realIndex] = xArrj; 7642 w.globals.seriesYvalues[realIndex] = yArrj; 7643 ret.add(elSeries); 7644 } 7645 7646 return ret; 7647 } 7648 }, { 7649 key: "drawCandleStickPaths", 7650 value: function drawCandleStickPaths(_ref) { 7651 var indexes = _ref.indexes, 7652 x = _ref.x, 7653 y = _ref.y, 7654 xDivision = _ref.xDivision, 7655 pathTo = _ref.pathTo, 7656 pathFrom = _ref.pathFrom, 7657 barWidth = _ref.barWidth, 7658 zeroH = _ref.zeroH, 7659 strokeWidth = _ref.strokeWidth; 7660 var w = this.w; 7661 var graphics = new Graphics(this.ctx); 7662 var i = indexes.i; 7663 var j = indexes.j; 7664 var isPositive = true; 7665 var colorPos = w.config.plotOptions.candlestick.colors.upward; 7666 var colorNeg = w.config.plotOptions.candlestick.colors.downward; 7667 var yRatio = this.yRatio[this.yaxisIndex]; 7668 var realIndex = indexes.realIndex; 7669 var ohlc = this.getOHLCValue(realIndex, j); 7670 var l1 = zeroH; 7671 var l2 = zeroH; 7672 7673 if (ohlc.o > ohlc.c) { 7674 isPositive = false; 7675 } 7676 7677 var y1 = Math.min(ohlc.o, ohlc.c); 7678 var y2 = Math.max(ohlc.o, ohlc.c); 7679 7680 if (w.globals.isXNumeric) { 7681 x = (w.globals.seriesX[i][j] - w.globals.minX) / this.xRatio - barWidth / 2; 7682 } 7683 7684 var barXPosition = x + barWidth * this.visibleI; 7685 7686 if (typeof this.series[i][j] === 'undefined' || this.series[i][j] === null) { 7687 y1 = zeroH; 7688 } else { 7689 y1 = zeroH - y1 / yRatio; 7690 y2 = zeroH - y2 / yRatio; 7691 l1 = zeroH - ohlc.h / yRatio; 7692 l2 = zeroH - ohlc.l / yRatio; 7693 } 7694 7695 pathTo = graphics.move(barXPosition, zeroH); 7696 pathFrom = graphics.move(barXPosition, y1); 7697 7698 if (w.globals.previousPaths.length > 0) { 7699 pathFrom = this.getPathFrom(realIndex, j, true); 7700 } 7701 7702 pathTo = graphics.move(barXPosition, y2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth, y2) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition, y1) + graphics.line(barXPosition, y2 - strokeWidth / 2); 7703 pathFrom = pathFrom + graphics.move(barXPosition, y1); 7704 7705 if (!w.globals.isXNumeric) { 7706 x = x + xDivision; 7707 } 7708 7709 return { 7710 pathTo: pathTo, 7711 pathFrom: pathFrom, 7712 x: x, 7713 y: y2, 7714 barXPosition: barXPosition, 7715 color: isPositive ? colorPos : colorNeg 7716 }; 7717 } 7718 }, { 7719 key: "getOHLCValue", 7720 value: function getOHLCValue(i, j) { 7721 var w = this.w; 7722 return { 7723 o: w.globals.seriesCandleO[i][j], 7724 h: w.globals.seriesCandleH[i][j], 7725 l: w.globals.seriesCandleL[i][j], 7726 c: w.globals.seriesCandleC[i][j] 7727 }; 7728 } 7729 }]); 7730 7731 return CandleStick; 7732 }(Bar); 7733 7734 var Crosshairs = 7735 /*#__PURE__*/ 7736 function () { 7737 function Crosshairs(ctx) { 7738 _classCallCheck(this, Crosshairs); 7739 7740 this.ctx = ctx; 7741 this.w = ctx.w; 7742 } 7743 7744 _createClass(Crosshairs, [{ 7745 key: "drawXCrosshairs", 7746 value: function drawXCrosshairs() { 7747 var w = this.w; 7748 var graphics = new Graphics(this.ctx); 7749 var filters = new Filters(this.ctx); 7750 var crosshairGradient = w.config.xaxis.crosshairs.fill.gradient; 7751 var crosshairShadow = w.config.xaxis.crosshairs.dropShadow; 7752 var fillType = w.config.xaxis.crosshairs.fill.type; 7753 var gradientFrom = crosshairGradient.colorFrom; 7754 var gradientTo = crosshairGradient.colorTo; 7755 var opacityFrom = crosshairGradient.opacityFrom; 7756 var opacityTo = crosshairGradient.opacityTo; 7757 var stops = crosshairGradient.stops;
7758 var shadow = 'none'; 7759 var dropShadow = crosshairShadow.enabled; 7760 var shadowLeft = crosshairShadow.left; 7761 var shadowTop = crosshairShadow.top; 7762 var shadowBlur = crosshairShadow.blur; 7763 var shadowColor = crosshairShadow.color; 7764 var shadowOpacity = crosshairShadow.opacity; 7765 var xcrosshairsFill = w.config.xaxis.crosshairs.fill.color; 7766 7767 if (w.config.xaxis.crosshairs.show) { 7768 if (fillType === 'gradient') { 7769 xcrosshairsFill = graphics.drawGradient('vertical', gradientFrom, gradientTo, opacityFrom, opacityTo, null, stops, null); 7770 } 7771 7772 var xcrosshairs = graphics.drawRect(); 7773 7774 if (w.config.xaxis.crosshairs.width === 1) { 7775 // to prevent drawing 2 lines, convert rect to line 7776 xcrosshairs = graphics.drawLine(); 7777 } 7778 7779 xcrosshairs.attr({ 7780 class: 'apexcharts-xcrosshairs', 7781 x: 0, 7782 y: 0, 7783 y2: w.globals.gridHeight, 7784 width: Utils.isNumber(w.config.xaxis.crosshairs.width) ? w.config.xaxis.crosshairs.width : 0, 7785 height: w.globals.gridHeight, 7786 fill: xcrosshairsFill, 7787 filter: shadow, 7788 'fill-opacity': w.config.xaxis.crosshairs.opacity, 7789 stroke: w.config.xaxis.crosshairs.stroke.color, 7790 'stroke-width': w.config.xaxis.crosshairs.stroke.width, 7791 'stroke-dasharray': w.config.xaxis.crosshairs.stroke.dashArray 7792 }); 7793 7794 if (dropShadow) { 7795 xcrosshairs = filters.dropShadow(xcrosshairs, { 7796 left: shadowLeft, 7797 top: shadowTop, 7798 blur: shadowBlur, 7799 color: shadowColor, 7800 opacity: shadowOpacity 7801 }); 7802 } 7803 7804 w.globals.dom.elGraphical.add(xcrosshairs); 7805 } 7806 } 7807 }, { 7808 key: "drawYCrosshairs", 7809 value: function drawYCrosshairs() { 7810 var w = this.w; 7811 var graphics = new Graphics(this.ctx); 7812 var crosshair = w.config.yaxis[0].crosshairs; 7813 7814 if (w.config.yaxis[0].crosshairs.show) { 7815 var ycrosshairs = graphics.drawLine(0, 0, w.globals.gridWidth, 0, crosshair.stroke.color, crosshair.stroke.dashArray, crosshair.stroke.width); 7816 ycrosshairs.attr({ 7817 class: 'apexcharts-ycrosshairs' 7818 }); 7819 w.globals.dom.elGraphical.add(ycrosshairs); 7820 } // draw an invisible crosshair to help in positioning the yaxis tooltip 7821 7822 7823 var ycrosshairsHidden = graphics.drawLine(0, 0, w.globals.gridWidth, 0, crosshair.stroke.color, 0, 0); 7824 ycrosshairsHidden.attr({ 7825 class: 'apexcharts-ycrosshairs-hidden' 7826 }); 7827 w.globals.dom.elGraphical.add(ycrosshairsHidden); 7828 } 7829 }]); 7830 7831 return Crosshairs; 7832 }(); 7833 7834 /** 7835 * ApexCharts HeatMap Class. 7836 * @module HeatMap 7837 **/ 7838 7839 var HeatMap = 7840 /*#__PURE__*/ 7841 function () { 7842 function HeatMap(ctx, xyRatios) { 7843 _classCallCheck(this, HeatMap); 7844 7845 this.ctx = ctx; 7846 this.w = ctx.w; 7847 this.xRatio = xyRatios.xRatio; 7848 this.yRatio = xyRatios.yRatio; 7849 this.negRange = false; 7850 this.dynamicAnim = this.w.config.chart.animations.dynamicAnimation; 7851 this.rectRadius = this.w.config.plotOptions.heatmap.radius; 7852 this.strokeWidth = this.w.config.stroke.width; 7853 } 7854 7855 _createClass(HeatMap, [{ 7856 key: "draw", 7857 value: function draw(series) { 7858 var w = this.w; 7859 var graphics = new Graphics(this.ctx); 7860 var ret = graphics.group({ 7861 class: 'apexcharts-heatmap' 7862 }); 7863 ret.attr('clip-path', "url(#gridRectMask".concat(w.globals.cuid, ")")); // width divided into equal parts 7864 7865 var xDivision = w.globals.gridWidth / w.globals.dataPoints; 7866 var yDivision = w.globals.gridHeight / w.globals.series.length; 7867 var y1 = 0; 7868 var rev = false; 7869 this.checkColorRange(); 7870 var heatSeries = series.slice(); 7871 7872 if (w.config.yaxis[0].reversed) { 7873 rev = true; 7874 heatSeries.reverse(); 7875 } 7876 7877 for (var i = rev ? 0 : heatSeries.length - 1; rev ? i < heatSeries.length : i >= 0; rev ? i++ : i--) { 7878 // el to which series will be drawn 7879 var elSeries = graphics.group({ 7880 class: "apexcharts-series apexcharts-heatmap-series", 7881 seriesName: Utils.escapeString(w.globals.seriesNames[i]), 7882 rel: i + 1, 7883 'data:realIndex': i 7884 }); 7885 7886 if (w.config.chart.dropShadow.enabled) { 7887 var shadow = w.config.chart.dropShadow; 7888 var filters = new Filters(this.ctx); 7889 filters.dropShadow(elSeries, shadow, i); 7890 } 7891 7892 var x1 = 0; 7893 7894 for (var j = 0; j < heatSeries[i].length; j++) { 7895 var colorShadePercent = 1; 7896 var heatColorProps = this.determineHeatColor(i, j); 7897 7898 if (w.globals.hasNegs || this.negRange) { 7899 var shadeIntensity = w.config.plotOptions.heatmap.shadeIntensity; 7900 7901 if (w.config.plotOptions.heatmap.reverseNegativeShade) { 7902 if (heatColorProps.percent < 0) { 7903 colorShadePercent = heatColorProps.percent / 100 * (shadeIntensity * 1.25); 7904 } else { 7905 colorShadePercent = (1 - heatColorProps.percent / 100) * (shadeIntensity * 1.25); 7906 } 7907 } else { 7908 if (heatColorProps.percent < 0) { 7909 colorShadePercent = 1 - (1 + heatColorProps.percent / 100) * shadeIntensity; 7910 } else { 7911 colorShadePercent = (1 - heatColorProps.percent / 100) * shadeIntensity; 7912 } 7913 } 7914 } else { 7915 colorShadePercent = 1 - heatColorProps.percent / 100; 7916 } 7917 7918 var color = heatColorProps.color; 7919 7920 if (w.config.plotOptions.heatmap.enableShades) { 7921 var utils = new Utils(); 7922 color = Utils.hexToRgba(utils.shadeColor(colorShadePercent, heatColorProps.color), w.config.fill.opacity); 7923 } 7924 7925 var radius = this.rectRadius;
7926 var rect = graphics.drawRect(x1, y1, xDivision, yDivision, radius); 7927 rect.attr({ 7928 cx: x1, 7929 cy: y1 7930 }); 7931 rect.node.classList.add('apexcharts-heatmap-rect'); 7932 elSeries.add(rect); 7933 rect.attr({ 7934 fill: color, 7935 i: i, 7936 index: i, 7937 j: j, 7938 val: heatSeries[i][j], 7939 'stroke-width': this.strokeWidth, 7940 stroke: w.globals.stroke.colors[0], 7941 color: color 7942 }); 7943 rect.node.addEventListener('mouseenter', graphics.pathMouseEnter.bind(this, rect)); 7944 rect.node.addEventListener('mouseleave', graphics.pathMouseLeave.bind(this, rect)); 7945 rect.node.addEventListener('mousedown', graphics.pathMouseDown.bind(this, rect)); 7946 7947 if (w.config.chart.animations.enabled && !w.globals.dataChanged) { 7948 var speed = 1; 7949 7950 if (!w.globals.resized) { 7951 speed = w.config.chart.animations.speed; 7952 } 7953 7954 this.animateHeatMap(rect, x1, y1, xDivision, yDivision, speed); 7955 } 7956 7957 if (w.globals.dataChanged) { 7958 var _speed = 1; 7959 7960 if (this.dynamicAnim.enabled && w.globals.shouldAnimate) { 7961 _speed = this.dynamicAnim.speed; 7962 var colorFrom = w.globals.previousPaths[i] && w.globals.previousPaths[i][j] && w.globals.previousPaths[i][j].color; 7963 if (!colorFrom) colorFrom = 'rgba(255, 255, 255, 0)'; 7964 this.animateHeatColor(rect, Utils.isColorHex(colorFrom) ? colorFrom : Utils.rgb2hex(colorFrom), Utils.isColorHex(color) ? color : Utils.rgb2hex(color), _speed); 7965 } 7966 } 7967 7968 var dataLabels = this.calculateHeatmapDataLabels({ 7969 x: x1, 7970 y: y1, 7971 i: i, 7972 j: j, 7973 series: heatSeries, 7974 rectHeight: yDivision, 7975 rectWidth: xDivision 7976 }); 7977 7978 if (dataLabels !== null) { 7979 elSeries.add(dataLabels); 7980 } 7981 7982 x1 = x1 + xDivision; 7983 } 7984 7985 y1 = y1 + yDivision; 7986 ret.add(elSeries); 7987 } // adjust yaxis labels for heatmap 7988 7989 7990 var yAxisScale = w.globals.yAxisScale[0].result.slice(); 7991 7992 if (w.config.yaxis[0].reversed) { 7993 yAxisScale.unshift(''); 7994 } else { 7995 yAxisScale.push(''); 7996 } 7997 7998 w.globals.yAxisScale[0].result = yAxisScale; 7999 var divisor = w.globals.gridHeight / w.globals.series.length; 8000 w.config.yaxis[0].labels.offsetY = -(divisor / 2); 8001 return ret; 8002 } 8003 }, { 8004 key: "checkColorRange", 8005 value: function checkColorRange() { 8006 var _this = this; 8007 8008 var w = this.w; 8009 var heatmap = w.config.plotOptions.heatmap; 8010 8011 if (heatmap.colorScale.ranges.length > 0) { 8012 heatmap.colorScale.ranges.map(function (range, index) { 8013 if (range.from < 0) { 8014 _this.negRange = true; 8015 } 8016 }); 8017 } 8018 } 8019 }, { 8020 key: "determineHeatColor", 8021 value: function determineHeatColor(i, j) { 8022 var w = this.w; 8023 var val = w.globals.series[i][j]; 8024 var heatmap = w.config.plotOptions.heatmap; 8025 var seriesNumber = heatmap.colorScale.inverse ? j : i; 8026 var color = w.globals.colors[seriesNumber]; 8027 var min = Math.min.apply(Math, _toConsumableArray(w.globals.series[i])); 8028 var max = Math.max.apply(Math, _toConsumableArray(w.globals.series[i])); 8029 8030 if (!heatmap.distributed) { 8031 min = w.globals.minY; 8032 max = w.globals.maxY; 8033 } 8034 8035 if (typeof heatmap.colorScale.min !== 'undefined') { 8036 min = heatmap.colorScale.min < w.globals.minY ? heatmap.colorScale.min : w.globals.minY; 8037 max = heatmap.colorScale.max > w.globals.maxY ? heatmap.colorScale.max : w.globals.maxY; 8038 } 8039 8040 var total = Math.abs(max) + Math.abs(min); 8041 var percent = 100 * val / (total === 0 ? total - 0.000001 : total); 8042 8043 if (heatmap.colorScale.ranges.length > 0) { 8044 var colorRange = heatmap.colorScale.ranges; 8045 colorRange.map(function (range, index) { 8046 if (val >= range.from && val <= range.to) { 8047 color = range.color; 8048 min = range.from; 8049 max = range.to; 8050 8051 var _total = Math.abs(max) + Math.abs(min); 8052 8053 percent = 100 * val / (_total === 0 ? _total - 0.000001 : _total); 8054 } 8055 }); 8056 } 8057 8058 return { 8059 color: color, 8060 percent: percent 8061 }; 8062 } 8063 }, { 8064 key: "calculateHeatmapDataLabels", 8065 value: function calculateHeatmapDataLabels(_ref) { 8066 var x = _ref.x, 8067 y = _ref.y, 8068 i = _ref.i, 8069 j = _ref.j, 8070 series = _ref.series, 8071 rectHeight = _ref.rectHeight, 8072 rectWidth = _ref.rectWidth; 8073 var w = this.w; // let graphics = new Graphics(this.ctx) 8074 8075 var dataLabelsConfig = w.config.dataLabels; 8076 var graphics = new Graphics(this.ctx); 8077 var dataLabels = new DataLabels(this.ctx); 8078 var formatter = dataLabelsConfig.formatter; 8079 var elDataLabelsWrap = null; 8080 8081 if (dataLabelsConfig.enabled) { 8082 elDataLabelsWrap = graphics.group({ 8083 class: 'apexcharts-data-labels' 8084 }); 8085 var offX = dataLabelsConfig.offsetX; 8086 var offY = dataLabelsConfig.offsetY; 8087 var dataLabelsX = x + rectWidth / 2 + offX; 8088 var dataLabelsY = y + rectHeight / 2 + parseInt(dataLabelsConfig.style.fontSize) / 3 + offY; 8089 var text = formatter(w.globals.series[i][j], { 8090 seriesIndex: i, 8091 dataPointIndex: j, 8092 w: w 8093 }); 8094 dataLabels.plotDataLabelsText({ 8095 x: dataLabelsX, 8096 y: dataLabelsY, 8097 text: text, 8098 i: i, 8099 j: j, 8100 parent: elDataLabelsWrap, 8101 dataLabelsConfig: dataLabelsConfig 8102 }); 8103 } 8104 8105 return elDataLabelsWrap; 8106 } 8107 }, { 8108 key: "animateHeatMap", 8109 value: function animateHeatMap(el, x, y, width, height, speed) { 8110 var _this2 = this; 8111 8112 var animations = new Animations(this.ctx);
8113 animations.animateRect(el, { 8114 x: x + width / 2, 8115 y: y + height / 2, 8116 width: 0, 8117 height: 0 8118 }, { 8119 x: x, 8120 y: y, 8121 width: width, 8122 height: height 8123 }, speed, function () { 8124 _this2.w.globals.animationEnded = true; 8125 }); 8126 } 8127 }, { 8128 key: "animateHeatColor", 8129 value: function animateHeatColor(el, colorFrom, colorTo, speed) { 8130 el.attr({ 8131 fill: colorFrom 8132 }).animate(speed).attr({ 8133 fill: colorTo 8134 }); 8135 } 8136 }]); 8137 8138 return HeatMap; 8139 }(); 8140 8141 /** 8142 * ApexCharts Pie Class for drawing Pie / Donut Charts. 8143 * @module Pie 8144 **/ 8145 8146 var Pie = 8147 /*#__PURE__*/ 8148 function () { 8149 function Pie(ctx) { 8150 _classCallCheck(this, Pie); 8151 8152 this.ctx = ctx; 8153 this.w = ctx.w; 8154 this.chartType = this.w.config.chart.type; 8155 this.initialAnim = this.w.config.chart.animations.enabled; 8156 this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled; 8157 this.animBeginArr = [0]; 8158 this.animDur = 0; 8159 this.donutDataLabels = this.w.config.plotOptions.pie.donut.labels; 8160 var w = this.w; 8161 this.lineColorArr = w.globals.stroke.colors !== undefined ? w.globals.stroke.colors : w.globals.colors; 8162 this.defaultSize = w.globals.svgHeight < w.globals.svgWidth ? w.globals.svgHeight - 35 : w.globals.gridWidth; 8163 this.centerY = this.defaultSize / 2; 8164 this.centerX = w.globals.gridWidth / 2; 8165 this.fullAngle = 360; 8166 this.size = 0; 8167 this.donutSize = 0; 8168 this.sliceLabels = []; 8169 this.prevSectorAngleArr = []; // for dynamic animations 8170 } 8171 8172 _createClass(Pie, [{ 8173 key: "draw", 8174 value: function draw(series) { 8175 var self = this; 8176 var w = this.w; 8177 var graphics = new Graphics(this.ctx); 8178 var ret = graphics.group({ 8179 class: 'apexcharts-pie' 8180 }); 8181 var total = 0; 8182 8183 for (var k = 0; k < series.length; k++) { 8184 // CALCULATE THE TOTAL 8185 total += Utils.negToZero(series[k]); 8186 } 8187 8188 var sectorAngleArr = []; // el to which series will be drawn 8189 8190 var elSeries = graphics.group(); // prevent division by zero error if there is no data 8191 8192 if (total === 0) { 8193 total = 0.00001; 8194 } 8195 8196 for (var i = 0; i < series.length; i++) { 8197 // CALCULATE THE ANGLES 8198 var angle = this.fullAngle * Utils.negToZero(series[i]) / total; 8199 sectorAngleArr.push(angle); 8200 } 8201 8202 if (w.globals.dataChanged) { 8203 var prevTotal = 0; 8204 8205 for (var _k = 0; _k < w.globals.previousPaths.length; _k++) { 8206 // CALCULATE THE PREV TOTAL 8207 prevTotal += Utils.negToZero(w.globals.previousPaths[_k]); 8208 } 8209 8210 var previousAngle; 8211 8212 for (var _i = 0; _i < w.globals.previousPaths.length; _i++) { 8213 // CALCULATE THE PREVIOUS ANGLES 8214 previousAngle = this.fullAngle * Utils.negToZero(w.globals.previousPaths[_i]) / prevTotal; 8215 this.prevSectorAngleArr.push(previousAngle); 8216 } 8217 } 8218 8219 this.size = this.defaultSize / 2.05 - w.config.stroke.width - w.config.chart.dropShadow.blur; 8220 8221 if (w.config.plotOptions.pie.size !== undefined) { 8222 this.size = w.config.plotOptions.pie.size; 8223 } 8224 8225 this.donutSize = this.size * parseInt(w.config.plotOptions.pie.donut.size) / 100; 8226 var scaleSize = w.config.plotOptions.pie.customScale; 8227 var halfW = w.globals.gridWidth / 2; 8228 var halfH = w.globals.gridHeight / 2; 8229 var translateX = halfW - w.globals.gridWidth / 2 * scaleSize; 8230 var translateY = halfH - w.globals.gridHeight / 2 * scaleSize; 8231 8232 if (this.donutDataLabels.show) { 8233 var dataLabels = this.renderInnerDataLabels(this.donutDataLabels, { 8234 hollowSize: this.donutSize, 8235 centerX: this.centerX, 8236 centerY: this.centerY, 8237 opacity: this.donutDataLabels.show, 8238 translateX: translateX, 8239 translateY: translateY 8240 }); 8241 ret.add(dataLabels); 8242 } 8243 8244 if (w.config.chart.type === 'donut') { 8245 // draw the inner circle and add some text to it 8246 var circle = graphics.drawCircle(this.donutSize); 8247 circle.attr({ 8248 cx: this.centerX, 8249 cy: this.centerY, 8250 fill: w.config.plotOptions.pie.donut.background 8251 }); 8252 elSeries.add(circle); 8253 } 8254 8255 var elG = self.drawArcs(sectorAngleArr, series); // add slice dataLabels at the end 8256
8257 this.sliceLabels.forEach(function (s) { 8258 elG.add(s); 8259 }); 8260 elSeries.attr({ 8261 transform: "translate(".concat(translateX, ", ").concat(translateY - 5, ") scale(").concat(scaleSize, ")") 8262 }); 8263 ret.attr({ 8264 'data:innerTranslateX': translateX, 8265 'data:innerTranslateY': translateY - 25 8266 }); 8267 elSeries.add(elG); 8268 ret.add(elSeries); 8269 return ret; 8270 } // core function for drawing pie arcs 8271 8272 }, { 8273 key: "drawArcs", 8274 value: function drawArcs(sectorAngleArr, series) { 8275 var w = this.w; 8276 var filters = new Filters(this.ctx); 8277 var graphics = new Graphics(this.ctx); 8278 var fill = new Fill(this.ctx); 8279 var g = graphics.group(); 8280 var startAngle = 0; 8281 var prevStartAngle = 0; 8282 var endAngle = 0; 8283 var prevEndAngle = 0; 8284 this.strokeWidth = w.config.stroke.show ? w.config.stroke.width : 0; 8285 8286 for (var i = 0; i < sectorAngleArr.length; i++) { 8287 // if(sectorAngleArr[i]>0) { 8288 var elPieArc = graphics.group({ 8289 class: "apexcharts-series apexcharts-pie-series", 8290 seriesName: Utils.escapeString(w.globals.seriesNames[i]), 8291 id: 'apexcharts-series-' + i, 8292 rel: i + 1 8293 }); 8294 g.add(elPieArc); 8295 startAngle = endAngle; 8296 prevStartAngle = prevEndAngle; 8297 endAngle = startAngle + sectorAngleArr[i]; 8298 prevEndAngle = prevStartAngle + this.prevSectorAngleArr[i]; 8299 var angle = endAngle - startAngle; 8300 var pathFill = fill.fillPath({ 8301 seriesNumber: i, 8302 size: this.size, 8303 value: series[i] 8304 }); // additionaly, pass size for gradient drawing in the fillPath function 8305 8306 var path = this.getChangedPath(prevStartAngle, prevEndAngle); 8307 var elPath = graphics.drawPath({ 8308 d: path, 8309 stroke: this.lineColorArr instanceof Array ? this.lineColorArr[i] : this.lineColorArr, 8310 strokeWidth: this.strokeWidth, 8311 fill: pathFill, 8312 fillOpacity: w.config.fill.opacity, 8313 classes: 'apexcharts-pie-area' 8314 }); 8315 elPath.attr({ 8316 id: "apexcharts-".concat(w.config.chart.type, "-slice-").concat(i), 8317 index: 0, 8318 j: i 8319 }); 8320 8321 if (w.config.chart.dropShadow.enabled) { 8322 var shadow = w.config.chart.dropShadow; 8323 filters.dropShadow(elPath, shadow, i); 8324 } 8325 8326 this.addListeners(elPath, this.donutDataLabels); 8327 Graphics.setAttrs(elPath.node, { 8328 'data:angle': angle, 8329 'data:startAngle': startAngle, 8330 'data:strokeWidth': this.strokeWidth, 8331 'data:value': series[i] 8332 }); 8333 var labelPosition = { 8334 x: 0, 8335 y: 0 8336 }; 8337 8338 if (w.config.chart.type === 'pie') { 8339 labelPosition = Utils.polarToCartesian(this.centerX, this.centerY, this.size / 1.25 + w.config.plotOptions.pie.dataLabels.offset, startAngle + (endAngle - startAngle) / 2); 8340 } else if (w.config.chart.type === 'donut') { 8341 labelPosition = Utils.polarToCartesian(this.centerX, this.centerY, (this.size + this.donutSize) / 2 + w.config.plotOptions.pie.dataLabels.offset, startAngle + (endAngle - startAngle) / 2); 8342 } 8343 8344 elPieArc.add(elPath); // Animation code starts 8345 8346 var dur = 0; 8347 8348 if (this.initialAnim && !w.globals.resized && !w.globals.dataChanged) { 8349 dur = (endAngle - startAngle) / this.fullAngle * w.config.chart.animations.speed; 8350 this.animDur = dur + this.animDur; 8351 this.animBeginArr.push(this.animDur); 8352 } else { 8353 this.animBeginArr.push(0); 8354 } 8355 8356 if (this.dynamicAnim && w.globals.dataChanged) { 8357 this.animatePaths(elPath, { 8358 endAngle: endAngle, 8359 startAngle: startAngle, 8360 prevStartAngle: prevStartAngle, 8361 prevEndAngle: prevEndAngle, 8362 animateStartingPos: true, 8363 i: i, 8364 animBeginArr: this.animBeginArr, 8365 dur: w.config.chart.animations.dynamicAnimation.speed 8366 }); 8367 } else { 8368 this.animatePaths(elPath, { 8369 endAngle: endAngle, 8370 startAngle: startAngle, 8371 i: i, 8372 totalItems: sectorAngleArr.length - 1, 8373 animBeginArr: this.animBeginArr, 8374 dur: dur 8375 }); 8376 } // animation code ends 8377 8378 8379 if (w.config.plotOptions.pie.expandOnClick) { 8380 elPath.click(this.pieClicked.bind(this, i)); 8381 } 8382 8383 if (w.config.dataLabels.enabled) { 8384 var xPos = labelPosition.x; 8385 var yPos = labelPosition.y; 8386 var text = 100 * (endAngle - startAngle) / 360 + '%'; 8387 8388 if (angle !== 0 && w.config.plotOptions.pie.dataLabels.minAngleToShowLabel < sectorAngleArr[i]) { 8389 var formatter = w.config.dataLabels.formatter; 8390 8391 if (formatter !== undefined) { 8392 text = formatter(w.globals.seriesPercent[i][0], { 8393 seriesIndex: i, 8394 w: w 8395 }); 8396 } 8397 8398 var foreColor = w.globals.dataLabels.style.colors[i]; 8399 var elPieLabel = graphics.drawText({ 8400 x: xPos, 8401 y: yPos, 8402 text: text, 8403 textAnchor: 'middle', 8404 fontSize: w.config.dataLabels.style.fontSize, 8405 fontFamily: w.config.dataLabels.style.fontFamily, 8406 foreColor: foreColor 8407 }); 8408 8409 if (w.config.dataLabels.dropShadow.enabled) { 8410 var textShadow = w.config.dataLabels.dropShadow; 8411 8412 var _filters = new Filters(this.ctx); 8413 8414 _filters.dropShadow(elPieLabel, textShadow); 8415 } 8416 8417 elPieLabel.node.classList.add('apexcharts-pie-label'); 8418 8419 if (w.config.chart.animations.animate && w.globals.resized === false) { 8420 elPieLabel.node.classList.add('apexcharts-pie-label-delay'); 8421 elPieLabel.node.style.animationDelay = w.config.chart.animations.speed / 940 + 's'; 8422 } 8423
8424 this.sliceLabels.push(elPieLabel); 8425 } 8426 } // } 8427 8428 } 8429 8430 return g; 8431 } 8432 }, { 8433 key: "addListeners", 8434 value: function addListeners(elPath, dataLabels) { 8435 var graphics = new Graphics(this.ctx); // append filters on mouseenter and mouseleave 8436 8437 elPath.node.addEventListener('mouseenter', graphics.pathMouseEnter.bind(this, elPath)); 8438 elPath.node.addEventListener('mouseenter', this.printDataLabelsInner.bind(this, elPath.node, dataLabels)); 8439 elPath.node.addEventListener('mouseleave', graphics.pathMouseLeave.bind(this, elPath)); 8440 elPath.node.addEventListener('mouseleave', this.revertDataLabelsInner.bind(this, elPath.node, dataLabels)); 8441 elPath.node.addEventListener('mousedown', graphics.pathMouseDown.bind(this, elPath)); 8442 elPath.node.addEventListener('mousedown', this.printDataLabelsInner.bind(this, elPath.node, dataLabels)); 8443 } // This function can be used for other circle charts too 8444 8445 }, { 8446 key: "animatePaths", 8447 value: function animatePaths(el, opts) { 8448 var w = this.w; 8449 var me = this; 8450 var angle = opts.endAngle - opts.startAngle; 8451 var prevAngle = angle; 8452 var fromStartAngle = opts.startAngle; 8453 var toStartAngle = opts.startAngle; 8454 8455 if (opts.prevStartAngle !== undefined && opts.prevEndAngle !== undefined) { 8456 fromStartAngle = opts.prevEndAngle; 8457 prevAngle = opts.prevEndAngle - opts.prevStartAngle; 8458 } 8459 8460 if (opts.i === w.config.series.length - 1) { 8461 // some adjustments for the last overlapping paths 8462 if (angle + toStartAngle > this.fullAngle) { 8463 opts.endAngle = opts.endAngle - (angle + toStartAngle); 8464 } else if (angle + toStartAngle < this.fullAngle) { 8465 opts.endAngle = opts.endAngle + (this.fullAngle - (angle + toStartAngle)); 8466 } 8467 } 8468 8469 if (angle === this.fullAngle) angle = this.fullAngle - 0.01; 8470 me.animateArc(el, fromStartAngle, toStartAngle, angle, prevAngle, opts); 8471 } 8472 }, { 8473 key: "animateArc", 8474 value: function animateArc(el, fromStartAngle, toStartAngle, angle, prevAngle, opts) { 8475 var me = this; 8476 var w = this.w; 8477 var size = me.size; 8478 8479 if (!size) { 8480 size = opts.size; 8481 } 8482 8483 var path; 8484 8485 if (isNaN(fromStartAngle) || isNaN(prevAngle)) { 8486 fromStartAngle = toStartAngle; 8487 prevAngle = angle; 8488 opts.dur = 0; 8489 } 8490 8491 var currAngle = angle; 8492 var startAngle = toStartAngle; 8493 var fromAngle = fromStartAngle - toStartAngle; 8494 8495 if (w.globals.dataChanged && opts.shouldSetPrevPaths) { 8496 // to avoid flickering, set prev path first and then we will animate from there 8497 path = me.getPiePath({ 8498 me: me, 8499 startAngle: startAngle, 8500 angle: prevAngle, 8501 size: size 8502 }); 8503 el.attr({ 8504 d: path 8505 }); 8506 } 8507 8508 if (opts.dur !== 0) { 8509 el.animate(opts.dur, w.globals.easing, opts.animBeginArr[opts.i]).afterAll(function () { 8510 if (w.config.chart.type === 'pie' || w.config.chart.type === 'donut') { 8511 this.animate(300).attr({ 8512 'stroke-width': w.config.stroke.width 8513 }); 8514 } 8515 8516 w.globals.animationEnded = true; 8517 }).during(function (pos) { 8518 currAngle = fromAngle + (angle - fromAngle) * pos; 8519 8520 if (opts.animateStartingPos) { 8521 currAngle = prevAngle + (angle - prevAngle) * pos; 8522 startAngle = fromStartAngle - prevAngle + (toStartAngle - (fromStartAngle - prevAngle)) * pos; 8523 } 8524 8525 path = me.getPiePath({ 8526 me: me, 8527 startAngle: startAngle, 8528 angle: currAngle, 8529 size: size 8530 }); 8531 el.node.setAttribute('data:pathOrig', path); 8532 el.attr({ 8533 d: path 8534 }); 8535 }); 8536 } else { 8537 path = me.getPiePath({ 8538 me: me, 8539 startAngle: startAngle, 8540 angle: angle, 8541 size: size 8542 }); 8543 8544 if (!opts.isTrack) { 8545 w.globals.animationEnded = true; 8546 } 8547 8548 el.node.setAttribute('data:pathOrig', path); 8549 el.attr({ 8550 d: path 8551 }); 8552 } 8553 } 8554 }, { 8555 key: "pieClicked", 8556 value: function pieClicked(i) { 8557 var w = this.w; 8558 var me = this; 8559 var path; 8560 var size = me.size + 4; 8561 var elPath = w.globals.dom.Paper.select("#apexcharts-".concat(w.config.chart.type.toLowerCase(), "-slice-").concat(i)).members[0]; 8562 var pathFrom = elPath.attr('d'); 8563 8564 if (elPath.attr('data:pieClicked') === 'true') { 8565 elPath.attr({ 8566 'data:pieClicked': 'false' 8567 }); 8568 this.revertDataLabelsInner(elPath.node, this.donutDataLabels); 8569 var origPath = elPath.attr('data:pathOrig'); 8570 elPath.attr({ 8571 d: origPath 8572 }); 8573 return; 8574 } else { 8575 // reset all elems 8576 var allEls = w.globals.dom.baseEl.querySelectorAll('.apexcharts-pie-area'); 8577 Array.prototype.forEach.call(allEls, function (pieSlice) { 8578 pieSlice.setAttribute('data:pieClicked', 'false'); 8579 var origPath = pieSlice.getAttribute('data:pathOrig'); 8580 pieSlice.setAttribute('d', origPath); 8581 }); 8582 elPath.attr('data:pieClicked', 'true'); 8583 } 8584 8585 var startAngle = parseInt(elPath.attr('data:startAngle'));
8586 var angle = parseInt(elPath.attr('data:angle')); 8587 path = me.getPiePath({ 8588 me: me, 8589 startAngle: startAngle, 8590 angle: angle, 8591 size: size 8592 }); 8593 if (angle === 360) return; 8594 elPath.plot(path).animate(1).plot(pathFrom).animate(100).plot(path); 8595 } 8596 }, { 8597 key: "getChangedPath", 8598 value: function getChangedPath(prevStartAngle, prevEndAngle) { 8599 var path = ''; 8600 8601 if (this.dynamicAnim && this.w.globals.dataChanged) { 8602 path = this.getPiePath({ 8603 me: this, 8604 startAngle: prevStartAngle, 8605 angle: prevEndAngle - prevStartAngle, 8606 size: this.size 8607 }); 8608 } 8609 8610 return path; 8611 } 8612 }, { 8613 key: "getPiePath", 8614 value: function getPiePath(_ref) { 8615 var me = _ref.me, 8616 startAngle = _ref.startAngle, 8617 angle = _ref.angle, 8618 size = _ref.size; 8619 var w = this.w; 8620 var path; 8621 var startDeg = startAngle; 8622 var startRadians = Math.PI * (startDeg - 90) / 180; 8623 var endDeg = angle + startAngle; 8624 if (Math.ceil(endDeg) >= 360) endDeg = 359.99; 8625 var endRadians = Math.PI * (endDeg - 90) / 180; 8626 var x1 = me.centerX + size * Math.cos(startRadians); 8627 var y1 = me.centerY + size * Math.sin(startRadians); 8628 var x2 = me.centerX + size * Math.cos(endRadians); 8629 var y2 = me.centerY + size * Math.sin(endRadians); 8630 var startInner = Utils.polarToCartesian(me.centerX, me.centerY, me.donutSize, endDeg); 8631 var endInner = Utils.polarToCartesian(me.centerX, me.centerY, me.donutSize, startDeg); 8632 var largeArc = angle > 180 ? 1 : 0; 8633 8634 if (w.config.chart.type === 'donut') { 8635 path = ['M', x1, y1, 'A', size, size, 0, largeArc, 1, x2, y2, 'L', startInner.x, startInner.y, 'A', me.donutSize, me.donutSize, 0, largeArc, 0, endInner.x, endInner.y, 'L', x1, y1, 'z'].join(' '); 8636 } else if (w.config.chart.type === 'pie') { 8637 path = ['M', x1, y1, 'A', size, size, 0, largeArc, 1, x2, y2, 'L', me.centerX, me.centerY, 'L', x1, y1].join(' '); 8638 } else { 8639 path = ['M', x1, y1, 'A', size, size, 0, largeArc, 1, x2, y2].join(' '); 8640 } 8641 8642 return path; 8643 } 8644 }, { 8645 key: "renderInnerDataLabels", 8646 value: function renderInnerDataLabels(dataLabelsConfig, opts) { 8647 var w = this.w; 8648 var graphics = new Graphics(this.ctx); 8649 var g = graphics.group({ 8650 class: 'apexcharts-datalabels-group', 8651 transform: "translate(".concat(opts.translateX ? opts.translateX : 0, ", ").concat(opts.translateY ? opts.translateY : 0, ")") 8652 }); 8653 var showTotal = dataLabelsConfig.total.show; 8654 g.node.style.opacity = opts.opacity; 8655 var x = opts.centerX; 8656 var y = opts.centerY; 8657 var labelColor, valueColor; 8658 8659 if (dataLabelsConfig.name.color === undefined) { 8660 labelColor = w.globals.colors[0]; 8661 } else { 8662 labelColor = dataLabelsConfig.name.color; 8663 } 8664 8665 if (dataLabelsConfig.value.color === undefined) { 8666 valueColor = w.config.chart.foreColor; 8667 } else { 8668 valueColor = dataLabelsConfig.value.color; 8669 } 8670 8671 var lbFormatter = dataLabelsConfig.value.formatter; 8672 var val = ''; 8673 var name = ''; 8674 8675 if (showTotal) { 8676 labelColor = dataLabelsConfig.total.color; 8677 name = dataLabelsConfig.total.label; 8678 val = dataLabelsConfig.total.formatter(w); 8679 } else { 8680 if (w.globals.series.length === 1) { 8681 val = lbFormatter(w.globals.series[0], w); 8682 name = w.globals.seriesNames[0]; 8683 } 8684 } 8685 8686 if (dataLabelsConfig.name.show) { 8687 var elLabel = graphics.drawText({ 8688 x: x, 8689 y: y + parseInt(dataLabelsConfig.name.offsetY), 8690 text: name, 8691 textAnchor: 'middle', 8692 foreColor: labelColor, 8693 fontSize: dataLabelsConfig.name.fontSize, 8694 fontFamily: dataLabelsConfig.name.fontFamily 8695 }); 8696 elLabel.node.classList.add('apexcharts-datalabel-label'); 8697 g.add(elLabel); 8698 } 8699 8700 if (dataLabelsConfig.value.show) { 8701 var valOffset = dataLabelsConfig.name.show ? parseInt(dataLabelsConfig.value.offsetY) + 16 : dataLabelsConfig.value.offsetY; 8702 var elValue = graphics.drawText({ 8703 x: x, 8704 y: y + valOffset, 8705 text: val, 8706 textAnchor: 'middle', 8707 foreColor: valueColor, 8708 fontSize: dataLabelsConfig.value.fontSize, 8709 fontFamily: dataLabelsConfig.value.fontFamily 8710 }); 8711 elValue.node.classList.add('apexcharts-datalabel-value'); 8712 g.add(elValue); 8713 } // for a multi-series circle chart, we need to show total value instead of first series labels 8714 8715 8716 return g; 8717 } 8718 /** 8719 * 8720 * @param {string} name - The name of the series 8721 * @param {string} val - The value of that series 8722 * @param {object} el - Optional el (indicates which series was hovered/clicked). If this param is not present, means we need to show total 8723 */ 8724 8725 }, { 8726 key: "printInnerLabels", 8727 value: function printInnerLabels(labelsConfig, name, val, el) { 8728 var w = this.w; 8729 var labelColor; 8730 8731 if (el) { 8732 if (labelsConfig.name.color === undefined) { 8733 labelColor = w.globals.colors[parseInt(el.parentNode.getAttribute('rel')) - 1]; 8734 } else { 8735 labelColor = labelsConfig.name.color; 8736 } 8737 } else { 8738 if (w.globals.series.length > 1 && labelsConfig.total.show) { 8739 labelColor = labelsConfig.total.color; 8740 } 8741 } 8742 8743 var elLabel = w.globals.dom.baseEl.querySelector('.apexcharts-datalabel-label'); 8744 var elValue = w.globals.dom.baseEl.querySelector('.apexcharts-datalabel-value'); 8745 var lbFormatter = labelsConfig.value.formatter; 8746 val = lbFormatter(val, w); // we need to show Total Val - so get the formatter of it 8747 8748 if (!el && typeof labelsConfig.total.formatter === 'function') { 8749 val = labelsConfig.total.formatter(w); 8750 } 8751 8752 if (elLabel !== null) { 8753 elLabel.textContent = name; 8754 } 8755 8756 if (elValue !== null) { 8757 elValue.textContent = val; 8758 } 8759 8760 if (elLabel !== null) { 8761 elLabel.style.fill = labelColor; 8762 } 8763 } 8764 }, { 8765 key: "printDataLabelsInner", 8766 value: function printDataLabelsInner(el, dataLabelsConfig) { 8767 var w = this.w; 8768 var val = el.getAttribute('data:value'); 8769 var name = w.globals.seriesNames[parseInt(el.parentNode.getAttribute('rel')) - 1]; 8770 8771 if (w.globals.series.length > 1) { 8772 this.printInnerLabels(dataLabelsConfig, name, val, el); 8773 } 8774 8775 var dataLabelsGroup = w.globals.dom.baseEl.querySelector('.apexcharts-datalabels-group'); 8776 8777 if (dataLabelsGroup !== null) { 8778 dataLabelsGroup.style.opacity = 1; 8779 } 8780 } 8781 }, { 8782 key: "revertDataLabelsInner", 8783 value: function revertDataLabelsInner(el, dataLabelsConfig, event) { 8784 var _this = this; 8785 8786 var w = this.w; 8787 var dataLabelsGroup = w.globals.dom.baseEl.querySelector('.apexcharts-datalabels-group'); 8788 8789 if (dataLabelsConfig.total.show && w.globals.series.length > 1) { 8790 var pie = new Pie(this.ctx); 8791 pie.printInnerLabels(dataLabelsConfig, dataLabelsConfig.total.label, dataLabelsConfig.total.formatter(w)); 8792 } else { 8793 var slices = document.querySelectorAll(".apexcharts-pie-area"); 8794 var sliceOut = false;
8795 slices.forEach(function (s) { 8796 if (s.getAttribute('data:pieClicked') === 'true') { 8797 sliceOut = true; 8798 8799 _this.printDataLabelsInner(s, dataLabelsConfig); 8800 } 8801 }); 8802 8803 if (!sliceOut) { 8804 if (w.globals.selectedDataPoints.length && w.globals.series.length > 1) { 8805 if (w.globals.selectedDataPoints[0].length > 0) { 8806 var index = w.globals.selectedDataPoints[0]; 8807 8808 var _el = w.globals.dom.baseEl.querySelector("#apexcharts-".concat(w.config.chart.type.toLowerCase(), "-slice-").concat(index)); 8809 8810 this.printDataLabelsInner(_el, dataLabelsConfig); 8811 } else if (dataLabelsGroup && w.globals.selectedDataPoints.length && w.globals.selectedDataPoints[0].length === 0) { 8812 dataLabelsGroup.style.opacity = 0; 8813 } 8814 } else { 8815 if (dataLabelsGroup && w.globals.series.length > 1) { 8816 dataLabelsGroup.style.opacity = 0; 8817 } 8818 } 8819 } 8820 } 8821 } 8822 }]); 8823 8824 return Pie; 8825 }(); 8826 8827 /** 8828 * ApexCharts Radar Class for Spider/Radar Charts. 8829 * @module Radar 8830 **/ 8831 8832 var Radar = 8833 /*#__PURE__*/ 8834 function () { 8835 function Radar(ctx) { 8836 _classCallCheck(this, Radar); 8837 8838 this.ctx = ctx; 8839 this.w = ctx.w; 8840 this.chartType = this.w.config.chart.type; 8841 this.initialAnim = this.w.config.chart.animations.enabled; 8842 this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled; 8843 this.animDur = 0; 8844 var w = this.w; 8845 this.graphics = new Graphics(this.ctx); 8846 this.lineColorArr = w.globals.stroke.colors !== undefined ? w.globals.stroke.colors : w.globals.colors; 8847 this.defaultSize = w.globals.svgHeight < w.globals.svgWidth ? w.globals.svgHeight - 35 : w.globals.gridWidth; 8848 this.maxValue = this.w.globals.maxY; 8849 this.polygons = w.config.plotOptions.radar.polygons; 8850 this.maxLabelWidth = 20; 8851 var longestLabel = w.globals.labels.slice().sort(function (a, b) { 8852 return b.length - a.length; 8853 })[0]; 8854 var labelWidth = this.graphics.getTextRects(longestLabel, w.config.dataLabels.style.fontSize); 8855 this.size = this.defaultSize / 2.1 - w.config.stroke.width - w.config.chart.dropShadow.blur - labelWidth.width / 1.75; 8856 8857 if (w.config.plotOptions.radar.size !== undefined) { 8858 this.size = w.config.plotOptions.radar.size; 8859 } 8860 8861 this.dataRadiusOfPercent = []; 8862 this.dataRadius = []; 8863 this.angleArr = []; 8864 this.yaxisLabelsTextsPos = []; 8865 } 8866 8867 _createClass(Radar, [{ 8868 key: "draw", 8869 value: function draw(series) { 8870 var _this = this; 8871 8872 var w = this.w; 8873 var fill = new Fill(this.ctx); 8874 var allSeries = []; 8875 this.dataPointsLen = series[w.globals.maxValsInArrayIndex].length; 8876 this.disAngle = Math.PI * 2 / this.dataPointsLen; 8877 var halfW = w.globals.gridWidth / 2; 8878 var halfH = w.globals.gridHeight / 2; 8879 var translateX = halfW; 8880 var translateY = halfH; 8881 var ret = this.graphics.group({ 8882 class: 'apexcharts-radar-series', 8883 'data:innerTranslateX': translateX, 8884 'data:innerTranslateY': translateY - 25, 8885 transform: "translate(".concat(translateX || 0, ", ").concat(translateY || 0, ")") 8886 }); 8887 var dataPointsPos = []; 8888 var elPointsMain = null; 8889 this.yaxisLabels = this.graphics.group({ 8890 class: 'apexcharts-yaxis' 8891 }); 8892 series.forEach(function (s, i) { 8893 // el to which series will be drawn 8894 var elSeries = _this.graphics.group().attr({ 8895 class: "apexcharts-series", 8896 seriesName: Utils.escapeString(w.globals.seriesNames[i]), 8897 rel: i + 1, 8898 'data:realIndex': i 8899 }); 8900 8901 _this.dataRadiusOfPercent[i] = []; 8902 _this.dataRadius[i] = []; 8903 _this.angleArr[i] = [];
8904 s.forEach(function (dv, j) { 8905 _this.dataRadiusOfPercent[i][j] = dv / _this.maxValue; 8906 _this.dataRadius[i][j] = _this.dataRadiusOfPercent[i][j] * _this.size; 8907 _this.angleArr[i][j] = j * _this.disAngle; 8908 }); 8909 dataPointsPos = _this.getDataPointsPos(_this.dataRadius[i], _this.angleArr[i]); 8910 8911 var paths = _this.createPaths(dataPointsPos, { 8912 x: 0, 8913 y: 0 8914 }); // points 8915 8916 8917 elPointsMain = _this.graphics.group({ 8918 class: 'apexcharts-series-markers-wrap hidden' 8919 }); 8920 w.globals.delayedElements.push({ 8921 el: elPointsMain.node, 8922 index: i 8923 }); 8924 var defaultRenderedPathOptions = { 8925 i: i, 8926 realIndex: i, 8927 animationDelay: i, 8928 initialSpeed: w.config.chart.animations.speed, 8929 dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed, 8930 className: "apexcharts-radar", 8931 id: "apexcharts-radar", 8932 shouldClipToGrid: false, 8933 bindEventsOnPaths: false, 8934 stroke: w.globals.stroke.colors[i], 8935 strokeLineCap: w.config.stroke.lineCap 8936 }; 8937 var pathFrom = null; 8938 8939 if (w.globals.previousPaths.length > 0) { 8940 pathFrom = _this.getPathFrom(i); 8941 } 8942 8943 for (var p = 0; p < paths.linePathsTo.length; p++) { 8944 var renderedLinePath = _this.graphics.renderPaths(_objectSpread({}, defaultRenderedPathOptions, { 8945 pathFrom: pathFrom === null ? paths.linePathsFrom[p] : pathFrom, 8946 pathTo: paths.linePathsTo[p], 8947 strokeWidth: Array.isArray(w.config.stroke.width) ? w.config.stroke.width[i] : w.config.stroke.width, 8948 fill: 'none', 8949 drawShadow: false 8950 })); 8951 8952 elSeries.add(renderedLinePath); 8953 var pathFill = fill.fillPath({ 8954 seriesNumber: i 8955 }); 8956 8957 var renderedAreaPath = _this.graphics.renderPaths(_objectSpread({}, defaultRenderedPathOptions, { 8958 pathFrom: pathFrom === null ? paths.areaPathsFrom[p] : pathFrom, 8959 pathTo: paths.areaPathsTo[p], 8960 strokeWidth: 0, 8961 fill: pathFill, 8962 drawShadow: false 8963 })); 8964 8965 if (w.config.chart.dropShadow.enabled) { 8966 var filters = new Filters(_this.ctx); 8967 var shadow = w.config.chart.dropShadow; 8968 filters.dropShadow(renderedAreaPath, Object.assign({}, shadow, { 8969 noUserSpaceOnUse: true 8970 }), i); 8971 } 8972 8973 elSeries.add(renderedAreaPath); 8974 } 8975 8976 s.forEach(function (sj, j) { 8977 var markers = new Markers(_this.ctx); 8978 var opts = markers.getMarkerConfig('apexcharts-marker', i); 8979 8980 var point = _this.graphics.drawMarker(dataPointsPos[j].x, dataPointsPos[j].y, opts); 8981 8982 point.attr('rel', j); 8983 point.attr('j', j); 8984 point.attr('index', i); 8985 point.node.setAttribute('default-marker-size', opts.pSize); 8986 8987 var elPointsWrap = _this.graphics.group({ 8988 class: 'apexcharts-series-markers' 8989 }); 8990 8991 if (elPointsWrap) { 8992 elPointsWrap.add(point); 8993 } 8994 8995 elPointsMain.add(elPointsWrap); 8996 elSeries.add(elPointsMain); 8997 }); 8998 allSeries.push(elSeries); 8999 }); 9000 this.drawPolygons({ 9001 parent: ret 9002 }); 9003 9004 if (w.config.dataLabels.enabled) { 9005 var dataLabels = this.drawLabels(); 9006 ret.add(dataLabels); 9007 } 9008 9009 ret.add(this.yaxisLabels); 9010 allSeries.forEach(function (elS) { 9011 ret.add(elS); 9012 }); 9013 return ret; 9014 } 9015 }, { 9016 key: "drawPolygons", 9017 value: function drawPolygons(opts) { 9018 var _this2 = this; 9019 9020 var w = this.w; 9021 var parent = opts.parent; 9022 var yaxisTexts = w.globals.yAxisScale[0].result.reverse(); 9023 var layers = yaxisTexts.length; 9024 var radiusSizes = []; 9025 var layerDis = this.size / (layers - 1); 9026 9027 for (var i = 0; i < layers; i++) { 9028 radiusSizes[i] = layerDis * i; 9029 } 9030 9031 radiusSizes.reverse(); 9032 var polygonStrings = []; 9033 var lines = [];
9034 radiusSizes.forEach(function (radiusSize, r) { 9035 var polygon = _this2.getPolygonPos(radiusSize); 9036 9037 var string = ''; 9038 polygon.forEach(function (p, i) { 9039 if (r === 0) { 9040 var line = _this2.graphics.drawLine(p.x, p.y, 0, 0, Array.isArray(_this2.polygons.connectorColors) ? _this2.polygons.connectorColors[i] : _this2.polygons.connectorColors); 9041 9042 lines.push(line); 9043 } 9044 9045 if (i === 0) { 9046 _this2.yaxisLabelsTextsPos.push({ 9047 x: p.x, 9048 y: p.y 9049 }); 9050 } 9051 9052 string += p.x + ',' + p.y + ' '; 9053 }); 9054 polygonStrings.push(string); 9055 }); 9056 polygonStrings.forEach(function (p, i) { 9057 var strokeColors = _this2.polygons.strokeColors; 9058 9059 var polygon = _this2.graphics.drawPolygon(p, Array.isArray(strokeColors) ? strokeColors[i] : strokeColors, w.globals.radarPolygons.fill.colors[i]); 9060 9061 parent.add(polygon); 9062 }); 9063 lines.forEach(function (l) { 9064 parent.add(l); 9065 }); 9066 9067 if (w.config.yaxis[0].show) { 9068 this.yaxisLabelsTextsPos.forEach(function (p, i) { 9069 var yText = _this2.drawYAxisText(p.x, p.y, i, yaxisTexts[i]); 9070 9071 _this2.yaxisLabels.add(yText); 9072 }); 9073 } 9074 } 9075 }, { 9076 key: "drawYAxisText", 9077 value: function drawYAxisText(x, y, i, text) { 9078 var w = this.w; 9079 var yaxisConfig = w.config.yaxis[0]; 9080 var formatter = w.globals.yLabelFormatters[0]; 9081 var yaxisLabel = this.graphics.drawText({ 9082 x: x + yaxisConfig.labels.offsetX, 9083 y: y + yaxisConfig.labels.offsetY, 9084 text: formatter(text, i), 9085 textAnchor: 'middle', 9086 fontSize: yaxisConfig.labels.style.fontSize, 9087 fontFamily: yaxisConfig.labels.style.fontFamily, 9088 foreColor: yaxisConfig.labels.style.color 9089 }); 9090 return yaxisLabel; 9091 } 9092 }, { 9093 key: "drawLabels", 9094 value: function drawLabels() { 9095 var _this3 = this; 9096 9097 var w = this.w; 9098 var limit = 10; 9099 var textAnchor = 'middle'; 9100 var dataLabelsConfig = w.config.dataLabels; 9101 var elDataLabelsWrap = this.graphics.group({ 9102 class: 'apexcharts-datalabels' 9103 }); 9104 var polygonPos = this.getPolygonPos(this.size); 9105 var currPosX = 0; 9106 var currPosY = 0; 9107 w.globals.labels.forEach(function (label, i) { 9108 var formatter = dataLabelsConfig.formatter; 9109 var dataLabels = new DataLabels(_this3.ctx); 9110 9111 if (polygonPos[i]) { 9112 currPosX = polygonPos[i].x; 9113 currPosY = polygonPos[i].y; 9114 9115 if (Math.abs(polygonPos[i].x) >= limit) { 9116 if (polygonPos[i].x > 0) { 9117 textAnchor = 'start'; 9118 currPosX += 10; 9119 } else if (polygonPos[i].x < 0) { 9120 textAnchor = 'end'; 9121 currPosX -= 10; 9122 } 9123 } else { 9124 textAnchor = 'middle'; 9125 } 9126 9127 if (Math.abs(polygonPos[i].y) >= _this3.size - limit) { 9128 if (polygonPos[i].y < 0) { 9129 currPosY -= 10; 9130 } else if (polygonPos[i].y > 0) { 9131 currPosY += 10; 9132 } 9133 } 9134 9135 var text = formatter(label, { 9136 seriesIndex: -1, 9137 dataPointIndex: i, 9138 w: w 9139 }); 9140 dataLabels.plotDataLabelsText({ 9141 x: currPosX, 9142 y: currPosY, 9143 text: text, 9144 textAnchor: textAnchor, 9145 i: i, 9146 j: i, 9147 parent: elDataLabelsWrap, 9148 dataLabelsConfig: dataLabelsConfig, 9149 offsetCorrection: false 9150 }); 9151 } 9152 }); 9153 return elDataLabelsWrap; 9154 } 9155 }, { 9156 key: "createPaths", 9157 value: function createPaths(pos, origin) { 9158 var _this4 = this; 9159 9160 var linePathsTo = []; 9161 var linePathsFrom = []; 9162 var areaPathsTo = []; 9163 var areaPathsFrom = []; 9164 9165 if (pos.length) { 9166 linePathsFrom = [this.graphics.move(origin.x, origin.y)]; 9167 areaPathsFrom = [this.graphics.move(origin.x, origin.y)]; 9168 var linePathTo = this.graphics.move(pos[0].x, pos[0].y); 9169 var areaPathTo = this.graphics.move(pos[0].x, pos[0].y); 9170 pos.forEach(function (p, i) { 9171 linePathTo += _this4.graphics.line(p.x, p.y); 9172 areaPathTo += _this4.graphics.line(p.x, p.y); 9173 9174 if (i === pos.length - 1) { 9175 linePathTo += 'Z'; 9176 areaPathTo += 'Z'; 9177 } 9178 }); 9179 linePathsTo.push(linePathTo); 9180 areaPathsTo.push(areaPathTo); 9181 } 9182 9183 return { 9184 linePathsFrom: linePathsFrom, 9185 linePathsTo: linePathsTo, 9186 areaPathsFrom: areaPathsFrom, 9187 areaPathsTo: areaPathsTo 9188 }; 9189 } 9190 }, { 9191 key: "getPathFrom", 9192 value: function getPathFrom(realIndex) { 9193 var w = this.w; 9194 var pathFrom = null; 9195 9196 for (var pp = 0; pp < w.globals.previousPaths.length; pp++) { 9197 var gpp = w.globals.previousPaths[pp]; 9198 9199 if (gpp.paths.length > 0 && parseInt(gpp.realIndex) === parseInt(realIndex)) { 9200 if (typeof w.globals.previousPaths[pp].paths[0] !== 'undefined') { 9201 pathFrom = w.globals.previousPaths[pp].paths[0].d; 9202 } 9203 } 9204 } 9205 9206 return pathFrom; 9207 } 9208 }, { 9209 key: "getDataPointsPos", 9210 value: function getDataPointsPos(dataRadiusArr, angleArr) { 9211 var dataPointsLen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.dataPointsLen; 9212 dataRadiusArr = dataRadiusArr || []; 9213 angleArr = angleArr || []; 9214 var dataPointsPosArray = []; 9215 9216 for (var j = 0; j < dataPointsLen; j++) { 9217 var curPointPos = {}; 9218 curPointPos.x = dataRadiusArr[j] * Math.sin(angleArr[j]); 9219 curPointPos.y = -dataRadiusArr[j] * Math.cos(angleArr[j]); 9220 dataPointsPosArray.push(curPointPos); 9221 } 9222 9223 return dataPointsPosArray; 9224 } 9225 }, { 9226 key: "getPolygonPos", 9227 value: function getPolygonPos(size) { 9228 var dotsArray = []; 9229 var angle = Math.PI * 2 / this.dataPointsLen; 9230 9231 for (var i = 0; i < this.dataPointsLen; i++) { 9232 var curPos = {}; 9233 curPos.x = size * Math.sin(i * angle); 9234 curPos.y = -size * Math.cos(i * angle); 9235 dotsArray.push(curPos); 9236 } 9237 9238 return dotsArray; 9239 } 9240 }]); 9241 9242 return Radar; 9243 }(); 9244 9245 /** 9246 * ApexCharts Radial Class for drawing Circle / Semi Circle Charts. 9247 * @module Radial 9248 **/ 9249 9250 var Radial = 9251 /*#__PURE__*/ 9252 function (_Pie) { 9253 _inherits(Radial, _Pie); 9254 9255 function Radial(ctx) { 9256 var _this; 9257 9258 _classCallCheck(this, Radial); 9259 9260 _this = _possibleConstructorReturn(this, _getPrototypeOf(Radial).call(this, ctx)); 9261 _this.ctx = ctx; 9262 _this.w = ctx.w; 9263 _this.animBeginArr = [0]; 9264 _this.animDur = 0; 9265 var w = _this.w; 9266 _this.startAngle = w.config.plotOptions.radialBar.startAngle; 9267 _this.endAngle = w.config.plotOptions.radialBar.endAngle; 9268 _this.trackStartAngle = w.config.plotOptions.radialBar.track.startAngle; 9269 _this.trackEndAngle = w.config.plotOptions.radialBar.track.endAngle; 9270 _this.radialDataLabels = w.config.plotOptions.radialBar.dataLabels; 9271 if (!_this.trackStartAngle) _this.trackStartAngle = _this.startAngle; 9272 if (!_this.trackEndAngle) _this.trackEndAngle = _this.endAngle; 9273 if (_this.endAngle === 360) _this.endAngle = 359.99; 9274 _this.fullAngle = 360 - w.config.plotOptions.radialBar.endAngle - w.config.plotOptions.radialBar.startAngle; 9275 _this.margin = parseInt(w.config.plotOptions.radialBar.track.margin); 9276 return _this; 9277 } 9278 9279 _createClass(Radial, [{ 9280 key: "draw", 9281 value: function draw(series) { 9282 var w = this.w; 9283 var graphics = new Graphics(this.ctx); 9284 var ret = graphics.group({ 9285 class: 'apexcharts-radialbar' 9286 }); 9287 var elSeries = graphics.group(); 9288 var centerY = this.defaultSize / 2; 9289 var centerX = w.globals.gridWidth / 2; 9290 var size = this.defaultSize / 2.05 - w.config.stroke.width - w.config.chart.dropShadow.blur; 9291 9292 if (w.config.plotOptions.radialBar.size !== undefined) { 9293 size = w.config.plotOptions.radialBar.size; 9294 } 9295 9296 var colorArr = w.globals.fill.colors; 9297 9298 if (w.config.plotOptions.radialBar.track.show) { 9299 var elTracks = this.drawTracks({ 9300 size: size, 9301 centerX: centerX, 9302 centerY: centerY, 9303 colorArr: colorArr, 9304 series: series 9305 }); 9306 elSeries.add(elTracks); 9307 } 9308 9309 var elG = this.drawArcs({ 9310 size: size, 9311 centerX: centerX, 9312 centerY: centerY, 9313 colorArr: colorArr, 9314 series: series 9315 }); 9316 elSeries.add(elG.g); 9317 9318 if (w.config.plotOptions.radialBar.hollow.position === 'front') { 9319 elG.g.add(elG.elHollow);
9320 9321 if (elG.dataLabels) { 9322 elG.g.add(elG.dataLabels); 9323 } 9324 } 9325 9326 ret.add(elSeries); 9327 return ret; 9328 } 9329 }, { 9330 key: "drawTracks", 9331 value: function drawTracks(opts) { 9332 var w = this.w; 9333 var graphics = new Graphics(this.ctx); 9334 var g = graphics.group(); 9335 var filters = new Filters(this.ctx); 9336 var fill = new Fill(this.ctx); 9337 var strokeWidth = this.getStrokeWidth(opts); 9338 opts.size = opts.size - strokeWidth / 2; 9339 9340 for (var i = 0; i < opts.series.length; i++) { 9341 var elRadialBarTrack = graphics.group({ 9342 class: 'apexcharts-radialbar-track apexcharts-track' 9343 }); 9344 g.add(elRadialBarTrack); 9345 elRadialBarTrack.attr({ 9346 id: 'apexcharts-track-' + i, 9347 rel: i + 1 9348 }); 9349 opts.size = opts.size - strokeWidth - this.margin; 9350 var trackConfig = w.config.plotOptions.radialBar.track; 9351 var pathFill = fill.fillPath({ 9352 seriesNumber: 0, 9353 size: opts.size, 9354 fillColors: Array.isArray(trackConfig.background) ? trackConfig.background[i] : trackConfig.background, 9355 solid: true 9356 }); 9357 var startAngle = this.trackStartAngle; 9358 var endAngle = this.trackEndAngle; 9359 if (Math.abs(endAngle) + Math.abs(startAngle) >= 360) endAngle = 360 - Math.abs(this.startAngle) - 0.1; 9360 var elPath = graphics.drawPath({ 9361 d: '', 9362 stroke: pathFill, 9363 strokeWidth: strokeWidth * parseInt(trackConfig.strokeWidth) / 100, 9364 fill: 'none', 9365 strokeOpacity: trackConfig.opacity, 9366 classes: 'apexcharts-radialbar-area' 9367 }); 9368 9369 if (trackConfig.dropShadow.enabled) { 9370 var shadow = trackConfig.dropShadow; 9371 filters.dropShadow(elPath, shadow); 9372 } 9373 9374 elRadialBarTrack.add(elPath); 9375 elPath.attr('id', 'apexcharts-radialbarTrack-' + i); 9376 var pie = new Pie(this.ctx); 9377 pie.animatePaths(elPath, { 9378 centerX: opts.centerX, 9379 centerY: opts.centerY, 9380 endAngle: endAngle, 9381 startAngle: startAngle, 9382 size: opts.size, 9383 i: i, 9384 totalItems: 2, 9385 animBeginArr: 0, 9386 dur: 0, 9387 isTrack: true, 9388 easing: w.globals.easing 9389 }); 9390 } 9391 9392 return g; 9393 } 9394 }, { 9395 key: "drawArcs", 9396 value: function drawArcs(opts) { 9397 var w = this.w; // size, donutSize, centerX, centerY, colorArr, lineColorArr, sectorAngleArr, series 9398 9399 var graphics = new Graphics(this.ctx); 9400 var fill = new Fill(this.ctx); 9401 var filters = new Filters(this.ctx); 9402 var g = graphics.group(); 9403 var strokeWidth = this.getStrokeWidth(opts); 9404 opts.size = opts.size - strokeWidth / 2; 9405 var hollowFillID = w.config.plotOptions.radialBar.hollow.background; 9406 var hollowSize = opts.size - strokeWidth * opts.series.length - this.margin * opts.series.length - strokeWidth * parseInt(w.config.plotOptions.radialBar.track.strokeWidth) / 100 / 2; 9407 var hollowRadius = hollowSize - w.config.plotOptions.radialBar.hollow.margin; 9408 9409 if (w.config.plotOptions.radialBar.hollow.image !== undefined) { 9410 hollowFillID = this.drawHollowImage(opts, g, hollowSize, hollowFillID); 9411 } 9412 9413 var elHollow = this.drawHollow({ 9414 size: hollowRadius, 9415 centerX: opts.centerX, 9416 centerY: opts.centerY, 9417 fill: hollowFillID 9418 }); 9419 9420 if (w.config.plotOptions.radialBar.hollow.dropShadow.enabled) { 9421 var shadow = w.config.plotOptions.radialBar.hollow.dropShadow; 9422 filters.dropShadow(elHollow, shadow); 9423 } 9424 9425 var shown = 1; 9426 9427 if (!this.radialDataLabels.total.show && w.globals.series.length > 1) { 9428 shown = 0; 9429 } 9430 9431 var pie = new Pie(this.ctx); 9432 var dataLabels = null; 9433 9434 if (this.radialDataLabels.show) { 9435 dataLabels = pie.renderInnerDataLabels(this.radialDataLabels, { 9436 hollowSize: hollowSize, 9437 centerX: opts.centerX, 9438 centerY: opts.centerY, 9439 opacity: shown 9440 }); 9441 } 9442 9443 if (w.config.plotOptions.radialBar.hollow.position === 'back') { 9444 g.add(elHollow);
9445 9446 if (dataLabels) { 9447 g.add(dataLabels); 9448 } 9449 } 9450 9451 var reverseLoop = false; 9452 9453 if (w.config.plotOptions.radialBar.inverseOrder) { 9454 reverseLoop = true; 9455 } 9456 9457 for (var i = reverseLoop ? opts.series.length - 1 : 0; reverseLoop ? i >= 0 : i < opts.series.length; reverseLoop ? i-- : i++) { 9458 var elRadialBarArc = graphics.group({ 9459 class: "apexcharts-series apexcharts-radial-series", 9460 seriesName: Utils.escapeString(w.globals.seriesNames[i]) 9461 }); 9462 g.add(elRadialBarArc); 9463 elRadialBarArc.attr({ 9464 id: 'apexcharts-series-' + i, 9465 rel: i + 1 9466 }); 9467 this.ctx.series.addCollapsedClassToSeries(elRadialBarArc, i); 9468 opts.size = opts.size - strokeWidth - this.margin; 9469 var pathFill = fill.fillPath({ 9470 seriesNumber: i, 9471 size: opts.size, 9472 value: opts.series[i] 9473 }); 9474 var startAngle = this.startAngle; 9475 var prevStartAngle = void 0; 9476 var totalAngle = Math.abs(w.config.plotOptions.radialBar.endAngle - w.config.plotOptions.radialBar.startAngle); // if data exceeds 100, make it 100 9477 9478 var dataValue = Utils.negToZero(opts.series[i] > 100 ? 100 : opts.series[i]) / 100; 9479 var endAngle = Math.round(totalAngle * dataValue) + this.startAngle; 9480 var prevEndAngle = void 0; 9481 9482 if (w.globals.dataChanged) { 9483 prevStartAngle = this.startAngle; 9484 prevEndAngle = Math.round(totalAngle * Utils.negToZero(w.globals.previousPaths[i]) / 100) + prevStartAngle; 9485 } 9486 9487 var currFullAngle = Math.abs(endAngle) + Math.abs(startAngle); 9488 9489 if (currFullAngle >= 360) { 9490 endAngle = endAngle - 0.01; 9491 } 9492 9493 var prevFullAngle = Math.abs(prevEndAngle) + Math.abs(prevStartAngle); 9494 9495 if (prevFullAngle >= 360) { 9496 prevEndAngle = prevEndAngle - 0.01; 9497 } 9498 9499 var angle = endAngle - startAngle; 9500 var dashArray = Array.isArray(w.config.stroke.dashArray) ? w.config.stroke.dashArray[i] : w.config.stroke.dashArray; 9501 var elPath = graphics.drawPath({ 9502 d: '', 9503 stroke: pathFill, 9504 strokeWidth: strokeWidth, 9505 fill: 'none', 9506 fillOpacity: w.config.fill.opacity, 9507 classes: 'apexcharts-radialbar-area', 9508 strokeDashArray: dashArray 9509 }); 9510 Graphics.setAttrs(elPath.node, { 9511 'data:angle': angle, 9512 'data:value': opts.series[i] 9513 }); 9514 9515 if (w.config.chart.dropShadow.enabled) { 9516 var _shadow = w.config.chart.dropShadow; 9517 filters.dropShadow(elPath, _shadow, i); 9518 } 9519 9520 this.addListeners(elPath, this.radialDataLabels); 9521 9522 var _pie = new Pie(this.ctx); 9523 9524 elRadialBarArc.add(elPath); 9525 elPath.attr({ 9526 id: 'apexcharts-radialbar-slice-' + i, 9527 index: 0, 9528 j: i 9529 }); 9530 var dur = 0; 9531 9532 if (_pie.initialAnim && !w.globals.resized && !w.globals.dataChanged) { 9533 dur = (endAngle - startAngle) / 360 * w.config.chart.animations.speed; 9534 this.animDur = dur / (opts.series.length * 1.2) + this.animDur; 9535 this.animBeginArr.push(this.animDur); 9536 } 9537 9538 if (w.globals.dataChanged) { 9539 dur = (endAngle - startAngle) / 360 * w.config.chart.animations.dynamicAnimation.speed; 9540 this.animDur = dur / (opts.series.length * 1.2) + this.animDur; 9541 this.animBeginArr.push(this.animDur); 9542 } 9543 9544 _pie.animatePaths(elPath, { 9545 centerX: opts.centerX, 9546 centerY: opts.centerY, 9547 endAngle: endAngle, 9548 startAngle: startAngle, 9549 prevEndAngle: prevEndAngle, 9550 prevStartAngle: prevStartAngle, 9551 size: opts.size, 9552 i: i, 9553 totalItems: 2, 9554 animBeginArr: this.animBeginArr, 9555 dur: dur, 9556 shouldSetPrevPaths: true, 9557 easing: w.globals.easing 9558 }); 9559 } 9560 9561 return { 9562 g: g, 9563 elHollow: elHollow, 9564 dataLabels: dataLabels 9565 }; 9566 } 9567 }, { 9568 key: "drawHollow", 9569 value: function drawHollow(opts) { 9570 var graphics = new Graphics(this.ctx); 9571 var circle = graphics.drawCircle(opts.size * 2); 9572 circle.attr({ 9573 class: 'apexcharts-radialbar-hollow', 9574 cx: opts.centerX, 9575 cy: opts.centerY, 9576 r: opts.size, 9577 fill: opts.fill 9578 });
9579 return circle; 9580 } 9581 }, { 9582 key: "drawHollowImage", 9583 value: function drawHollowImage(opts, g, hollowSize, hollowFillID) { 9584 var w = this.w; 9585 var fill = new Fill(this.ctx); 9586 var randID = (Math.random() + 1).toString(36).substring(4); 9587 var hollowFillImg = w.config.plotOptions.radialBar.hollow.image; 9588 9589 if (w.config.plotOptions.radialBar.hollow.imageClipped) { 9590 fill.clippedImgArea({ 9591 width: hollowSize, 9592 height: hollowSize, 9593 image: hollowFillImg, 9594 patternID: "pattern".concat(w.globals.cuid).concat(randID) 9595 }); 9596 hollowFillID = "url(#pattern".concat(w.globals.cuid).concat(randID, ")"); 9597 } else { 9598 var imgWidth = w.config.plotOptions.radialBar.hollow.imageWidth; 9599 var imgHeight = w.config.plotOptions.radialBar.hollow.imageHeight; 9600 9601 if (imgWidth === undefined && imgHeight === undefined) { 9602 var image = w.globals.dom.Paper.image(hollowFillImg).loaded(function (loader) { 9603 this.move(opts.centerX - loader.width / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetX, opts.centerY - loader.height / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetY); 9604 }); 9605 g.add(image); 9606 } else { 9607 var _image = w.globals.dom.Paper.image(hollowFillImg).loaded(function (loader) { 9608 this.move(opts.centerX - imgWidth / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetX, opts.centerY - imgHeight / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetY); 9609 this.size(imgWidth, imgHeight); 9610 }); 9611 9612 g.add(_image); 9613 } 9614 } 9615 9616 return hollowFillID; 9617 } 9618 }, { 9619 key: "getStrokeWidth", 9620 value: function getStrokeWidth(opts) { 9621 var w = this.w; 9622 return opts.size * (100 - parseInt(w.config.plotOptions.radialBar.hollow.size)) / 100 / (opts.series.length + 1) - this.margin; 9623 } 9624 }]); 9625 9626 return Radial; 9627 }(Pie); 9628 9629 /** 9630 * ApexCharts RangeBar Class responsible for drawing Range/Timeline Bars. 9631 * 9632 * @module RangeBar 9633 **/ 9634 9635 var RangeBar = 9636 /*#__PURE__*/ 9637 function (_Bar) { 9638 _inherits(RangeBar, _Bar); 9639 9640 function RangeBar() { 9641 _classCallCheck(this, RangeBar); 9642 9643 return _possibleConstructorReturn(this, _getPrototypeOf(RangeBar).apply(this, arguments)); 9644 } 9645 9646 _createClass(RangeBar, [{ 9647 key: "draw", 9648 value: function draw(series, seriesIndex) { 9649 var w = this.w; 9650 var graphics = new Graphics(this.ctx); 9651 var fill = new Fill(this.ctx); 9652 this.rangeBarOptions = this.w.config.plotOptions.rangeBar; 9653 this.series = series; 9654 this.seriesRangeStart = w.globals.seriesRangeStart; 9655 this.seriesRangeEnd = w.globals.seriesRangeEnd; 9656 this.initVariables(series); 9657 var ret = graphics.group({ 9658 class: 'apexcharts-rangebar-series apexcharts-plot-series' 9659 }); 9660 9661 for (var i = 0, bc = 0; i < series.length; i++, bc++) { 9662 var pathTo = void 0, 9663 pathFrom = void 0; 9664 var x = void 0, 9665 y = void 0, 9666 xDivision = void 0, 9667 // xDivision is the GRIDWIDTH divided by number of datapoints (columns) 9668 yDivision = void 0, 9669 // yDivision is the GRIDHEIGHT divided by number of datapoints (bars) 9670 zeroH = void 0, 9671 // zeroH is the baseline where 0 meets y axis 9672 zeroW = void 0; // zeroW is the baseline where 0 meets x axis 9673 9674 var yArrj = []; // hold y values of current iterating series 9675 9676 var xArrj = []; // hold x values of current iterating series 9677 9678 var realIndex = w.globals.comboCharts ? seriesIndex[i] : i; // el to which series will be drawn 9679 9680 var elSeries = graphics.group({ 9681 class: "apexcharts-series", 9682 seriesName: Utils.escapeString(w.globals.seriesNames[realIndex]), 9683 rel: i + 1, 9684 'data:realIndex': realIndex 9685 }); 9686 9687 if (series[i].length > 0) { 9688 this.visibleI = this.visibleI + 1; 9689 } 9690 9691 var strokeWidth = 0; 9692 var barHeight = 0; 9693 var barWidth = 0; 9694 9695 if (this.yRatio.length > 1) { 9696 this.yaxisIndex = realIndex; 9697 } 9698 9699 var initPositions = this.initialPositions(); 9700 y = initPositions.y;
9701 yDivision = initPositions.yDivision; 9702 barHeight = initPositions.barHeight; 9703 zeroW = initPositions.zeroW; 9704 x = initPositions.x; 9705 barWidth = initPositions.barWidth; 9706 xDivision = initPositions.xDivision; 9707 zeroH = initPositions.zeroH; 9708 xArrj.push(x + barWidth / 2); // eldatalabels 9709 9710 var elDataLabelsWrap = graphics.group({ 9711 class: 'apexcharts-datalabels' 9712 }); 9713 9714 for (var j = 0, tj = w.globals.dataPoints; j < w.globals.dataPoints; j++, tj--) { 9715 if (typeof this.series[i][j] === 'undefined' || series[i][j] === null) { 9716 this.isNullValue = true; 9717 } else { 9718 this.isNullValue = false; 9719 } 9720 9721 if (w.config.stroke.show) { 9722 if (this.isNullValue) { 9723 strokeWidth = 0; 9724 } else { 9725 strokeWidth = Array.isArray(this.strokeWidth) ? this.strokeWidth[realIndex] : this.strokeWidth; 9726 } 9727 } 9728 9729 var paths = null; 9730 9731 if (this.isHorizontal) { 9732 paths = this.drawRangeBarPaths({ 9733 indexes: { 9734 i: i, 9735 j: j, 9736 realIndex: realIndex, 9737 bc: bc 9738 }, 9739 barHeight: barHeight, 9740 strokeWidth: strokeWidth, 9741 pathTo: pathTo, 9742 pathFrom: pathFrom, 9743 zeroW: zeroW, 9744 x: x, 9745 y: y, 9746 yDivision: yDivision, 9747 elSeries: elSeries 9748 }); 9749 barWidth = paths.barWidth; 9750 } else { 9751 paths = this.drawRangeColumnPaths({ 9752 indexes: { 9753 i: i, 9754 j: j, 9755 realIndex: realIndex, 9756 bc: bc 9757 }, 9758 x: x, 9759 y: y, 9760 xDivision: xDivision, 9761 pathTo: pathTo, 9762 pathFrom: pathFrom, 9763 barWidth: barWidth, 9764 zeroH: zeroH, 9765 strokeWidth: strokeWidth, 9766 elSeries: elSeries 9767 }); 9768 barHeight = paths.barHeight; 9769 } 9770 9771 pathTo = paths.pathTo; 9772 pathFrom = paths.pathFrom; 9773 y = paths.y; 9774 x = paths.x; // push current X 9775 9776 if (j > 0) { 9777 xArrj.push(x + barWidth / 2); 9778 } 9779 9780 yArrj.push(y); 9781 var pathFill = fill.fillPath({ 9782 seriesNumber: realIndex 9783 }); 9784 var lineFill = w.globals.stroke.colors[realIndex]; 9785 elSeries = this.renderSeries({ 9786 realIndex: realIndex, 9787 pathFill: pathFill, 9788 lineFill: lineFill, 9789 j: j, 9790 i: i, 9791 pathFrom: pathFrom, 9792 pathTo: pathTo, 9793 strokeWidth: strokeWidth, 9794 elSeries: elSeries, 9795 x: x, 9796 y: y, 9797 series: series, 9798 barHeight: barHeight, 9799 barWidth: barWidth, 9800 elDataLabelsWrap: elDataLabelsWrap, 9801 visibleSeries: this.visibleI, 9802 type: 'rangebar' 9803 }); 9804 } // push all x val arrays into main xArr 9805 9806 9807 w.globals.seriesXvalues[realIndex] = xArrj; 9808 w.globals.seriesYvalues[realIndex] = yArrj; 9809 ret.add(elSeries); 9810 } 9811 9812 return ret; 9813 } 9814 }, { 9815 key: "drawRangeColumnPaths", 9816 value: function drawRangeColumnPaths(_ref) { 9817 var indexes = _ref.indexes, 9818 x = _ref.x, 9819 y = _ref.y, 9820 strokeWidth = _ref.strokeWidth, 9821 xDivision = _ref.xDivision, 9822 pathTo = _ref.pathTo, 9823 pathFrom = _ref.pathFrom, 9824 barWidth = _ref.barWidth, 9825 zeroH = _ref.zeroH; 9826 var w = this.w; 9827 var graphics = new Graphics(this.ctx); 9828 var i = indexes.i; 9829 var j = indexes.j; 9830 var yRatio = this.yRatio[this.yaxisIndex]; 9831 var realIndex = indexes.realIndex; 9832 var range = this.getRangeValue(realIndex, j); 9833 var y1 = Math.min(range.start, range.end); 9834 var y2 = Math.max(range.start, range.end); 9835 9836 if (w.globals.isXNumeric) { 9837 x = (w.globals.seriesX[i][j] - w.globals.minX) / this.xRatio - barWidth / 2; 9838 } 9839 9840 var barXPosition = x + barWidth * this.visibleI; 9841 9842 if (typeof this.series[i][j] === 'undefined' || this.series[i][j] === null) { 9843 y1 = zeroH; 9844 } else { 9845 y1 = zeroH - y1 / yRatio; 9846 y2 = zeroH - y2 / yRatio; 9847 } 9848 9849 var barHeight = Math.abs(y2 - y1); 9850 pathTo = graphics.move(barXPosition, zeroH); 9851 pathFrom = graphics.move(barXPosition, y1);
9852 9853 if (w.globals.previousPaths.length > 0) { 9854 pathFrom = this.getPathFrom(realIndex, j, true); 9855 } 9856 9857 pathTo = graphics.move(barXPosition, y2) + graphics.line(barXPosition + barWidth, y2) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition, y1) + graphics.line(barXPosition, y2 - strokeWidth / 2); 9858 pathFrom = pathFrom + graphics.move(barXPosition, y1) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition, y1); 9859 9860 if (!w.globals.isXNumeric) { 9861 x = x + xDivision; 9862 } 9863 9864 return { 9865 pathTo: pathTo, 9866 pathFrom: pathFrom, 9867 barHeight: barHeight, 9868 x: x, 9869 y: y2, 9870 barXPosition: barXPosition 9871 }; 9872 } 9873 }, { 9874 key: "drawRangeBarPaths", 9875 value: function drawRangeBarPaths(_ref2) { 9876 var indexes = _ref2.indexes, 9877 x = _ref2.x, 9878 y = _ref2.y, 9879 yDivision = _ref2.yDivision, 9880 pathTo = _ref2.pathTo, 9881 pathFrom = _ref2.pathFrom, 9882 barHeight = _ref2.barHeight, 9883 zeroW = _ref2.zeroW; 9884 var w = this.w; 9885 var graphics = new Graphics(this.ctx); 9886 var i = indexes.i; 9887 var j = indexes.j; 9888 var realIndex = indexes.realIndex; 9889 var x1 = zeroW; 9890 var x2 = zeroW; 9891 9892 if (w.globals.isXNumeric) { 9893 y = (w.globals.seriesX[i][j] - w.globals.minX) / this.invertedXRatio - barHeight; 9894 } 9895 9896 var barYPosition = y + barHeight * this.visibleI; 9897 9898 if (typeof this.series[i][j] !== 'undefined' && this.series[i][j] !== null) { 9899 x1 = zeroW + this.seriesRangeStart[i][j] / this.invertedYRatio; 9900 x2 = zeroW + this.seriesRangeEnd[i][j] / this.invertedYRatio; 9901 } 9902 9903 pathTo = graphics.move(zeroW, barYPosition); 9904 pathFrom = graphics.move(zeroW, barYPosition); 9905 9906 if (w.globals.previousPaths.length > 0) { 9907 pathFrom = this.getPathFrom(realIndex, j); 9908 } 9909 9910 var barWidth = Math.abs(x2 - x1); 9911 pathTo = graphics.move(x1, barYPosition) + graphics.line(x2, barYPosition) + graphics.line(x2, barYPosition + barHeight) + graphics.line(x1, barYPosition + barHeight) + graphics.line(x1, barYPosition); 9912 pathFrom = pathFrom + graphics.line(x1, barYPosition) + graphics.line(x1, barYPosition + barHeight) + graphics.line(x1, barYPosition + barHeight) + graphics.line(x1, barYPosition); 9913 9914 if (!w.globals.isXNumeric) { 9915 y = y + yDivision; 9916 } 9917 9918 return { 9919 pathTo: pathTo, 9920 pathFrom: pathFrom, 9921 barWidth: barWidth, 9922 x: x2, 9923 y: y, 9924 barYPosition: barYPosition 9925 }; 9926 } 9927 }, { 9928 key: "getRangeValue", 9929 value: function getRangeValue(i, j) { 9930 var w = this.w; 9931 return { 9932 start: w.globals.seriesRangeStart[i][j], 9933 end: w.globals.seriesRangeEnd[i][j] 9934 }; 9935 } 9936 }]); 9937 9938 return RangeBar; 9939 }(Bar); 9940 9941 /** 9942 * ApexCharts Line Class responsible for drawing Line / Area Charts. 9943 * This class is also responsible for generating values for Bubble/Scatter charts, so need to rename it to Axis Charts to avoid confusions 9944 * @module Line 9945 **/ 9946 9947 var Line = 9948 /*#__PURE__*/ 9949 function () { 9950 function Line(ctx, xyRatios, isPointsChart) { 9951 _classCallCheck(this, Line); 9952 9953 this.ctx = ctx; 9954 this.w = ctx.w; 9955 this.xyRatios = xyRatios; 9956 this.pointsChart = !(this.w.config.chart.type !== 'bubble' && this.w.config.chart.type !== 'scatter') || isPointsChart; 9957 this.scatter = new Scatter(this.ctx); 9958 this.noNegatives = this.w.globals.minX === Number.MAX_VALUE; 9959 this.yaxisIndex = 0; 9960 } 9961 9962 _createClass(Line, [{ 9963 key: "draw", 9964 value: function draw(series, ptype, seriesIndex) { 9965 var w = this.w; 9966 var graphics = new Graphics(this.ctx); 9967 var fill = new Fill(this.ctx); 9968 var type = w.globals.comboCharts ? ptype : w.config.chart.type; 9969 var ret = graphics.group({ 9970 class: "apexcharts-".concat(type, "-series apexcharts-plot-series") 9971 }); 9972 var coreUtils = new CoreUtils(this.ctx, w);
9973 series = coreUtils.getLogSeries(series); 9974 var yRatio = this.xyRatios.yRatio; 9975 yRatio = coreUtils.getLogYRatios(yRatio); 9976 var zRatio = this.xyRatios.zRatio; 9977 var xRatio = this.xyRatios.xRatio; 9978 var baseLineY = this.xyRatios.baseLineY; // push all series in an array, so we can draw in reverse order (for stacked charts) 9979 9980 var allSeries = []; 9981 var prevSeriesY = []; 9982 var categoryAxisCorrection = 0; 9983 9984 for (var i = 0; i < series.length; i++) { 9985 // width divided into equal parts 9986 if (type === 'line' && (w.config.fill.type === 'gradient' || w.config.fill.type[i] === 'gradient')) { 9987 // a small adjustment to allow gradient line to draw correctly for all same values 9988 9989 /* #fix https://github.com/apexcharts/apexcharts.js/issues/358 */ 9990 if (coreUtils.seriesHaveSameValues(i)) { 9991 var gSeries = series[i].slice(); 9992 gSeries[gSeries.length - 1] = gSeries[gSeries.length - 1] + 0.000001; 9993 series[i] = gSeries; 9994 } 9995 } 9996 9997 var xDivision = w.globals.gridWidth / w.globals.dataPoints; 9998 var realIndex = w.globals.comboCharts ? seriesIndex[i] : i; 9999 10000 if (yRatio.length > 1) { 10001 this.yaxisIndex = realIndex; 10002 } 10003 10004 this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed; 10005 var yArrj = []; // hold y values of current iterating series 10006 10007 var xArrj = []; // hold x values of current iterating series 10008 // zeroY is the 0 value in y series which can be used in negative charts 10009 10010 var zeroY = w.globals.gridHeight - baseLineY[this.yaxisIndex] - (this.isReversed ? w.globals.gridHeight : 0) + (this.isReversed ? baseLineY[this.yaxisIndex] * 2 : 0); 10011 var areaBottomY = zeroY; 10012 10013 if (zeroY > w.globals.gridHeight) { 10014 areaBottomY = w.globals.gridHeight; 10015 } 10016 10017 categoryAxisCorrection = xDivision / 2; 10018 var x = w.globals.padHorizontal + categoryAxisCorrection; 10019 var y = 1; 10020 10021 if (w.globals.isXNumeric && w.globals.seriesX.length > 0) { 10022 x = (w.globals.seriesX[realIndex][0] - w.globals.minX) / xRatio; 10023 } 10024 10025 xArrj.push(x); 10026 var linePath = void 0, 10027 areaPath = void 0, 10028 pathFromLine = void 0, 10029 pathFromArea = void 0; 10030 var linePaths = []; 10031 var areaPaths = []; // el to which series will be drawn 10032 10033 var elSeries = graphics.group({ 10034 class: "apexcharts-series", 10035 seriesName: Utils.escapeString(w.globals.seriesNames[realIndex]) 10036 }); // points 10037 10038 var elPointsMain = graphics.group({ 10039 class: 'apexcharts-series-markers-wrap' 10040 }); // eldatalabels 10041 10042 var elDataLabelsWrap = graphics.group({ 10043 class: 'apexcharts-datalabels' 10044 }); 10045 this.ctx.series.addCollapsedClassToSeries(elSeries, realIndex); 10046 var longestSeries = series[i].length === w.globals.dataPoints; 10047 elSeries.attr({ 10048 'data:longestSeries': longestSeries, 10049 rel: i + 1, 10050 'data:realIndex': realIndex 10051 }); 10052 this.appendPathFrom = true; 10053 var pX = x; 10054 var pY = void 0; 10055 var prevX = pX; 10056 var prevY = zeroY; // w.globals.svgHeight; 10057 10058 var lineYPosition = 0; // the first value in the current series is not null or undefined 10059 10060 var firstPrevY = this.determineFirstPrevY({ 10061 i: i, 10062 series: series, 10063 yRatio: yRatio[this.yaxisIndex], 10064 zeroY: zeroY, 10065 prevY: prevY, 10066 prevSeriesY: prevSeriesY, 10067 lineYPosition: lineYPosition 10068 }); 10069 prevY = firstPrevY.prevY; 10070 yArrj.push(prevY); 10071 pY = prevY; 10072 10073 if (series[i][0] === null) { 10074 // when the first value itself is null, we need to move the pointer to a location where a null value is not found 10075 for (var s = 0; s < series[i].length; s++) { 10076 if (series[i][s] !== null) { 10077 prevX = xDivision * s; 10078 prevY = zeroY - series[i][s] / yRatio[this.yaxisIndex]; 10079 linePath = graphics.move(prevX, prevY); 10080 areaPath = graphics.move(prevX, areaBottomY); 10081 break; 10082 } 10083 } 10084 } else { 10085 linePath = graphics.move(prevX, prevY); 10086 areaPath = graphics.move(prevX, areaBottomY) + graphics.line(prevX, prevY); 10087 } 10088 10089 pathFromLine = graphics.move(-1, zeroY) + graphics.line(-1, zeroY); 10090 pathFromArea = graphics.move(-1, zeroY) + graphics.line(-1, zeroY); 10091 10092 if (w.globals.previousPaths.length > 0) { 10093 var pathFrom = this.checkPreviousPaths({ 10094 pathFromLine: pathFromLine, 10095 pathFromArea: pathFromArea, 10096 realIndex: realIndex 10097 }); 10098 pathFromLine = pathFrom.pathFromLine; 10099 pathFromArea = pathFrom.pathFromArea; 10100 } 10101 10102 var iterations = w.globals.dataPoints > 1 ? w.globals.dataPoints - 1 : w.globals.dataPoints; 10103 10104 for (var j = 0; j < iterations; j++) { 10105 if (w.globals.isXNumeric) { 10106 var sX = w.globals.seriesX[realIndex][j + 1];
10107 10108 if (typeof w.globals.seriesX[realIndex][j + 1] === 'undefined') { 10109 /* fix #374 */ 10110 sX = w.globals.seriesX[realIndex][iterations - 1]; 10111 } 10112 10113 x = (sX - w.globals.minX) / xRatio; 10114 } else { 10115 x = x + xDivision; 10116 } 10117 10118 var minY = Utils.isNumber(w.globals.minYArr[realIndex]) ? w.globals.minYArr[realIndex] : w.globals.minY; 10119 10120 if (w.config.chart.stacked) { 10121 if (i > 0 && w.globals.collapsedSeries.length < w.config.series.length - 1) { 10122 lineYPosition = prevSeriesY[i - 1][j + 1]; 10123 } else { 10124 // the first series will not have prevY values 10125 lineYPosition = zeroY; 10126 } 10127 10128 if (typeof series[i][j + 1] === 'undefined' || series[i][j + 1] === null) { 10129 y = lineYPosition - minY / yRatio[this.yaxisIndex] + (this.isReversed ? minY / yRatio[this.yaxisIndex] : 0) * 2; 10130 } else { 10131 y = lineYPosition - series[i][j + 1] / yRatio[this.yaxisIndex] + (this.isReversed ? series[i][j + 1] / yRatio[this.yaxisIndex] : 0) * 2; 10132 } 10133 } else { 10134 if (typeof series[i][j + 1] === 'undefined' || series[i][j + 1] === null) { 10135 y = zeroY - minY / yRatio[this.yaxisIndex] + (this.isReversed ? minY / yRatio[this.yaxisIndex] : 0) * 2; 10136 } else { 10137 y = zeroY - series[i][j + 1] / yRatio[this.yaxisIndex] + (this.isReversed ? series[i][j + 1] / yRatio[this.yaxisIndex] : 0) * 2; 10138 } 10139 } // push current X 10140 10141 10142 xArrj.push(x); // push current Y that will be used as next series's bottom position 10143 10144 yArrj.push(y); 10145 var calculatedPaths = this.createPaths({ 10146 series: series, 10147 i: i, 10148 j: j, 10149 x: x, 10150 y: y, 10151 xDivision: xDivision, 10152 pX: pX, 10153 pY: pY, 10154 areaBottomY: areaBottomY, 10155 linePath: linePath, 10156 areaPath: areaPath, 10157 linePaths: linePaths, 10158 areaPaths: areaPaths, 10159 seriesIndex: seriesIndex 10160 }); 10161 areaPaths = calculatedPaths.areaPaths; 10162 linePaths = calculatedPaths.linePaths; 10163 pX = calculatedPaths.pX; 10164 pY = calculatedPaths.pY; 10165 areaPath = calculatedPaths.areaPath; 10166 linePath = calculatedPaths.linePath; 10167 10168 if (this.appendPathFrom) { 10169 pathFromLine = pathFromLine + graphics.line(x, zeroY); 10170 pathFromArea = pathFromArea + graphics.line(x, zeroY); 10171 } 10172 10173 var pointsPos = this.calculatePoints({ 10174 series: series, 10175 x: x, 10176 y: y, 10177 realIndex: realIndex, 10178 i: i, 10179 j: j, 10180 prevY: prevY, 10181 categoryAxisCorrection: categoryAxisCorrection, 10182 xRatio: xRatio 10183 }); 10184 10185 if (!this.pointsChart) { 10186 var markers = new Markers(this.ctx); 10187 10188 if (w.globals.dataPoints > 1) { 10189 elPointsMain.node.classList.add('hidden'); 10190 } 10191 10192 var elPointsWrap = markers.plotChartMarkers(pointsPos, realIndex, j + 1); 10193 10194 if (elPointsWrap !== null) { 10195 elPointsMain.add(elPointsWrap); 10196 } 10197 } else { 10198 // scatter / bubble chart points creation 10199 this.scatter.draw(elSeries, j, { 10200 realIndex: realIndex, 10201 pointsPos: pointsPos, 10202 zRatio: zRatio, 10203 elParent: elPointsMain 10204 }); 10205 } 10206 10207 var dataLabelAlign = !series[i][j + 1] || series[i][j + 1] > series[i][j] ? 'top' : 'bottom'; 10208 var dataLabels = new DataLabels(this.ctx); 10209 var drawnLabels = dataLabels.drawDataLabel(pointsPos, realIndex, j + 1, null, dataLabelAlign); 10210 10211 if (drawnLabels !== null) { 10212 elDataLabelsWrap.add(drawnLabels); 10213 } 10214 } // push all current y values array to main PrevY Array 10215 10216 10217 prevSeriesY.push(yArrj); // push all x val arrays into main xArr 10218 10219 w.globals.seriesXvalues[realIndex] = xArrj; 10220 w.globals.seriesYvalues[realIndex] = yArrj; // these elements will be shown after area path animation completes 10221 10222 if (!this.pointsChart) { 10223 w.globals.delayedElements.push({ 10224 el: elPointsMain.node, 10225 index: realIndex 10226 }); 10227 } 10228 10229 var defaultRenderedPathOptions = { 10230 i: i, 10231 realIndex: realIndex, 10232 animationDelay: i, 10233 initialSpeed: w.config.chart.animations.speed, 10234 dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed, 10235 className: "apexcharts-".concat(type), 10236 id: "apexcharts-".concat(type) 10237 }; 10238 10239 if (type === 'area') { 10240 var pathFill = fill.fillPath({ 10241 seriesNumber: realIndex 10242 }); 10243 10244 for (var p = 0; p < areaPaths.length; p++) { 10245 var renderedPath = graphics.renderPaths(_objectSpread({}, defaultRenderedPathOptions, { 10246 pathFrom: pathFromArea, 10247 pathTo: areaPaths[p],
10248 stroke: 'none', 10249 strokeWidth: 0, 10250 strokeLineCap: null, 10251 fill: pathFill 10252 })); 10253 elSeries.add(renderedPath); 10254 } 10255 } 10256 10257 if (w.config.stroke.show && !this.pointsChart) { 10258 var lineFill = null; 10259 10260 if (type === 'line') { 10261 // fillable lines only for lineChart 10262 lineFill = fill.fillPath({ 10263 seriesNumber: realIndex, 10264 i: i 10265 }); 10266 } else { 10267 lineFill = w.globals.stroke.colors[realIndex]; 10268 } 10269 10270 for (var _p = 0; _p < linePaths.length; _p++) { 10271 var _renderedPath = graphics.renderPaths(_objectSpread({}, defaultRenderedPathOptions, { 10272 pathFrom: pathFromLine, 10273 pathTo: linePaths[_p], 10274 stroke: lineFill, 10275 strokeWidth: Array.isArray(w.config.stroke.width) ? w.config.stroke.width[realIndex] : w.config.stroke.width, 10276 strokeLineCap: w.config.stroke.lineCap, 10277 fill: 'none' 10278 })); 10279 10280 elSeries.add(_renderedPath); 10281 } 10282 } 10283 10284 elSeries.add(elPointsMain); 10285 elSeries.add(elDataLabelsWrap); 10286 allSeries.push(elSeries); 10287 } 10288 10289 for (var _s = allSeries.length; _s > 0; _s--) { 10290 ret.add(allSeries[_s - 1]); 10291 } 10292 10293 return ret; 10294 } 10295 }, { 10296 key: "createPaths", 10297 value: function createPaths(_ref) { 10298 var series = _ref.series, 10299 i = _ref.i, 10300 j = _ref.j, 10301 x = _ref.x, 10302 y = _ref.y, 10303 pX = _ref.pX, 10304 pY = _ref.pY, 10305 xDivision = _ref.xDivision, 10306 areaBottomY = _ref.areaBottomY, 10307 linePath = _ref.linePath, 10308 areaPath = _ref.areaPath, 10309 linePaths = _ref.linePaths, 10310 areaPaths = _ref.areaPaths, 10311 seriesIndex = _ref.seriesIndex; 10312 var w = this.w; 10313 var graphics = new Graphics(this.ctx); 10314 var curve = w.config.stroke.curve; 10315 10316 if (Array.isArray(w.config.stroke.curve)) { 10317 if (Array.isArray(seriesIndex)) { 10318 curve = w.config.stroke.curve[seriesIndex[i]]; 10319 } else { 10320 curve = w.config.stroke.curve[i]; 10321 } 10322 } // logic of smooth curve derived from chartist 10323 // CREDITS: https://gionkunz.github.io/chartist-js/ 10324 10325 10326 if (curve === 'smooth') { 10327 var length = (x - pX) * 0.35; 10328 10329 if (w.globals.hasNullValues) { 10330 if (series[i][j] !== null) { 10331 if (series[i][j + 1] !== null) { 10332 linePath = graphics.move(pX, pY) + graphics.curve(pX + length, pY, x - length, y, x + 1, y); 10333 areaPath = graphics.move(pX + 1, pY) + graphics.curve(pX + length, pY, x - length, y, x + 1, y) + graphics.line(x, areaBottomY) + graphics.line(pX, areaBottomY) + 'z'; 10334 } else { 10335 linePath = graphics.move(pX, pY); 10336 areaPath = graphics.move(pX, pY) + 'z'; 10337 } 10338 } 10339 10340 linePaths.push(linePath); 10341 areaPaths.push(areaPath); 10342 } else { 10343 linePath = linePath + graphics.curve(pX + length, pY, x - length, y, x, y); 10344 areaPath = areaPath + graphics.curve(pX + length, pY, x - length, y, x, y); 10345 } 10346 10347 pX = x; 10348 pY = y; 10349 10350 if (j === series[i].length - 2) { 10351 // last loop, close path 10352 areaPath = areaPath + graphics.curve(pX, pY, x, y, x, areaBottomY) + graphics.move(x, y) + 'z'; 10353 10354 if (!w.globals.hasNullValues) { 10355 linePaths.push(linePath); 10356 areaPaths.push(areaPath); 10357 } 10358 } 10359 } else { 10360 if (series[i][j + 1] === null) { 10361 linePath = linePath + graphics.move(x, y); 10362 areaPath = areaPath + graphics.line(x - xDivision, areaBottomY) + graphics.move(x, y); 10363 } 10364 10365 if (series[i][j] === null) { 10366 linePath = linePath + graphics.move(x, y); 10367 areaPath = areaPath + graphics.move(x, areaBottomY); 10368 } 10369 10370 if (curve === 'stepline') { 10371 linePath = linePath + graphics.line(x, null, 'H') + graphics.line(null, y, 'V'); 10372 areaPath = areaPath + graphics.line(x, null, 'H') + graphics.line(null, y, 'V'); 10373 } else if (curve === 'straight') { 10374 linePath = linePath + graphics.line(x, y); 10375 areaPath = areaPath + graphics.line(x, y); 10376 } 10377 10378 if (j === series[i].length - 2) { 10379 // last loop, close path 10380 areaPath = areaPath + graphics.line(x, areaBottomY) + graphics.move(x, y) + 'z'; 10381 linePaths.push(linePath); 10382 areaPaths.push(areaPath); 10383 } 10384 } 10385 10386 return { 10387 linePaths: linePaths, 10388 areaPaths: areaPaths, 10389 pX: pX, 10390 pY: pY, 10391 linePath: linePath, 10392 areaPath: areaPath 10393 }; 10394 } 10395 }, { 10396 key: "calculatePoints", 10397 value: function calculatePoints(_ref2) { 10398 var series = _ref2.series, 10399 realIndex = _ref2.realIndex, 10400 x = _ref2.x, 10401 y = _ref2.y, 10402 i = _ref2.i, 10403 j = _ref2.j, 10404 prevY = _ref2.prevY, 10405 categoryAxisCorrection = _ref2.categoryAxisCorrection, 10406 xRatio = _ref2.xRatio; 10407 var w = this.w; 10408 var ptX = []; 10409 var ptY = []; 10410 10411 if (j === 0) { 10412 var xPT1st = categoryAxisCorrection + w.config.markers.offsetX; // the first point for line series
10413 // we need to check whether it's not a time series, because a time series may 10414 // start from the middle of the x axis 10415 10416 if (w.globals.isXNumeric) { 10417 xPT1st = (w.globals.seriesX[realIndex][0] - w.globals.minX) / xRatio + w.config.markers.offsetX; 10418 } // push 2 points for the first data values 10419 10420 10421 ptX.push(xPT1st); 10422 ptY.push(Utils.isNumber(series[i][0]) ? prevY + w.config.markers.offsetY : null); 10423 ptX.push(x + w.config.markers.offsetX); 10424 ptY.push(Utils.isNumber(series[i][j + 1]) ? y + w.config.markers.offsetY : null); 10425 } else { 10426 ptX.push(x + w.config.markers.offsetX); 10427 ptY.push(Utils.isNumber(series[i][j + 1]) ? y + w.config.markers.offsetY : null); 10428 } 10429 10430 var pointsPos = { 10431 x: ptX, 10432 y: ptY 10433 }; 10434 return pointsPos; 10435 } 10436 }, { 10437 key: "checkPreviousPaths", 10438 value: function checkPreviousPaths(_ref3) { 10439 var pathFromLine = _ref3.pathFromLine, 10440 pathFromArea = _ref3.pathFromArea, 10441 realIndex = _ref3.realIndex; 10442 var w = this.w; 10443 10444 for (var pp = 0; pp < w.globals.previousPaths.length; pp++) { 10445 var gpp = w.globals.previousPaths[pp]; 10446 10447 if ((gpp.type === 'line' || gpp.type === 'area') && gpp.paths.length > 0 && parseInt(gpp.realIndex) === parseInt(realIndex)) { 10448 if (gpp.type === 'line') { 10449 this.appendPathFrom = false; 10450 pathFromLine = w.globals.previousPaths[pp].paths[0].d; 10451 } else if (gpp.type === 'area') { 10452 this.appendPathFrom = false; 10453 pathFromArea = w.globals.previousPaths[pp].paths[0].d; 10454 10455 if (w.config.stroke.show) { 10456 pathFromLine = w.globals.previousPaths[pp].paths[1].d; 10457 } 10458 } 10459 } 10460 } 10461 10462 return { 10463 pathFromLine: pathFromLine, 10464 pathFromArea: pathFromArea 10465 }; 10466 } 10467 }, { 10468 key: "determineFirstPrevY", 10469 value: function determineFirstPrevY(_ref4) { 10470 var i = _ref4.i, 10471 series = _ref4.series, 10472 yRatio = _ref4.yRatio, 10473 zeroY = _ref4.zeroY, 10474 prevY = _ref4.prevY, 10475 prevSeriesY = _ref4.prevSeriesY, 10476 lineYPosition = _ref4.lineYPosition; 10477 var w = this.w; 10478 10479 if (typeof series[i][0] !== 'undefined') { 10480 if (w.config.chart.stacked) { 10481 if (i > 0) { 10482 // 1st y value of previous series 10483 lineYPosition = prevSeriesY[i - 1][0]; 10484 } else { 10485 // the first series will not have prevY values 10486 lineYPosition = zeroY; 10487 } 10488 10489 prevY = lineYPosition - series[i][0] / yRatio + (this.isReversed ? series[i][0] / yRatio : 0) * 2; 10490 } else { 10491 prevY = zeroY - series[i][0] / yRatio + (this.isReversed ? series[i][0] / yRatio : 0) * 2; 10492 } 10493 } else { 10494 // the first value in the current series is null 10495 if (w.config.chart.stacked && i > 0 && typeof series[i][0] === 'undefined') { 10496 // check for undefined value (undefined value will occur when we clear the series while user clicks on legend to hide serieses) 10497 for (var s = i - 1; s >= 0; s--) { 10498 // for loop to get to 1st previous value until we get it 10499 if (series[s][0] !== null && typeof series[s][0] !== 'undefined') { 10500 lineYPosition = prevSeriesY[s][0]; 10501 prevY = lineYPosition; 10502 break; 10503 } 10504 } 10505 } 10506 } 10507 10508 return { 10509 prevY: prevY, 10510 lineYPosition: lineYPosition 10511 }; 10512 } 10513 }]); 10514 10515 return Line; 10516 }(); 10517 10518 /** 10519 * ApexCharts Formatter Class for setting value formatters for axes as well as tooltips. 10520 * 10521 * @module Formatters 10522 **/ 10523 10524 var Formatters = 10525 /*#__PURE__*/ 10526 function () { 10527 function Formatters(ctx) { 10528 _classCallCheck(this, Formatters); 10529 10530 this.ctx = ctx; 10531 this.w = ctx.w; 10532 this.tooltipKeyFormat = 'dd MMM'; 10533 } 10534 10535 _createClass(Formatters, [{ 10536 key: "xLabelFormat", 10537 value: function xLabelFormat(fn, val) { 10538 var w = this.w; 10539 10540 if (w.config.xaxis.type === 'datetime') { 10541 // if user has not specified a custom formatter, use the default tooltip.x.format 10542 if (w.config.tooltip.x.formatter === undefined) { 10543 var datetimeObj = new DateTime(this.ctx); 10544 return datetimeObj.formatDate(new Date(val), w.config.tooltip.x.format, true, true); 10545 } 10546 } 10547 10548 return fn(val); 10549 } 10550 }, { 10551 key: "setLabelFormatters", 10552 value: function setLabelFormatters() { 10553 var w = this.w; 10554 10555 w.globals.xLabelFormatter = function (val) { 10556 return val; 10557 }; 10558 10559 w.globals.xaxisTooltipFormatter = function (val) { 10560 return val; 10561 }; 10562 10563 w.globals.ttKeyFormatter = function (val) { 10564 return val; 10565 }; 10566 10567 w.globals.ttZFormatter = function (val) { 10568 return val; 10569 }; 10570 10571 w.globals.legendFormatter = function (val) { 10572 return val; 10573 }; 10574 10575 if (typeof w.config.tooltip.x.formatter === 'function') { 10576 w.globals.ttKeyFormatter = w.config.tooltip.x.formatter; 10577 } 10578 10579 if (typeof w.config.xaxis.tooltip.formatter === 'function') { 10580 w.globals.xaxisTooltipFormatter = w.config.xaxis.tooltip.formatter; 10581 } 10582 10583 if (Array.isArray(w.config.tooltip.y)) { 10584 w.globals.ttVal = w.config.tooltip.y; 10585 } else { 10586 if (w.config.tooltip.y.formatter !== undefined) { 10587 w.globals.ttVal = w.config.tooltip.y; 10588 } 10589 } 10590 10591 if (w.config.tooltip.z.formatter !== undefined) { 10592 w.globals.ttZFormatter = w.config.tooltip.z.formatter; 10593 } // legend formatter - if user wants to append any global values of series to legend text 10594 10595 10596 if (w.config.legend.formatter !== undefined) { 10597 w.globals.legendFormatter = w.config.legend.formatter; 10598 } // formatter function will always overwrite format property 10599 10600 10601 if (w.config.xaxis.labels.formatter !== undefined) { 10602 w.globals.xLabelFormatter = w.config.xaxis.labels.formatter; 10603 } else { 10604 w.globals.xLabelFormatter = function (val) { 10605 if (Utils.isNumber(val)) { 10606 // numeric xaxis may have smaller range, so defaulting to 1 decimal 10607 if (w.config.xaxis.type === 'numeric' && w.globals.dataPoints < 50) { 10608 return val.toFixed(1); 10609 } 10610 10611 return val.toFixed(0); 10612 } 10613 10614 return val; 10615 }; 10616 } // formatter function will always overwrite format property 10617 10618 10619 w.config.yaxis.forEach(function (yaxe, i) { 10620 if (yaxe.labels.formatter !== undefined) { 10621 w.globals.yLabelFormatters[i] = yaxe.labels.formatter; 10622 } else { 10623 w.globals.yLabelFormatters[i] = function (val) { 10624 if (Utils.isNumber(val)) { 10625 if (w.globals.yValueDecimal !== 0) { 10626 return val.toFixed(yaxe.decimalsInFloat !== undefined ? yaxe.decimalsInFloat : w.globals.yValueDecimal); 10627 } else if (w.globals.maxY - w.globals.minY < 5) { 10628 return val.toFixed(1); 10629 } else { 10630 return val.toFixed(0); 10631 } 10632 } 10633 10634 return val; 10635 }; 10636 } 10637 }); 10638 return w.globals; 10639 } 10640 }, { 10641 key: "heatmapLabelFormatters", 10642 value: function heatmapLabelFormatters() { 10643 var w = this.w; 10644 10645 if (w.config.chart.type === 'heatmap') { 10646 w.globals.yAxisScale[0].result = w.globals.seriesNames.slice(); // get the longest string from the labels array and also apply label formatter to it 10647 10648 var longest = w.globals.seriesNames.reduce(function (a, b) { 10649 return a.length > b.length ? a : b; 10650 }, 0); 10651 w.globals.yAxisScale[0].niceMax = longest; 10652 w.globals.yAxisScale[0].niceMin = longest; 10653 } 10654 } 10655 }]); 10656 10657 return Formatters; 10658 }(); 10659 10660 var AxesUtils = 10661 /*#__PURE__*/ 10662 function () { 10663 function AxesUtils(ctx) { 10664 _classCallCheck(this, AxesUtils); 10665 10666 this.ctx = ctx; 10667 this.w = ctx.w; 10668 } // Based on the formatter function, get the label text and position 10669 10670 10671 _createClass(AxesUtils, [{ 10672 key: "getLabel", 10673 value: function getLabel(labels, timelineLabels, x, i) { 10674 var drawnLabels = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : []; 10675 var w = this.w; 10676 var rawLabel = typeof labels[i] === 'undefined' ? '' : labels[i]; 10677 var label; 10678 var xlbFormatter = w.globals.xLabelFormatter; 10679 var customFormatter = w.config.xaxis.labels.formatter; 10680 var xFormat = new Formatters(this.ctx);
10681 label = xFormat.xLabelFormat(xlbFormatter, rawLabel); 10682 10683 if (customFormatter !== undefined) { 10684 label = customFormatter(rawLabel, labels[i], i); 10685 } 10686 10687 if (timelineLabels.length > 0) { 10688 x = timelineLabels[i].position; 10689 label = timelineLabels[i].value; 10690 } else { 10691 if (w.config.xaxis.type === 'datetime' && customFormatter === undefined) { 10692 label = ''; 10693 } 10694 } 10695 10696 if (typeof label === 'undefined') label = ''; 10697 label = label.toString(); 10698 10699 if (label.indexOf('NaN') === 0 || label.toLowerCase().indexOf('invalid') === 0 || label.toLowerCase().indexOf('infinity') >= 0 || drawnLabels.indexOf(label) >= 0 && !w.config.xaxis.labels.showDuplicates) { 10700 label = ''; 10701 } 10702 10703 return { 10704 x: x, 10705 text: label 10706 }; 10707 } 10708 }, { 10709 key: "drawYAxisTicks", 10710 value: function drawYAxisTicks(x, tickAmount, axisBorder, axisTicks, realIndex, labelsDivider, elYaxis) { 10711 var w = this.w; 10712 var graphics = new Graphics(this.ctx); // initial label position = 0; 10713 10714 var t = w.globals.translateY; 10715 10716 if (axisTicks.show) { 10717 if (w.config.yaxis[realIndex].opposite === true) x = x + axisTicks.width; 10718 10719 for (var i = tickAmount; i >= 0; i--) { 10720 var tY = t + tickAmount / 10 + w.config.yaxis[realIndex].labels.offsetY - 1; 10721 10722 if (w.globals.isBarHorizontal) { 10723 tY = labelsDivider * i; 10724 } 10725 10726 var elTick = graphics.drawLine(x + axisBorder.offsetX - axisTicks.width + axisTicks.offsetX, tY + axisTicks.offsetY, x + axisBorder.offsetX + axisTicks.offsetX, tY + axisTicks.offsetY, axisBorder.color); 10727 elYaxis.add(elTick); 10728 t = t + labelsDivider; 10729 } 10730 } 10731 } 10732 }]); 10733 10734 return AxesUtils; 10735 }(); 10736 10737 /** 10738 * ApexCharts XAxis Class for drawing X-Axis. 10739 * 10740 * @module XAxis 10741 **/ 10742 10743 var XAxis = 10744 /*#__PURE__*/ 10745 function () { 10746 function XAxis(ctx) { 10747 _classCallCheck(this, XAxis); 10748 10749 this.ctx = ctx; 10750 this.w = ctx.w; 10751 var w = this.w; 10752 this.xaxisLabels = w.globals.labels.slice(); 10753 10754 if (w.globals.timelineLabels.length > 0) { 10755 // timeline labels are there 10756 this.xaxisLabels = w.globals.timelineLabels.slice(); 10757 } 10758 10759 this.drawnLabels = []; 10760 10761 if (w.config.xaxis.position === 'top') { 10762 this.offY = 0; 10763 } else { 10764 this.offY = w.globals.gridHeight + 1; 10765 } 10766 10767 this.offY = this.offY + w.config.xaxis.axisBorder.offsetY; 10768 this.xaxisFontSize = w.config.xaxis.labels.style.fontSize; 10769 this.xaxisFontFamily = w.config.xaxis.labels.style.fontFamily; 10770 this.xaxisForeColors = w.config.xaxis.labels.style.colors; 10771 this.xaxisBorderWidth = w.config.xaxis.axisBorder.width; 10772 10773 if (this.xaxisBorderWidth.indexOf('%') > -1) { 10774 this.xaxisBorderWidth = w.globals.gridWidth * parseInt(this.xaxisBorderWidth) / 100; 10775 } else { 10776 this.xaxisBorderWidth = parseInt(this.xaxisBorderWidth); 10777 } 10778 10779 this.xaxisBorderHeight = w.config.xaxis.axisBorder.height; // For bars, we will only consider single y xais, 10780 // as we are not providing multiple yaxis for bar charts 10781 10782 this.yaxis = w.config.yaxis[0]; 10783 this.axesUtils = new AxesUtils(ctx); 10784 } 10785 10786 _createClass(XAxis, [{ 10787 key: "drawXaxis", 10788 value: function drawXaxis() { 10789 var w = this.w; 10790 var graphics = new Graphics(this.ctx); 10791 var elXaxis = graphics.group({ 10792 class: 'apexcharts-xaxis', 10793 transform: "translate(".concat(w.config.xaxis.offsetX, ", ").concat(w.config.xaxis.offsetY, ")") 10794 }); 10795 var elXaxisTexts = graphics.group({ 10796 class: 'apexcharts-xaxis-texts-g', 10797 transform: "translate(".concat(w.globals.translateXAxisX, ", ").concat(w.globals.translateXAxisY, ")") 10798 }); 10799 elXaxis.add(elXaxisTexts); 10800 var colWidth; // initial x Position (keep adding column width in the loop) 10801 10802 var xPos = w.globals.padHorizontal; 10803 var labels = []; 10804 10805 for (var i = 0; i < this.xaxisLabels.length; i++) { 10806 labels.push(this.xaxisLabels[i]); 10807 } 10808 10809 if (w.globals.isXNumeric) { 10810 colWidth = w.globals.gridWidth / (labels.length - 1); 10811 xPos = xPos + colWidth / 2 + w.config.xaxis.labels.offsetX; 10812 } else { 10813 colWidth = w.globals.gridWidth / labels.length; 10814 xPos = xPos + colWidth + w.config.xaxis.labels.offsetX; 10815 } 10816 10817 var labelsLen = labels.length; 10818 10819 if (w.config.xaxis.labels.show) { 10820 for (var _i = 0; _i <= labelsLen - 1; _i++) { 10821 var x = xPos - colWidth / 2 + w.config.xaxis.labels.offsetX; 10822 var label = this.axesUtils.getLabel(labels, w.globals.timelineLabels, x, _i, this.drawnLabels); 10823 this.drawnLabels.push(label.text);
10824 var offsetYCorrection = 28; 10825 10826 if (w.globals.rotateXLabels) { 10827 offsetYCorrection = 22; 10828 } 10829 10830 var elTick = graphics.drawText({ 10831 x: label.x, 10832 y: this.offY + w.config.xaxis.labels.offsetY + offsetYCorrection, 10833 text: '', 10834 textAnchor: 'middle', 10835 fontSize: this.xaxisFontSize, 10836 fontFamily: this.xaxisFontFamily, 10837 foreColor: Array.isArray(this.xaxisForeColors) ? this.xaxisForeColors[_i] : this.xaxisForeColors, 10838 cssClass: 'apexcharts-xaxis-label ' + w.config.xaxis.labels.style.cssClass 10839 }); 10840 10841 if (_i === labelsLen - 1) { 10842 if (w.globals.skipLastTimelinelabel) { 10843 label.text = ''; 10844 } 10845 } 10846 10847 elXaxisTexts.add(elTick); 10848 graphics.addTspan(elTick, label.text, this.xaxisFontFamily); 10849 var elTooltipTitle = document.createElementNS(w.globals.SVGNS, 'title'); 10850 elTooltipTitle.textContent = label.text; 10851 elTick.node.appendChild(elTooltipTitle); 10852 xPos = xPos + colWidth; 10853 } 10854 } 10855 10856 if (w.config.xaxis.title.text !== undefined) { 10857 var elXaxisTitle = graphics.group({ 10858 class: 'apexcharts-xaxis-title' 10859 }); 10860 var elXAxisTitleText = graphics.drawText({ 10861 x: w.globals.gridWidth / 2 + w.config.xaxis.title.offsetX, 10862 y: this.offY - parseInt(this.xaxisFontSize) + w.globals.xAxisLabelsHeight + w.config.xaxis.title.offsetY, 10863 text: w.config.xaxis.title.text, 10864 textAnchor: 'middle', 10865 fontSize: w.config.xaxis.title.style.fontSize, 10866 fontFamily: w.config.xaxis.title.style.fontFamily, 10867 foreColor: w.config.xaxis.title.style.color, 10868 cssClass: 'apexcharts-xaxis-title-text ' + w.config.xaxis.title.style.cssClass 10869 }); 10870 elXaxisTitle.add(elXAxisTitleText); 10871 elXaxis.add(elXaxisTitle); 10872 } 10873 10874 if (w.config.xaxis.axisBorder.show) { 10875 var lineCorrection = 0; 10876 10877 if (w.config.chart.type === 'bar' && w.globals.isXNumeric) { 10878 lineCorrection = lineCorrection - 15; 10879 } 10880 10881 var elHorzLine = graphics.drawLine(w.globals.padHorizontal + lineCorrection + w.config.xaxis.axisBorder.offsetX, this.offY, this.xaxisBorderWidth, this.offY, w.c
10881onfig.xaxis.axisBorder.color, 0, this.xaxisBorderHeight); 10882 elXaxis.add(elHorzLine); 10883 } 10884 10885 return elXaxis; 10886 } // this actually becomes the vertical axis (for bar charts) 10887 10888 }, { 10889 key: "drawXaxisInversed", 10890 value: function drawXaxisInversed(realIndex) { 10891 var w = this.w; 10892 var graphics = new Graphics(this.ctx); 10893 var translateYAxisX = w.config.yaxis[0].opposite ? w.globals.translateYAxisX[realIndex] : 0; 10894 var elYaxis = graphics.group({ 10895 class: 'apexcharts-yaxis apexcharts-xaxis-inversed', 10896 rel: realIndex 10897 }); 10898 var elYaxisTexts = graphics.group({ 10899 class: 'apexcharts-yaxis-texts-g apexcharts-xaxis-inversed-texts-g', 10900 transform: 'translate(' + translateYAxisX + ', 0)' 10901 }); 10902 elYaxis.add(elYaxisTexts); 10903 var colHeight; // initial x Position (keep adding column width in the loop) 10904 10905 var yPos; 10906 var labels = []; 10907 10908 for (var i = 0; i < this.xaxisLabels.length; i++) { 10909 labels.push(this.xaxisLabels[i]); 10910 } 10911 10912 colHeight = w.globals.gridHeight / labels.length; 10913 yPos = -(colHeight / 2.2); 10914 var lbFormatter = w.globals.yLabelFormatters[0]; 10915 var ylabels = w.config.yaxis[0].labels; 10916 10917 if (ylabels.show) { 10918 for (var _i2 = 0; _i2 <= labels.length - 1; _i2++) { 10919 var label = typeof labels[_i2] === 'undefined' ? '' : labels[_i2]; 10920 label = lbFormatter(label); 10921 var elLabel = graphics.drawText({ 10922 x: ylabels.offsetX - 15, 10923 y: yPos + colHeight + ylabels.offsetY, 10924 text: label, 10925 textAnchor: this.yaxis.opposite ? 'start' : 'end', 10926 foreColor: ylabels.style.color ? ylabels.style.color : ylabels.style.colors[_i2], 10927 fontSize: ylabels.style.fontSize, 10928 fontFamily: ylabels.style.fontFamily, 10929 cssClass: 'apexcharts-yaxis-label ' + ylabels.style.cssClass 10930 }); 10931 elYaxisTexts.add(elLabel); 10932 10933 if (w.config.yaxis[realIndex].labels.rotate !== 0) { 10934 var labelRotatingCenter = graphics.rotateAroundCenter(elLabel.node); 10935 elLabel.node.setAttribute('transform', "rotate(".concat(w.config.yaxis[realIndex].labels.rotate, " ").concat(labelRotatingCenter.x, " ").concat(labelRotatingCenter.y, ")")); 10936 } 10937 10938 yPos = yPos + colHeight; 10939 } 10940 } 10941 10942 if (w.config.yaxis[0].title.text !== undefined) { 10943 var elXaxisTitle = graphics.group({ 10944 class: 'apexcharts-yaxis-title apexcharts-xaxis-title-inversed', 10945 transform: 'translate(' + translateYAxisX + ', 0)' 10946 }); 10947 var elXAxisTitleText = graphics.drawText({ 10948 x: 0, 10949 y: w.globals.gridHeight / 2, 10950 text: w.config.yaxis[0].title.text, 10951 textAnchor: 'middle', 10952 foreColor: w.config.yaxis[0].title.style.color, 10953 fontSize: w.config.yaxis[0].title.style.fontSize, 10954 fontFamily: w.config.yaxis[0].title.style.fontFamily, 10955 cssClass: 'apexcharts-yaxis-title-text ' + w.config.yaxis[0].title.style.cssClass 10956 }); 10957 elXaxisTitle.add(elXAxisTitleText); 10958 elYaxis.add(elXaxisTitle); 10959 } 10960 10961 if (w.config.xaxis.axisBorder.show) { 10962 var elHorzLine = graphics.drawLine(w.globals.padHorizontal + w.config.xaxis.axisBorder.offsetX, this.offY, this.xaxisBorderWidth, this.offY, this.yaxis.axisBorder.color, 0, this.xaxisBorderHeight); 10963 elYaxis.add(elHorzLine); 10964 this.axesUtils.drawYAxisTicks(0, labels.length, w.config.yaxis[0].axisBorder, w.config.yaxis[0].axisTicks, 0, colHeight, elYaxis); 10965 } 10966 10967 return elYaxis; 10968 } 10969 }, { 10970 key: "drawXaxisTicks", 10971 value: function drawXaxisTicks(x1, appendToElement) { 10972 var w = this.w; 10973 var x2 = x1; 10974 if (x1 < 0 || x1 > w.globals.gridWidth) return; 10975 var y1 = this.offY + w.config.xaxis.axisTicks.offsetY;
10976 var y2 = y1 + w.config.xaxis.axisTicks.height; 10977 10978 if (w.config.xaxis.axisTicks.show) { 10979 var graphics = new Graphics(this.ctx); 10980 var line = graphics.drawLine(x1 + w.config.xaxis.axisTicks.offsetX, y1 + w.config.xaxis.offsetY, x2 + w.config.xaxis.axisTicks.offsetX, y2 + w.config.xaxis.offsetY, w.config.xaxis.axisTicks.color); // we are not returning anything, but appending directly to the element pased in param 10981 10982 appendToElement.add(line); 10983 line.node.classList.add('apexcharts-xaxis-tick'); 10984 } 10985 } 10986 }, { 10987 key: "getXAxisTicksPositions", 10988 value: function getXAxisTicksPositions() { 10989 var w = this.w; 10990 var xAxisTicksPositions = []; 10991 var xCount = this.xaxisLabels.length; 10992 var x1 = w.globals.padHorizontal; 10993 10994 if (w.globals.timelineLabels.length > 0) { 10995 for (var i = 0; i < xCount; i++) { 10996 x1 = this.xaxisLabels[i].position; 10997 xAxisTicksPositions.push(x1); 10998 } 10999 } else { 11000 var xCountForCategoryCharts = xCount; 11001 11002 for (var _i3 = 0; _i3 < xCountForCategoryCharts; _i3++) { 11003 var x1Count = xCountForCategoryCharts; 11004 11005 if (w.globals.isXNumeric && w.config.chart.type !== 'bar') { 11006 x1Count -= 1;
11007 } 11008 11009 x1 = x1 + w.globals.gridWidth / x1Count; 11010 xAxisTicksPositions.push(x1); 11011 } 11012 } 11013 11014 return xAxisTicksPositions; 11015 } // to rotate x-axis labels or to put ... for longer text in xaxis 11016 11017 }, { 11018 key: "xAxisLabelCorrections", 11019 value: function xAxisLabelCorrections() { 11020 var w = this.w; 11021 var graphics = new Graphics(this.ctx); 11022 var xAxis = w.globals.dom.baseEl.querySelector('.apexcharts-xaxis-texts-g'); 11023 var xAxisTexts = w.globals.dom.baseEl.querySelectorAll('.apexcharts-xaxis-texts-g text'); 11024 var yAxisTextsInversed = w.globals.dom.baseEl.querySelectorAll('.apexcharts-yaxis-inversed text'); 11025 var xAxisTextsInversed = w.globals.dom.baseEl.querySelectorAll('.apexcharts-xaxis-inversed-texts-g text'); 11026 11027 if (w.globals.rotateXLabels || w.config.xaxis.labels.rotateAlways) { 11028 for (var xat = 0; xat < xAxisTexts.length; xat++) { 11029 var textRotatingCenter = graphics.rotateAroundCenter(xAxisTexts[xat]); 11030 textRotatingCenter.y = textRotatingCenter.y - 1; // + tickWidth/4; 11031 11032 textRotatingCenter.x = textRotatingCenter.x + 1; 11033 xAxisTexts[xat].setAttribute('transform', "rotate(".concat(w.config.xaxis.labels.rotate, " ").concat(textRotatingCenter.x, " ").concat(textRotatingCenter.y, ")")); 11034 xAxisTexts[xat].setAttribute('text-anchor', "end"); 11035 var offsetHeight = 10; 11036 xAxis.setAttribute('transform', "translate(0, ".concat(-offsetHeight, ")")); 11037 var tSpan = xAxisTexts[xat].childNodes; 11038 11039 if (w.config.xaxis.labels.trim) { 11040 graphics.placeTextWithEllipsis(tSpan[0], tSpan[0].textContent, w.config.xaxis.labels.maxHeight - 40); 11041 } 11042 } 11043 } else { 11044 var width = w.globals.gridWidth / w.globals.labels.length; 11045 11046 for (var _xat = 0; _xat < xAxisTexts.length; _xat++) { 11047 var _tSpan = xAxisTexts[_xat].childNodes; 11048 11049 if (w.config.xaxis.labels.trim && w.config.xaxis.type !== 'datetime') { 11050 graphics.placeTextWithEllipsis(_tSpan[0], _tSpan[0].textContent, width); 11051 } 11052 } 11053 } 11054 11055 if (yAxisTextsInversed.length > 0) { 11056 // truncate rotated y axis in bar chart (x axis) 11057 var firstLabelPosX = yAxisTextsInversed[yAxisTextsInversed.length - 1].getBBox(); 11058 var lastLabelPosX = yAxisTextsInversed[0].getBBox(); 11059 11060 if (firstLabelPosX.x < -20) { 11061 yAxisTextsInversed[yAxisTextsInversed.length - 1].parentNode.removeChild(yAxisTextsInversed[yAxisTextsInversed.length - 1]); 11062 } 11063 11064 if (lastLabelPosX.x + lastLabelPosX.width > w.globals.gridWidth) { 11065 yAxisTextsInversed[0].parentNode.removeChild(yAxisTextsInversed[0]); 11066 } // truncate rotated x axis in bar chart (y axis) 11067 11068 11069 for (var _xat2 = 0; _xat2 < xAxisTextsInversed.length; _xat2++) { 11070 graphics.placeTextWithEllipsis(xAxisTextsInversed[_xat2], xAxisTextsInversed[_xat2].textContent, w.config.yaxis[0].labels.maxWidth - parseInt(w.config.yaxis[0].title.style.fontSize) * 2 - 20); 11071 } 11072 } 11073 } // renderXAxisBands() { 11074 // let w = this.w; 11075 // let plotBand = document.createElementNS(w.globals.SVGNS, 'rect') 11076 // w.globals.dom.elGraphical.add(plotBand) 11077 // } 11078 11079 }]); 11080 11081 return XAxis; 11082 }(); 11083 11084 /** 11085 * ApexCharts YAxis Class for drawing Y-Axis. 11086 * 11087 * @module YAxis 11088 **/ 11089 11090 var YAxis = 11091 /*#__PURE__*/ 11092 function () { 11093 function YAxis(ctx) { 11094 _classCallCheck(this, YAxis); 11095 11096 this.ctx = ctx; 11097 this.w = ctx.w; 11098 var w = this.w; 11099 this.xaxisFontSize = w.config.xaxis.labels.style.fontSize; 11100 this.axisFontFamily = w.config.xaxis.labels.style.fontFamily; 11101 this.xaxisForeColors = w.config.xaxis.labels.style.colors; 11102 this.xAxisoffX = 0; 11103 11104 if (w.config.xaxis.position === 'bottom') { 11105 this.xAxisoffX = w.globals.gridHeight; 11106 } 11107 11108 this.drawnLabels = []; 11109 this.axesUtils = new AxesUtils(ctx); 11110 } 11111 11112 _createClass(YAxis, [{ 11113 key: "drawYaxis", 11114 value: function drawYaxis(realIndex) { 11115 var w = this.w; 11116 var graphics = new Graphics(this.ctx); 11117 var yaxisFontSize = w.config.yaxis[realIndex].labels.style.fontSize; 11118 var yaxisFontFamily = w.config.yaxis[realIndex].labels.style.fontFamily; 11119 var elYaxis = graphics.group({ 11120 class: 'apexcharts-yaxis', 11121 rel: realIndex, 11122 transform: 'translate(' + w.globals.translateYAxisX[realIndex] + ', 0)' 11123 }); 11124 11125 if (!w.config.yaxis[realIndex].show) { 11126 return elYaxis; 11127 } 11128 11129 var elYaxisTexts = graphics.group({ 11130 class: 'apexcharts-yaxis-texts-g' 11131 }); 11132 elYaxis.add(elYaxisTexts); 11133 var tickAmount = w.globals.yAxisScale[realIndex].result.length - 1; // labelsDivider is simply svg height/number of ticks 11134
11135 var labelsDivider = w.globals.gridHeight / tickAmount + 0.1; // initial label position = 0; 11136 11137 var l = w.globals.translateY; 11138 var lbFormatter = w.globals.yLabelFormatters[realIndex]; 11139 var labels = w.globals.yAxisScale[realIndex].result.slice(); 11140 11141 if (w.config.yaxis[realIndex] && w.config.yaxis[realIndex].reversed) { 11142 labels.reverse(); 11143 } 11144 11145 if (w.config.yaxis[realIndex].labels.show) { 11146 for (var i = tickAmount; i >= 0; i--) { 11147 var val = labels[i]; 11148 val = lbFormatter(val, i); 11149 var xPad = w.config.yaxis[realIndex].labels.padding; 11150 11151 if (w.config.yaxis[realIndex].opposite && w.config.yaxis.length !== 0) { 11152 xPad = xPad * -1; 11153 } 11154 11155 var label = graphics.drawText({ 11156 x: xPad, 11157 y: l + tickAmount / 10 + w.config.yaxis[realIndex].labels.offsetY + 1, 11158 text: val, 11159 textAnchor: w.config.yaxis[realIndex].opposite ? 'start' : 'end', 11160 fontSize: yaxisFontSize, 11161 fontFamily: yaxisFontFamily, 11162 foreColor: w.config.yaxis[realIndex].labels.style.color, 11163 cssClass: 'apexcharts-yaxis-label ' + w.config.yaxis[realIndex].labels.style.cssClass 11164 }); 11165 elYaxisTexts.add(label); 11166 var labelRotatingCenter = graphics.rotateAroundCenter(label.node); 11167 11168 if (w.config.yaxis[realIndex].labels.rotate !== 0) { 11169 label.node.setAttribute('transform', "rotate(".concat(w.config.yaxis[realIndex].labels.rotate, " ").concat(labelRotatingCenter.x, " ").concat(labelRotatingCenter.y, ")")); 11170 } 11171 11172 l = l + labelsDivider; 11173 } 11174 } 11175 11176 if (w.config.yaxis[realIndex].title.text !== undefined) { 11177 var elYaxisTitle = graphics.group({ 11178 class: 'apexcharts-yaxis-title' 11179 }); 11180 var x = 0; 11181 11182 if (w.config.yaxis[realIndex].opposite) { 11183 x = w.globals.translateYAxisX[realIndex]; 11184 } 11185 11186 var elYAxisTitleText = graphics.drawText({ 11187 x: x, 11188 y: w.globals.gridHeight / 2 + w.globals.translateY, 11189 text: w.config.yaxis[realIndex].title.text, 11190 textAnchor: 'end', 11191 foreColor: w.config.yaxis[realIndex].title.style.color, 11192 fontSize: w.config.yaxis[realIndex].title.style.fontSize, 11193 fontFamily: w.config.yaxis[realIndex].title.style.fontFamily, 11194 cssClass: 'apexcharts-yaxis-title-text ' + w.config.yaxis[realIndex].title.style.cssClass 11195 }); 11196 elYaxisTitle.add(elYAxisTitleText); 11197 elYaxis.add(elYaxisTitle); 11198 } 11199 11200 var axisBorder = w.config.yaxis[realIndex].axisBorder; 11201 11202 if (axisBorder.show) { 11203 var _x = 31 + axisBorder.offsetX; 11204 11205 if (w.config.yaxis[realIndex].opposite) { 11206 _x = -31 - axisBorder.offsetX; 11207 } 11208 11209 var elVerticalLine = graphics.drawLine(_x, w.globals.translateY + axisBorder.offsetY - 2, _x, w.globals.gridHeight + w.globals.translateY + axisBorder.offsetY + 2, axisBorder.color); 11210 elYaxis.add(elVerticalLine); 11211 this.axesUtils.drawYAxisTicks(_x, tickAmount, axisBorder, w.config.yaxis[realIndex].axisTicks, realIndex, labelsDivider, elYaxis); 11212 } 11213 11214 return elYaxis; 11215 } // This actually becomes horizonal axis (for bar charts) 11216 11217 }, { 11218 key: "drawYaxisInversed", 11219 value: function drawYaxisInversed(realIndex) { 11220 var w = this.w; 11221 var graphics = new Graphics(this.ctx); 11222 var elXaxis = graphics.group({ 11223 class: 'apexcharts-xaxis apexcharts-yaxis-inversed' 11224 }); 11225 var elXaxisTexts = graphics.group({ 11226 class: 'apexcharts-xaxis-texts-g', 11227 transform: "translate(".concat(w.globals.translateXAxisX, ", ").concat(w.globals.translateXAxisY, ")") 11228 }); 11229 elXaxis.add(elXaxisTexts); 11230 var tickAmount = w.globals.yAxisScale[realIndex].result.length - 1; // labelsDivider is simply svg width/number of ticks 11231 11232 var labelsDivider = w.globals.gridWidth / tickAmount + 0.1; // initial label position; 11233 11234 var l = labelsDivider + w.config.xaxis.labels.offsetX; 11235 var lbFormatter = w.globals.xLabelFormatter; 11236 var labels = w.globals.yAxisScale[realIndex].result.slice(); 11237 var timelineLabels = w.globals.invertedTimelineLabels;
11238 11239 if (timelineLabels.length > 0) { 11240 this.xaxisLabels = timelineLabels.slice(); 11241 labels = timelineLabels.slice(); 11242 tickAmount = labels.length; 11243 } 11244 11245 if (w.config.yaxis[realIndex] && w.config.yaxis[realIndex].reversed) { 11246 labels.reverse(); 11247 } 11248 11249 var tl = timelineLabels.length; 11250 11251 if (w.config.xaxis.labels.show) { 11252 for (var i = tl ? 0 : tickAmount; tl ? i < tl - 1 : i >= 0; tl ? i++ : i--) { 11253 var val = labels[i]; 11254 val = lbFormatter(val, i); 11255 var x = w.globals.gridWidth + w.globals.padHorizontal - (l - labelsDivider + w.config.xaxis.labels.offsetX); 11256 11257 if (timelineLabels.length) { 11258 var label = this.axesUtils.getLabel(labels, timelineLabels, x, i, this.drawnLabels); 11259 x = label.x; 11260 val = label.text; 11261 this.drawnLabels.push(label.text); 11262 } 11263 11264 var elTick = graphics.drawText({ 11265 x: x, 11266 y: this.xAxisoffX + w.config.xaxis.labels.offsetY + 30, 11267 text: '', 11268 textAnchor: 'middle', 11269 foreColor: Array.isArray(this.xaxisForeColors) ? this.xaxisForeColors[realIndex] : this.xaxisForeColors, 11270 fontSize: this.xaxisFontSize, 11271 fontFamily: this.xaxisFontFamily, 11272 cssClass: 'apexcharts-xaxis-label ' + w.config.xaxis.labels.style.cssClass 11273 }); 11274 elXaxisTexts.add(elTick); 11275 elTick.tspan(val); 11276 var elTooltipTitle = document.createElementNS(w.globals.SVGNS, 'title'); 11277 elTooltipTitle.textContent = val; 11278 elTick.node.appendChild(elTooltipTitle); 11279 l = l + labelsDivider; 11280 } 11281 } 11282 11283 if (w.config.xaxis.title.text !== undefined) { 11284 var elYaxisTitle = graphics.group({ 11285 class: 'apexcharts-xaxis-title apexcharts-yaxis-title-inversed' 11286 }); 11287 var elYAxisTitleText = graphics.drawText({ 11288 x: w.globals.gridWidth / 2, 11289 y: this.xAxisoffX + parseInt(this.xaxisFontSize) + parseInt(w.config.xaxis.title.style.fontSize) + 20, 11290 text: w.config.xaxis.title.text, 11291 textAnchor: 'middle', 11292 fontSize: w.config.xaxis.title.style.fontSize, 11293 fontFamily: w.config.xaxis.title.style.fontFamily, 11294 cssClass: 'apexcharts-xaxis-title-text ' + w.config.xaxis.title.style.cssClass 11295 }); 11296 elYaxisTitle.add(elYAxisTitleText); 11297 elXaxis.add(elYaxisTitle); 11298 } 11299 11300 var axisBorder = w.config.yaxis[realIndex].axisBorder; 11301 11302 if (axisBorder.show) { 11303 var elVerticalLine = graphics.drawLine(w.globals.padHorizontal + axisBorder.offsetX, 1 + axisBorder.offsetY, w.globals.padHorizontal + axisBorder.offsetX, w.globals.gridHeight + axisBorder.offsetY, axisBorder.color); 11304 elXaxis.add(elVerticalLine); 11305 } 11306 11307 return elXaxis; 11308 } 11309 }, { 11310 key: "yAxisTitleRotate", 11311 value: function yAxisTitleRotate(realIndex, yAxisOpposite) { 11312 var w = this.w; 11313 var graphics = new Graphics(this.ctx); 11314 var yAxisLabelsCoord = { 11315 width: 0, 11316 height: 0 11317 }; 11318 var yAxisTitleCoord = { 11319 width: 0, 11320 height: 0 11321 }; 11322 var elYAxisLabelsWrap = w.globals.dom.baseEl.querySelector(" .apexcharts-yaxis[rel='".concat(realIndex, "'] .apexcharts-yaxis-texts-g")); 11323 11324 if (elYAxisLabelsWrap !== null) { 11325 yAxisLabelsCoord = elYAxisLabelsWrap.getBoundingClientRect(); 11326 } 11327 11328 var yAxisTitle = w.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(realIndex, "'] .apexcharts-yaxis-title text")); 11329 11330 if (yAxisTitle !== null) { 11331 yAxisTitleCoord = yAxisTitle.getBoundingClientRect(); 11332 } 11333 11334 if (yAxisTitle !== null) { 11335 var x = this.xPaddingForYAxisTitle(realIndex, yAxisLabelsCoord, yAxisTitleCoord, yAxisOpposite); 11336 yAxisTitle.setAttribute('x', x.xPos - (yAxisOpposite ? 10 : 0)); 11337 } 11338 11339 if (yAxisTitle !== null) {
11340 var titleRotatingCenter = graphics.rotateAroundCenter(yAxisTitle); 11341 11342 if (!yAxisOpposite) { 11343 yAxisTitle.setAttribute('transform', "rotate(-".concat(w.config.yaxis[realIndex].title.rotate, " ").concat(titleRotatingCenter.x, " ").concat(titleRotatingCenter.y, ")")); 11344 } else { 11345 yAxisTitle.setAttribute('transform', "rotate(".concat(w.config.yaxis[realIndex].title.rotate, " ").concat(titleRotatingCenter.x, " ").concat(titleRotatingCenter.y, ")")); 11346 } 11347 } 11348 } 11349 }, { 11350 key: "xPaddingForYAxisTitle", 11351 value: function xPaddingForYAxisTitle(realIndex, yAxisLabelsCoord, yAxisTitleCoord, yAxisOpposite) { 11352 var w = this.w; 11353 var oppositeAxisCount = 0; 11354 var x = 0; 11355 var padd = 10; 11356 11357 if (w.config.yaxis[realIndex].title.text === undefined || realIndex < 0) { 11358 return { 11359 xPos: x, 11360 padd: 0 11361 }; 11362 } 11363 11364 if (yAxisOpposite) { 11365 x = yAxisLabelsCoord.width + w.config.yaxis[realIndex].title.offsetX + yAxisTitleCoord.width / 2 + padd / 2; 11366 oppositeAxisCount += 1; 11367 11368 if (oppositeAxisCount === 0) { 11369 x = x - padd / 2; 11370 } 11371 } else { 11372 x = yAxisLabelsCoord.width * -1 + w.config.yaxis[realIndex].title.offsetX + padd / 2 + yAxisTitleCoord.width / 2; 11373 11374 if (w.globals.isBarHorizontal) { 11375 padd = 25; 11376 x = yAxisLabelsCoord.width * -1 - w.config.yaxis[realIndex].title.offsetX - padd; 11377 } 11378 } 11379 11380 return { 11381 xPos: x, 11382 padd: padd 11383 }; 11384 } // sets the x position of the y-axis by counting the labels width, title width and any offset 11385 11386 }, { 11387 key: "setYAxisXPosition", 11388 value: function setYAxisXPosition(yaxisLabelCoords, yTitleCoords) { 11389 var w = this.w; 11390 var xLeft = 0; 11391 var xRight = 0; 11392 var leftOffsetX = 21; 11393 var rightOffsetX = 1; 11394 11395 if (w.config.yaxis.length > 1) { 11396 this.multipleYs = true; 11397 } 11398 11399 w.config.yaxis.map(function (yaxe, index) { 11400 var shouldNotDrawAxis = w.globals.ignoreYAxisIndexes.indexOf(index) > -1 || !yaxe.show || yaxe.floating || yaxisLabelCoords[index].width === 0; 11401 var axisWidth = yaxisLabelCoords[index].width + yTitleCoords[index].width; 11402 11403 if (!yaxe.opposite) { 11404 xLeft = w.globals.translateX - leftOffsetX; 11405 11406 if (!shouldNotDrawAxis) { 11407 leftOffsetX = leftOffsetX + axisWidth + 20; 11408 } 11409 11410 w.globals.translateYAxisX[index] = xLeft + yaxe.labels.offsetX; 11411 } else { 11412 if (w.globals.isBarHorizontal) { 11413 xRight = w.globals.gridWidth + w.globals.translateX - 1; 11414 w.globals.translateYAxisX[index] = xRight - yaxe.labels.offsetX; 11415 } else { 11416 xRight = w.globals.gridWidth + w.globals.translateX + rightOffsetX; 11417 11418 if (!shouldNotDrawAxis) { 11419 rightOffsetX = rightOffsetX + axisWidth + 20; 11420 } 11421 11422 w.globals.translateYAxisX[index] = xRight - yaxe.labels.offsetX + 20; 11423 } 11424 } 11425 }); 11426 } 11427 }, { 11428 key: "setYAxisTextAlignments", 11429 value: function setYAxisTextAlignments() { 11430 var w = this.w; 11431 var yaxis = w.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis"); 11432 yaxis = Utils.listToArray(yaxis); 11433 yaxis.forEach(function (y, index) { 11434 var yaxe = w.config.yaxis[index]; // proceed only if user has specified alignment 11435 11436 if (yaxe.labels.align !== undefined) { 11437 var yAxisInner = w.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(index, "'] .apexcharts-yaxis-texts-g")); 11438 var yAxisTexts = w.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis[rel='".concat(index, "'] .apexcharts-yaxis-label")); 11439 yAxisTexts = Utils.listToArray(yAxisTexts); 11440 var rect = yAxisInner.getBoundingClientRect(); 11441 11442 if (yaxe.labels.align === 'left') {
11443 yAxisTexts.forEach(function (label, lI) { 11444 label.setAttribute('text-anchor', 'start'); 11445 }); 11446 11447 if (!yaxe.opposite) { 11448 yAxisInner.setAttribute('transform', "translate(-".concat(rect.width, ", 0)")); 11449 } 11450 } else if (yaxe.labels.align === 'center') { 11451 yAxisTexts.forEach(function (label, lI) { 11452 label.setAttribute('text-anchor', 'middle'); 11453 }); 11454 yAxisInner.setAttribute('transform', "translate(".concat(rect.width / 2 * (!yaxe.opposite ? -1 : 1), ", 0)")); 11455 } else if (yaxe.labels.align === 'right') { 11456 yAxisTexts.forEach(function (label, lI) { 11457 label.setAttribute('text-anchor', 'end'); 11458 }); 11459 11460 if (yaxe.opposite) { 11461 yAxisInner.setAttribute('transform', "translate(".concat(rect.width, ", 0)")); 11462 } 11463 } 11464 } 11465 }); 11466 } 11467 }]); 11468 11469 return YAxis; 11470 }(); 11471 11472 var Range = 11473 /*#__PURE__*/ 11474 function () { 11475 function Range(ctx) { 11476 _classCallCheck(this, Range); 11477 11478 this.ctx = ctx; 11479 this.w = ctx.w; 11480 } // http://stackoverflow.com/questions/326679/choosing-an-attractive-linear-scale-for-a-graphs-y-axiss 11481 // This routine creates the Y axis values for a graph. 11482 11483 11484 _createClass(Range, [{ 11485 key: "niceScale", 11486 value: function niceScale(yMin, yMax, diff) { 11487 var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; 11488 var ticks = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 10; 11489 var w = this.w; 11490 var NO_MIN_MAX_PROVIDED = this.w.config.yaxis[index].max === undefined && this.w.config.yaxis[index].min === undefined || this.w.config.yaxis[index].forceNiceScale; 11491 11492 if (yMin === Number.MIN_VALUE && yMax === 0 || !Utils.isNumber(yMin) && !Utils.isNumber(yMax) || yMin === Number.MIN_VALUE && yMax === -Number.MAX_VALUE) { 11493 // when all values are 0 11494 yMin = 0; 11495 yMax = ticks; 11496 var linearScale = this.linearScale(yMin, yMax, ticks); 11497 return linearScale; 11498 } 11499 11500 if (yMin > yMax) { 11501 // if somehow due to some wrong config, user sent max less than min, 11502 // adjust the min/max again 11503 console.warn('yaxis.min cannot be greater than yaxis.max'); 11504 yMax = yMin + 0.1; 11505 } else if (yMin === yMax) { 11506 // If yMin and yMax are identical, then 11507 // adjust the yMin and yMax values to actually 11508 // make a graph. Also avoids division by zero errors. 11509 yMin = yMin === 0 ? 0 : yMin - 0.5; // some small value 11510 11511 yMax = yMax === 0 ? 2 : yMax + 0.5; // some small value 11512 } // Calculate Min amd Max graphical labels and graph 11513 // increments. The number of ticks defaults to 11514 // 10 which is the SUGGESTED value. Any tick value 11515 // entered is used as a suggested value which is 11516 // adjusted to be a 'pretty' value. 11517 // 11518 // Output will be an array of the Y axis values that 11519 // encompass the Y values. 11520 11521 11522 var result = []; // Determine Range 11523 11524 var range = Math.abs(yMax - yMin); 11525 11526 if (range < 1 && NO_MIN_MAX_PROVIDED && (w.config.chart.type === 'candlestick' || w.config.series[index].type === 'candlestick' || w.globals.isRangeData)) { 11527 /* fix https://github.com/apexcharts/apexcharts.js/issues/430 */ 11528 yMax = yMax * 1.01; 11529 } // for extremely small values - #fix #553 11530 11531 11532 if (range < 0.00001 && NO_MIN_MAX_PROVIDED && yMax < 10) { 11533 yMax = yMax * 1.05; 11534 } else if (diff > 0.1 && diff < 3 && NO_MIN_MAX_PROVIDED) { 11535 /* fix https://github.com/apexcharts/apexcharts.js/issues/576 */ 11536 11537 /* fix https://github.com/apexcharts/apexcharts.js/issues/588 */ 11538 yMax = yMax + diff / 3; 11539 } 11540 11541 var tiks = ticks + 1; // Adjust ticks if needed 11542 11543 if (tiks < 2) {
11544 tiks = 2; 11545 } else if (tiks > 2) { 11546 tiks -= 2; 11547 } // Get raw step value 11548 11549 11550 var tempStep = range / tiks; // Calculate pretty step value 11551 11552 var mag = Math.floor(Utils.log10(tempStep)); 11553 var magPow = Math.pow(10, mag); 11554 var magMsd = parseInt(tempStep / magPow); 11555 var stepSize = magMsd * magPow; // build Y label array. 11556 // Lower and upper bounds calculations 11557 11558 var lb = stepSize * Math.floor(yMin / stepSize); 11559 var ub = stepSize * Math.ceil(yMax / stepSize); // Build array 11560 11561 var val = lb; 11562 11563 while (1) { 11564 result.push(val); 11565 val += stepSize; 11566 11567 if (val > ub) { 11568 break; 11569 } 11570 } 11571 11572 if (NO_MIN_MAX_PROVIDED) { 11573 return { 11574 result: result, 11575 niceMin: result[0], 11576 niceMax: result[result.length - 1] 11577 }; 11578 } else { 11579 result = []; 11580 var v = yMin; 11581 result.push(v); 11582 var valuesDivider = Math.abs(yMax - yMin) / ticks; 11583 11584 for (var i = 0; i <= ticks - 1; i++) { 11585 v = v + valuesDivider; 11586 result.push(v); 11587 } 11588 11589 return { 11590 result: result, 11591 niceMin: result[0], 11592 niceMax: result[result.length - 1] 11593 }; 11594 } 11595 } 11596 }, { 11597 key: "linearScale", 11598 value: function linearScale(yMin, yMax) { 11599 var ticks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10; 11600 var range = Math.abs(yMax - yMin); 11601 var step = range / ticks; 11602 11603 if (ticks === Number.MAX_VALUE) { 11604 ticks = 10; 11605 step = 1; 11606 } 11607 11608 var result = []; 11609 var v = yMin; 11610 11611 while (ticks >= 0) { 11612 result.push(v); 11613 v = v + step; 11614 ticks -= 1; 11615 } 11616 11617 return { 11618 result: result, 11619 niceMin: result[0], 11620 niceMax: result[result.length - 1] 11621 }; 11622 } 11623 }, { 11624 key: "logarithmicScale", 11625 value: function logarithmicScale(index, yMin, yMax, ticks) { 11626 if (yMin < 0 || yMin === Number.MIN_VALUE) yMin = 0.01; 11627 var base = 10; 11628 var min = Math.log(yMin) / Math.log(base); 11629 var max = Math.log(yMax) / Math.log(base); 11630 var range = Math.abs(yMax - yMin); 11631 var step = range / ticks; 11632 var result = []; 11633 var v = yMin; 11634 11635 while (ticks >= 0) { 11636 result.push(v); 11637 v = v + step; 11638 ticks -= 1; 11639 } 11640 11641 var logs = result.map(function (niceNumber, i) { 11642 if (niceNumber <= 0) { 11643 niceNumber = 0.01; 11644 } // calculate adjustment factor 11645 11646 11647 var scale = (max - min) / (yMax - yMin); 11648 var logVal = Math.pow(base, min + scale * (niceNumber - min)); 11649 return Math.round(logVal / Utils.roundToBase(logVal, base)) * Utils.roundToBase(logVal, base); 11650 }); // Math.floor may have rounded the value to 0, revert back to 1 11651 11652 if (logs[0] === 0) logs[0] = 1; 11653 return { 11654 result: logs, 11655 niceMin: logs[0], 11656 niceMax: logs[logs.length - 1] 11657 }; 11658 } 11659 }, { 11660 key: "setYScaleForIndex", 11661 value: function setYScaleForIndex(index, minY, maxY) { 11662 var gl = this.w.globals; 11663 var cnf = this.w.config; 11664 var y = gl.isBarHorizontal ? cnf.xaxis : cnf.yaxis[index]; 11665 11666 if (typeof gl.yAxisScale[index] === 'undefined') { 11667 gl.yAxisScale[index] = []; 11668 } 11669 11670 if (y.logarithmic) { 11671 gl.allSeriesCollapsed = false; 11672 gl.yAxisScale[index] = this.logarithmicScale(index, minY, maxY, y.tickAmount ? y.tickAmount : Math.floor(Math.log10(maxY))); 11673 } else { 11674 if (maxY === -Number.MAX_VALUE || !Utils.isNumber(maxY)) { 11675 // no data in the chart. Either all series collapsed or user passed a blank array 11676 gl.yAxisScale[index] = this.linearScale(0, 5, 5); 11677 } else {
11678 // there is some data. Turn off the allSeriesCollapsed flag 11679 gl.allSeriesCollapsed = false; 11680 11681 if ((y.min !== undefined || y.max !== undefined) && !y.forceNiceScale) { 11682 // fix https://github.com/apexcharts/apexcharts.js/issues/492 11683 gl.yAxisScale[index] = this.linearScale(minY, maxY, y.tickAmount); 11684 } else { 11685 var diff = Math.abs(maxY - minY); 11686 gl.yAxisScale[index] = this.niceScale(minY, maxY, diff, index, // fix https://github.com/apexcharts/apexcharts.js/issues/397 11687 y.tickAmount ? y.tickAmount : diff < 5 && diff > 1 ? diff + 1 : 5); 11688 } 11689 } 11690 } 11691 } 11692 }, { 11693 key: "setMultipleYScales", 11694 value: function setMultipleYScales() { 11695 var _this = this; 11696 11697 var gl = this.w.globals; 11698 var cnf = this.w.config; 11699 var minYArr = gl.minYArr.concat([]); 11700 var maxYArr = gl.maxYArr.concat([]); 11701 var scalesIndices = []; // here, we loop through the yaxis array and find the item which has "seriesName" property 11702 11703 cnf.yaxis.forEach(function (yaxe, i) { 11704 var index = i; 11705 cnf.series.forEach(function (s, si) { 11706 // if seriesName matches and that series is not collapsed, we use that scale 11707 if (s.name === yaxe.seriesName && gl.collapsedSeriesIndices.indexOf(si) === -1) { 11708 index = si; 11709 11710 if (i !== si) { 11711 scalesIndices.push({ 11712 index: si, 11713 similarIndex: i, 11714 alreadyExists: true 11715 }); 11716 } else { 11717 scalesIndices.push({ 11718 index: si 11719 }); 11720 } 11721 } 11722 }); 11723 var minY = minYArr[index]; 11724 var maxY = maxYArr[index]; 11725 11726 _this.setYScaleForIndex(i, minY, maxY); 11727 }); 11728 this.sameScaleInMultipleAxes(minYArr, maxYArr, scalesIndices); 11729 } 11730 }, { 11731 key: "sameScaleInMultipleAxes", 11732 value: function sameScaleInMultipleAxes(minYArr, maxYArr, scalesIndices) { 11733 var _this2 = this; 11734 11735 var cnf = this.w.config; 11736 var gl = this.w.globals; // we got the scalesIndices array in the above code, but we need to filter out the items which doesn't have same scales 11737 11738 var similarIndices = []; 11739 scalesIndices.forEach(function (scale) { 11740 if (scale.alreadyExists) { 11741 if (typeof similarIndices[scale.index] === 'undefined') { 11742 similarIndices[scale.index] = []; 11743 } 11744 11745 similarIndices[scale.index].push(scale.index); 11746 similarIndices[scale.index].push(scale.similarIndex); 11747 } 11748 }); 11749 11750 function intersect(a, b) { 11751 return a.filter(function (value) { 11752 return b.indexOf(value) !== -1; 11753 }); 11754 } 11755 11756 similarIndices.forEach(function (si, i) { 11757 similarIndices.forEach(function (sj, j) { 11758 if (i !== j) { 11759 if (intersect(si, sj).length > 0) { 11760 similarIndices[i] = similarIndices[i].concat(similarIndices[j]); 11761 } 11762 } 11763 }); 11764 }); // then, we remove duplicates from the similarScale array 11765 11766 var uniqueSimilarIndices = similarIndices.map(function (item) { 11767 return item.filter(function (i, pos) { 11768 return item.indexOf(i) === pos; 11769 }); 11770 }); // sort further to remove whole duplicate arrays later 11771 11772 var sortedIndices = uniqueSimilarIndices.map(function (s) { 11773 return s.sort(); 11774 }); // remove undefined items 11775 11776 similarIndices = similarIndices.filter(function (s) { 11777 return !!s; 11778 }); 11779 var indices = sortedIndices.slice(); 11780 var stringIndices = indices.map(function (ind) { 11781 return JSON.stringify(ind); 11782 }); 11783 indices = indices.filter(function (ind, p) { 11784 return stringIndices.indexOf(JSON.stringify(ind)) === p; 11785 }); 11786 var sameScaleMinYArr = []; 11787 var sameScaleMaxYArr = []; 11788 minYArr.forEach(function (minYValue, yi) {
11789 indices.forEach(function (scale, i) { 11790 // we compare only the yIndex which exists in the indices array 11791 if (scale.indexOf(yi) > -1) { 11792 if (typeof sameScaleMinYArr[i] === 'undefined') { 11793 sameScaleMinYArr[i] = []; 11794 sameScaleMaxYArr[i] = []; 11795 } 11796 11797 sameScaleMinYArr[i].push({ 11798 key: yi, 11799 value: minYValue 11800 }); 11801 sameScaleMaxYArr[i].push({ 11802 key: yi, 11803 value: maxYArr[yi] 11804 }); 11805 } 11806 }); 11807 }); 11808 var sameScaleMin = Array.apply(null, Array(indices.length)).map(Number.prototype.valueOf, Number.MIN_VALUE); 11809 var sameScaleMax = Array.apply(null, Array(indices.length)).map(Number.prototype.valueOf, -Number.MAX_VALUE); 11810 sameScaleMinYArr.forEach(function (s, i) { 11811 s.forEach(function (sc, j) { 11812 sameScaleMin[i] = Math.min(sc.value, sameScaleMin[i]); 11813 }); 11814 }); 11815 sameScaleMaxYArr.forEach(function (s, i) { 11816 s.forEach(function (sc, j) { 11817 sameScaleMax[i] = Math.max(sc.value, sameScaleMax[i]); 11818 }); 11819 }); 11820 minYArr.forEach(function (min, i) { 11821 sameScaleMaxYArr.forEach(function (s, si) { 11822 var minY = sameScaleMin[si]; 11823 var maxY = sameScaleMax[si]; 11824 s.forEach(function (ind, k) { 11825 if (s[k].key === i) { 11826 if (cnf.yaxis[i].min !== undefined) { 11827 if (typeof cnf.yaxis[i].min === 'function') { 11828 minY = cnf.yaxis[i].min(gl.minY); 11829 } else { 11830 minY = cnf.yaxis[i].min; 11831 } 11832 } 11833 11834 if (cnf.yaxis[i].max !== undefined) { 11835 if (typeof cnf.yaxis[i].max === 'function') { 11836 maxY = cnf.yaxis[i].max(gl.maxY); 11837 } else { 11838 maxY = cnf.yaxis[i].max; 11839 } 11840 } 11841 11842 _this2.setYScaleForIndex(i, minY, maxY); 11843 } 11844 }); 11845 }); 11846 }); 11847 } 11848 }, { 11849 key: "autoScaleY", 11850 value: function autoScaleY(ctx, e) { 11851 if (!ctx) { 11852 ctx = this; 11853 } 11854 11855 var ret = []; 11856 ctx.w.config.series.forEach(function (serie) { 11857 var min, max; 11858 var first = serie.data.find(function (x) { 11859 return x[0] >= e.xaxis.min; 11860 }); 11861 var firstValue = first[1]; 11862 max = min = firstValue; 11863 serie.data.forEach(function (data) { 11864 if (data[0] <= e.xaxis.max && data[0] >= e.xaxis.min) { 11865 if (data[1] > max && data[1] !== null) max = data[1]; 11866 if (data[1] < min && data[1] !== null) min = data[1]; 11867 } 11868 }); 11869 min *= 0.95; 11870 max *= 1.05; 11871 ret.push({ 11872 min: min, 11873 max: max 11874 }); 11875 }); 11876 return ret; 11877 } 11878 }]); 11879 11880 return Range; 11881 }(); 11882 11883 /** 11884 * Range is used to generates values between min and max. 11885 * 11886 * @module Range 11887 **/ 11888 11889 var Range$1 = 11890 /*#__PURE__*/ 11891 function () { 11892 function Range$$1(ctx) { 11893 _classCallCheck(this, Range$$1); 11894 11895 this.ctx = ctx; 11896 this.w = ctx.w; 11897 this.scales = new Range(ctx); 11898 } 11899 11900 _createClass(Range$$1, [{ 11901 key: "init", 11902 value: function init() { 11903 this.setYRange(); 11904 this.setXRange(); 11905 this.setZRange(); 11906 } 11907 }, { 11908 key: "getMinYMaxY", 11909 value: function getMinYMaxY(startingIndex) { 11910 var lowestY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.MAX_VALUE; 11911 var highestY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -Number.MAX_VALUE; 11912 var len = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 11913 var gl = this.w.globals; 11914 var maxY = -Number.MAX_VALUE; 11915 var minY = Number.MIN_VALUE; 11916 11917 if (len === null) { 11918 len = startingIndex + 1; 11919 } 11920 11921 var series = gl.series; 11922 var seriesMin = series; 11923 var seriesMax = series; 11924 11925 if (this.w.config.chart.type === 'candlestick') { 11926 seriesMin = gl.seriesCandleL; 11927 seriesMax = gl.seriesCandleH; 11928 } else if (gl.isRangeData) { 11929 seriesMin = gl.seriesRangeStart; 11930 seriesMax = gl.seriesRangeEnd; 11931 } 11932 11933 for (var i = startingIndex; i < len; i++) { 11934 gl.dataPoints = Math.max(gl.dataPoints, series[i].length); 11935 11936 for (var j = 0; j < gl.series[i].length; j++) { 11937 var val = series[i][j];
11938 11939 if (val !== null && Utils.isNumber(val)) { 11940 maxY = Math.max(maxY, seriesMax[i][j]); 11941 lowestY = Math.min(lowestY, seriesMin[i][j]); 11942 highestY = Math.max(highestY, seriesMin[i][j]); 11943 11944 if (this.w.config.chart.type === 'candlestick') { 11945 maxY = Math.max(maxY, gl.seriesCandleO[i][j]); 11946 maxY = Math.max(maxY, gl.seriesCandleH[i][j]); 11947 maxY = Math.max(maxY, gl.seriesCandleL[i][j]); 11948 maxY = Math.max(maxY, gl.seriesCandleC[i][j]); 11949 highestY = maxY; 11950 } 11951 11952 if (Utils.isFloat(val)) { 11953 val = Utils.noExponents(val); 11954 gl.yValueDecimal = Math.max(gl.yValueDecimal, val.toString().split('.')[1].length); 11955 } 11956 11957 if (minY > seriesMin[i][j] && seriesMin[i][j] < 0) { 11958 minY = seriesMin[i][j]; 11959 } 11960 } else { 11961 gl.hasNullValues = true; 11962 } 11963 } 11964 } 11965 11966 return { 11967 minY: minY, 11968 maxY: maxY, 11969 lowestY: lowestY, 11970 highestY: highestY 11971 }; 11972 } 11973 }, { 11974 key: "setYRange", 11975 value: function setYRange() { 11976 var gl = this.w.globals; 11977 var cnf = this.w.config; 11978 gl.maxY = -Number.MAX_VALUE; 11979 gl.minY = Number.MIN_VALUE; 11980 var lowestYInAllSeries = Number.MAX_VALUE; 11981 11982 if (gl.isMultipleYAxis) { 11983 // we need to get minY and maxY for multiple y axis 11984 for (var i = 0; i < gl.series.length; i++) { 11985 var minYMaxYArr = this.getMinYMaxY(i, lowestYInAllSeries, null, i + 1); 11986 gl.minYArr.push(minYMaxYArr.minY); 11987 gl.maxYArr.push(minYMaxYArr.maxY); 11988 lowestYInAllSeries = minYMaxYArr.lowestY; 11989 } 11990 } // and then, get the minY and maxY from all series 11991 11992 11993 var minYMaxY = this.getMinYMaxY(0, lowestYInAllSeries, null, gl.series.length); 11994 gl.minY = minYMaxY.minY; 11995 gl.maxY = minYMaxY.maxY; 11996 lowestYInAllSeries = minYMaxY.lowestY; 11997 11998 if (cnf.chart.stacked) { 11999 // for stacked charts, we calculate each series's parallel values. i.e, series[0][j] + series[1][j] .... [series[i.length][j]] and get the max out of it 12000 var stackedPoss = []; 12001 var stackedNegs = []; 12002 12003 for (var j = 0; j < gl.series[gl.maxValsInArrayIndex].length; j++) { 12004 var poss = 0; 12005 var negs = 0; 12006 12007 for (var _i = 0; _i < gl.series.length; _i++) { 12008 if (gl.series[_i][j] !== null && Utils.isNumber(gl.series[_i][j])) { 12009 if (gl.series[_i][j] > 0) { 12010 // 0.0001 fixes #185 when values are very small 12011 poss = poss + parseFloat(gl.series[_i][j]) + 0.0001; 12012 } else { 12013 negs = negs + parseFloat(gl.series[_i][j]); 12014 } 12015 } 12016 12017 if (_i === gl.series.length - 1) { 12018 // push all the totals to the array for future use 12019 stackedPoss.push(poss); 12020 stackedNegs.push(negs); 12021 } 12022 } 12023 } // get the max/min out of the added parallel values 12024 12025 12026 for (var z = 0; z < stackedPoss.length; z++) { 12027 gl.maxY = Math.max(gl.maxY, stackedPoss[z]); 12028 gl.minY = Math.min(gl.minY, stackedNegs[z]); 12029 } 12030 } // if the numbers are too big, reduce the range 12031 // for eg, if number is between 100000-110000, putting 0 as the lowest value is not so good idea. So change the gl.minY for line/area/candlesticks 12032 12033 12034 if (cnf.chart.type === 'line' || cnf.chart.type === 'area' || cnf.chart.type === 'candlestick') { 12035 if (gl.minY === Number.MIN_VALUE && lowestYInAllSeries !== -Number.MAX_VALUE && lowestYInAllSeries !== gl.maxY // single value possibility 12036 ) { 12037 var diff = gl.maxY - lowestYInAllSeries; 12038 12039 if (lowestYInAllSeries >= 0 && lowestYInAllSeries <= 10) { 12040 // if minY is already 0/low value, we don't want to go negatives here - so this check is essential. 12041 diff = 0; 12042 } 12043 12044 gl.minY = lowestYInAllSeries - diff * 5 / 100; 12045 /* fix https://github.com/apexcharts/apexcharts.js/issues/426 */ 12046 12047 gl.maxY = gl.maxY + diff * 5 / 100; 12048 } 12049 } 12050 12051 cnf.yaxis.map(function (yaxe, index) { 12052 // override all min/max values by user defined values (y axis) 12053 if (yaxe.max !== undefined) { 12054 if (typeof yaxe.max === 'number') { 12055 gl.maxYArr[index] = yaxe.max; 12056 } else if (typeof yaxe.max === 'function') { 12057 gl.maxYArr[index] = yaxe.max(gl.maxY); 12058 } // gl.maxY is for single y-axis chart, it will be ignored in multi-yaxis 12059 12060 12061 gl.maxY = gl.maxYArr[index]; 12062 } 12063 12064 if (yaxe.min !== undefined) { 12065 if (typeof yaxe.min === 'number') { 12066 gl.minYArr[index] = yaxe.min; 12067 } else if (typeof yaxe.min === 'function') { 12068 gl.minYArr[index] = yaxe.min(gl.minY); 12069 } // gl.minY is for single y-axis chart, it will be ignored in multi-yaxis 12070 12071 12072 gl.minY = gl.minYArr[index]; 12073 } 12074 }); // for horizontal bar charts, we need to check xaxis min/max as user may have specified there 12075 12076 if (gl.isBarHorizontal) { 12077 if (cnf.xaxis.min !== undefined && typeof cnf.xaxis.min === 'number') { 12078 gl.minY = cnf.xaxis.min; 12079 } 12080 12081 if (cnf.xaxis.max !== undefined && typeof cnf.xaxis.max === 'number') { 12082 gl.maxY = cnf.xaxis.max; 12083 } 12084 } // for multi y-axis we need different scales for each 12085 12086 12087 if (gl.isMultipleYAxis) { 12088 this.scales.setMultipleYScales(); 12089 gl.minY = lowestYInAllSeries; 12090 gl.yAxisScale.forEach(function (scale, i) { 12091 gl.minYArr[i] = scale.niceMin; 12092 gl.maxYArr[i] = scale.niceMax; 12093 }); 12094 } else { 12095 this.scales.setYScaleForIndex(0, gl.minY, gl.maxY); 12096 gl.minY = gl.yAxisScale[0].niceMin; 12097 gl.maxY = gl.yAxisScale[0].niceMax; 12098 gl.minYArr[0] = gl.yAxisScale[0].niceMin; 12099 gl.maxYArr[0] = gl.yAxisScale[0].niceMax; 12100 } 12101 12102 return { 12103 minY: gl.minY, 12104 maxY: gl.maxY, 12105 minYArr: gl.minYArr, 12106 maxYArr: gl.maxYArr 12107 }; 12108 } 12109 }, { 12110 key: "setXRange", 12111 value: function setXRange() { 12112 var gl = this.w.globals; 12113 var cnf = this.w.config; 12114 var isXNumeric = cnf.xaxis.type === 'numeric' || cnf.xaxis.type === 'datetime' || cnf.xaxis.type === 'category' && !gl.noLabelsProvi
12114ded || gl.noLabelsProvided || gl.isXNumeric; // minX maxX starts here 12115 12116 if (gl.isXNumeric) { 12117 for (var i = 0; i < gl.series.length; i++) { 12118 if (gl.labels[i]) { 12119 for (var j = 0; j < gl.labels[i].length; j++) { 12120 if (gl.labels[i][j] !== null && Utils.isNumber(gl.labels[i][j])) { 12121 gl.maxX = Math.max(gl.maxX, gl.labels[i][j]); 12122 gl.initialmaxX = Math.max(gl.maxX, gl.labels[i][j]); 12123 gl.minX = Math.min(gl.minX, gl.labels[i][j]); 12124 gl.initialminX = Math.min(gl.minX, gl.labels[i][j]); 12125 } 12126 } 12127 } 12128 } 12129 } 12130 12131 if (gl.noLabelsProvided) { 12132 if (cnf.xaxis.categories.length === 0) { 12133 gl.maxX = gl.labels[gl.labels.length - 1]; 12134 gl.initialmaxX = gl.labels[gl.labels.length - 1]; 12135 gl.minX = 1; 12136 gl.initialminX = 1; 12137 } 12138 } // for numeric xaxis, we need to adjust some padding left and right for bar charts 12139 12140 12141 if (gl.comboChartsHasBars || cnf.chart.type === 'candlestick' || cnf.chart.type === 'bar' && gl.isXNumeric) { 12142 if (cnf.xaxis.type !== 'category' || gl.isXNumeric) { 12143 var minX = gl.minX - gl.svgWidth / gl.dataPoints * (Math.abs(gl.maxX - gl.minX) / gl.svgWidth) / 2; 12144 gl.minX = minX; 12145 gl.initialminX = minX; 12146 var maxX = gl.maxX + gl.svgWidth / gl.dataPoints * (Math.abs(gl.maxX - gl.minX) / gl.svgWidth) / 2; 12147 gl.maxX = maxX; 12148 gl.initialmaxX = maxX; 12149 } 12150 } 12151 12152 if ((gl.isXNumeric || gl.noLabelsProvided) && (!cnf.xaxis.convertedCatToNumeric || gl.dataFormatXNumeric)) { 12153 var ticks; 12154 12155 if (cnf.xaxis.tickAmount === undefined) { 12156 ticks = Math.round(gl.svgWidth / 150); // no labels provided and total number of dataPoints is less than 20 12157 12158 if (cnf.xaxis.type === 'numeric' && gl.dataPoints < 20) { 12159 ticks = gl.dataPoints - 1; 12160 } // this check is for when ticks exceeds total datapoints and that would result in duplicate labels 12161 12162 12163 if (ticks > gl.dataPoints && gl.dataPoints !== 0) { 12164 ticks = gl.dataPoints - 1; 12165 } 12166 } else if (cnf.xaxis.tickAmount === 'dataPoints') { 12167 ticks = gl.series[gl.maxValsInArrayIndex].length - 1; 12168 } else { 12169 ticks = cnf.xaxis.tickAmount; 12170 } // override all min/max values by user defined values (x axis) 12171 12172 12173 if (cnf.xaxis.max !== undefined && typeof cnf.xaxis.max === 'number') { 12174 gl.maxX = cnf.xaxis.max; 12175 } 12176 12177 if (cnf.xaxis.min !== undefined && typeof cnf.xaxis.min === 'number') { 12178 gl.minX = cnf.xaxis.min; 12179 } // if range is provided, adjust the new minX 12180 12181 12182 if (cnf.xaxis.range !== undefined) { 12183 gl.minX = gl.maxX - cnf.xaxis.range; 12184 } 12185 12186 if (gl.minX !== Number.MAX_VALUE && gl.maxX !== -Number.MAX_VALUE) { 12187 gl.xAxisScale = this.scales.linearScale(gl.minX, gl.maxX, ticks); 12188 } else { 12189 gl.xAxisScale = this.scales.linearScale(1, ticks, ticks); 12190 12191 if (gl.noLabelsProvided && gl.labels.length > 0) { 12192 gl.xAxisScale = this.scales.linearScale(1, gl.labels.length, ticks - 1); // this is the only place seriesX is again mutated 12193 12194 gl.seriesX = gl.labels.slice(); 12195 } 12196 } // we will still store these labels as the count for this will be different (to draw grid and labels placement) 12197 12198 12199 if (isXNumeric) { 12200 gl.labels = gl.xAxisScale.result.slice(); 12201 } 12202 } 12203 12204 if (gl.minX === gl.maxX) { 12205 // single dataPoint 12206 if (cnf.xaxis.type === 'datetime') { 12207 var newMinX = new Date(gl.minX); 12208 newMinX.setDate(newMinX.getDate() - 2); 12209 gl.minX = new Date(newMinX).getTime(); 12210 var newMaxX = new Date(gl.maxX); 12211 newMaxX.setDate(newMaxX.getDate() + 2); 12212 gl.maxX = new Date(newMaxX).getTime(); 12213 } else if (cnf.xaxis.type === 'numeric' || cnf.xaxis.type === 'category' && !gl.noLabelsProvi
12213ded) { 12214 gl.minX = gl.minX - 2; 12215 gl.maxX = gl.maxX + 2; 12216 } 12217 } 12218 12219 if (gl.isXNumeric) { 12220 // get the least x diff if numeric x axis is present 12221 gl.seriesX.forEach(function (sX, i) { 12222 sX.forEach(function (s, j) { 12223 if (j > 0) { 12224 var xDiff = s - gl.seriesX[i][j - 1]; 12225 gl.minXDiff = Math.min(xDiff, gl.minXDiff); 12226 } 12227 }); 12228 }); 12229 this.calcMinXDiffForTinySeries(); 12230 } 12231 12232 return { 12233 minX: gl.minX, 12234 maxX: gl.maxX 12235 }; 12236 } 12237 }, { 12238 key: "calcMinXDiffForTinySeries", 12239 value: function calcMinXDiffForTinySeries() { 12240 var w = this.w; 12241 var len = w.globals.labels.length; 12242 12243 if (w.globals.labels.length === 1) { 12244 w.globals.minXDiff = (w.globals.maxX - w.globals.minX) / len / 3; 12245 } else { 12246 if (w.globals.minXDiff === Number.MAX_VALUE) { 12247 // possibly a single dataPoint (fixes react-apexcharts/issue#34) 12248 if (w.globals.timelineLabels.length > 0) { 12249 len = w.globals.timelineLabels.length; 12250 } 12251 12252 if (len < 3) { 12253 len = 3; 12254 } 12255 12256 w.globals.minXDiff = (w.globals.maxX - w.globals.minX) / len; 12257 } 12258 } 12259 12260 return w.globals.minXDiff; 12261 } 12262 }, { 12263 key: "setZRange", 12264 value: function setZRange() { 12265 var gl = this.w.globals; // minZ, maxZ starts here 12266 12267 if (gl.isDataXYZ) { 12268 for (var i = 0; i < gl.series.length; i++) { 12269 if (typeof gl.seriesZ[i] !== 'undefined') { 12270 for (var j = 0; j < gl.seriesZ[i].length; j++) { 12271 if (gl.seriesZ[i][j] !== null && Utils.isNumber(gl.seriesZ[i][j])) { 12272 gl.maxZ = Math.max(gl.maxZ, gl.seriesZ[i][j]); 12273 gl.minZ = Math.min(gl.minZ, gl.seriesZ[i][j]); 12274 } 12275 } 12276 } 12277 } 12278 } 12279 } 12280 }]); 12281 12282 return Range$$1; 12283 }(); 12284 12285 /** 12286 * ApexCharts Series Class for interation with the Series of the chart. 12287 * 12288 * @module Series 12289 **/ 12290 12291 var Series = 12292 /*#__PURE__*/ 12293 function () { 12294 function Series(ctx) { 12295 _classCallCheck(this, Series); 12296 12297 this.ctx = ctx; 12298 this.w = ctx.w; 12299 } 12300 12301 _createClass(Series, [{ 12302 key: "getAllSeriesEls", 12303 value: function getAllSeriesEls() { 12304 return this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series"); 12305 } 12306 }, { 12307 key: "getSeriesByName", 12308 value: function getSeriesByName(seriesName) { 12309 return this.w.globals.dom.baseEl.querySelector("[seriesName='".concat(Utils.escapeString(seriesName), "']")); 12310 } 12311 }, { 12312 key: "addCollapsedClassToSeries", 12313 value: function addCollapsedClassToSeries(elSeries, index) { 12314 var w = this.w; 12315 12316 function iterateOnAllCollapsedSeries(series) { 12317 for (var cs = 0; cs < series.length; cs++) { 12318 if (series[cs].index === index) { 12319 elSeries.node.classList.add('apexcharts-series-collapsed'); 12320 } 12321 } 12322 } 12323 12324 iterateOnAllCollapsedSeries(w.globals.collapsedSeries); 12325 iterateOnAllCollapsedSeries(w.globals.ancillaryCollapsedSeries); 12326 } 12327 }, { 12328 key: "toggleSeriesOnHover", 12329 value: function toggleSeriesOnHover(e, targetElement) { 12330 var w = this.w; 12331 var allSeriesEls = w.globals.dom.baseEl.querySelectorAll(".apexcharts-series"); 12332 12333 if (e.type === 'mousemove') { 12334 var seriesCnt = parseInt(targetElement.getAttribute('rel')) - 1; 12335 var seriesEl = null; 12336 12337 if (w.globals.axisCharts || w.config.chart.type === 'radialBar') { 12338 if (w.globals.axisCharts) { 12339 seriesEl = w.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(seriesCnt, "']")); 12340 } else { 12341 seriesEl = w.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(seriesCnt + 1, "']")); 12342 } 12343 } else { 12344 seriesEl = w.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(seriesCnt + 1, "'] path")); 12345 } 12346 12347 for (var se = 0; se < allSeriesEls.length; se++) { 12348 allSeriesEls[se].classList.add('legend-mouseover-inactive'); 12349 } 12350 12351 if (seriesEl !== null) { 12352 if (!w.globals.axisCharts) { 12353 seriesEl.parentNode.classList.remove('legend-mouseover-inactive'); 12354 } 12355 12356 seriesEl.classList.remove('legend-mouseover-inactive'); 12357 } 12358 } else if (e.type === 'mouseout') { 12359 for (var _se = 0; _se < allSeriesEls.length; _se++) { 12360 allSeriesEls[_se].classList.remove('legend-mouseover-inactive'); 12361 } 12362 } 12363 } 12364 }, { 12365 key: "highlightRangeInSeries", 12366 value: function highlightRangeInSeries(e, targetElement) { 12367 var w = this.w; 12368 var allHeatMapElements = w.globals.dom.baseEl.querySelectorAll('.apexcharts-heatmap-rect'); 12369 12370 var allActive = function allActive() { 12371 for (var i = 0; i < allHeatMapElements.length; i++) { 12372 allHeatMapElements[i].classList.remove('legend-mouseover-inactive'); 12373 } 12374 }; 12375 12376 var allInactive = function allInactive() { 12377 for (var i = 0; i < allHeatMapElements.length; i++) { 12378 allHeatMapElements[i].classList.add('legend-mouseover-inactive'); 12379 } 12380 }; 12381 12382 var selectedActive = function selectedActive(range) { 12383 for (var i = 0; i < allHeatMapElements.length; i++) { 12384 var val = parseInt(allHeatMapElements[i].getAttribute('val')); 12385 12386 if (val >= range.from && val <= range.to) { 12387 allHeatMapElements[i].classList.remove('legend-mouseover-inactive'); 12388 } 12389 } 12390 }; 12391 12392 if (e.type === 'mousemove') { 12393 var seriesCnt = parseInt(targetElement.getAttribute('rel')) - 1; 12394 allActive(); 12395 allInactive(); 12396 var range = w.config.plotOptions.heatmap.colorScale.ranges[seriesCnt]; 12397 selectedActive(range); 12398 } else if (e.type === 'mouseout') { 12399 allActive(); 12400 } 12401 } 12402 }, { 12403 key: "getActiveSeriesIndex", 12404 value: function getActiveSeriesIndex() { 12405 var w = this.w; 12406 var activeIndex = 0; 12407 12408 if (w.globals.series.length > 1) { 12409 // active series flag is required to know if user has not deactivated via legend click 12410 var firstActiveSeriesIndex = w.globals.series.map(function (series, index) { 12411 if (series.length > 0 && w.config.series[index].type !== 'bar' && w.config.series[index].type !== 'column') { 12412 return index; 12413 } else { 12414 return -1; 12415 } 12416 }); 12417 12418 for (var a = 0; a < firstActiveSeriesIndex.length; a++) { 12419 if (firstActiveSeriesIndex[a] !== -1) { 12420 activeIndex = firstActiveSeriesIndex[a]; 12421 break; 12422 } 12423 } 12424 } 12425 12426 return activeIndex; 12427 } 12428 }, { 12429 key: "getActiveConfigSeriesIndex", 12430 value: function getActiveConfigSeriesIndex() { 12431 var w = this.w; 12432 var activeIndex = 0; 12433 12434 if (w.config.series.length > 1) { 12435 // active series flag is required to know if user has not deactivated via legend click 12436 var firstActiveSeriesIndex = w.config.series.map(function (series, index) { 12437 if (series.data && series.data.length > 0) { 12438 return index; 12439 } else { 12440 return -1; 12441 } 12442 }); 12443 12444 for (var a = 0; a < firstActiveSeriesIndex.length; a++) { 12445 if (firstActiveSeriesIndex[a] !== -1) { 12446 activeIndex = firstActiveSeriesIndex[a]; 12447 break; 12448 } 12449 } 12450 } 12451 12452 return activeIndex; 12453 } 12454 }, { 12455 key: "getPreviousPaths", 12456 value: function getPreviousPaths() { 12457 var w = this.w; 12458 w.globals.previousPaths = []; 12459 12460 function pushPaths(seriesEls, i, type) { 12461 var paths = seriesEls[i].childNodes; 12462 var dArr = { 12463 type: type, 12464 paths: [], 12465 realIndex: seriesEls[i].getAttribute('data:realIndex') 12466 }; 12467 12468 for (var j = 0; j < paths.length; j++) { 12469 if (paths[j].hasAttribute('pathTo')) { 12470 var d = paths[j].getAttribute('pathTo'); 12471 dArr.paths.push({ 12472 d: d 12473 }); 12474 } 12475 } 12476 12477 w.globals.previousPaths.push(dArr); 12478 } 12479 12480 var linePaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-line-series .apexcharts-series'); 12481 12482 if (linePaths.length > 0) { 12483 for (var p = linePaths.length - 1; p >= 0; p--) { 12484 pushPaths(linePaths, p, 'line'); 12485 } 12486 } 12487 12488 var areapaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-area-series .apexcharts-series'); 12489 12490 if (areapaths.length > 0) { 12491 for (var i = areapaths.length - 1; i >= 0; i--) { 12492 pushPaths(areapaths, i, 'area'); 12493 } 12494 } 12495 12496 var barPaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-bar-series .apexcharts-series'); 12497 12498 if (barPaths.length > 0) { 12499 for (var _p = 0; _p < barPaths.length; _p++) { 12500 pushPaths(barPaths, _p, 'bar'); 12501 } 12502 } 12503 12504 var candlestickPaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-candlestick-series .apexcharts-series'); 12505 12506 if (candlestickPaths.length > 0) { 12507 for (var _p2 = 0; _p2 < candlestickPaths.length; _p2++) { 12508 pushPaths(candlestickPaths, _p2, 'candlestick'); 12509 } 12510 } 12511 12512 var radarPaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-radar-series .apexcharts-series'); 12513 12514 if (radarPaths.length > 0) { 12515 for (var _p3 = 0; _p3 < radarPaths.length; _p3++) { 12516 pushPaths(radarPaths, _p3, 'radar'); 12517 } 12518 } 12519 12520 var bubblepaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-bubble-series .apexcharts-series'); 12521 12522 if (bubblepaths.length > 0) { 12523 for (var s = 0; s < bubblepaths.length; s++) { 12524 var seriesEls = w.globals.dom.baseEl.querySelectorAll(".apexcharts-bubble-series .apexcharts-series[data\\:realIndex='".concat(s, "'] circle"));
12525 var dArr = []; 12526 12527 for (var _i = 0; _i < seriesEls.length; _i++) { 12528 dArr.push({ 12529 x: seriesEls[_i].getAttribute('cx'), 12530 y: seriesEls[_i].getAttribute('cy'), 12531 r: seriesEls[_i].getAttribute('r') 12532 }); 12533 } 12534 12535 w.globals.previousPaths.push(dArr); 12536 } 12537 } 12538 12539 var scatterpaths = w.globals.dom.baseEl.querySelectorAll('.apexcharts-scatter-series .apexcharts-series'); 12540 12541 if (scatterpaths.length > 0) { 12542 for (var _s = 0; _s < scatterpaths.length; _s++) { 12543 var _seriesEls = w.globals.dom.baseEl.querySelectorAll(".apexcharts-scatter-series .apexcharts-series[data\\:realIndex='".concat(_s, "'] circle")); 12544 12545 var _dArr = []; 12546 12547 for (var _i2 = 0; _i2 < _seriesEls.length; _i2++) { 12548 _dArr.push({ 12549 x: _seriesEls[_i2].getAttribute('cx'), 12550 y: _seriesEls[_i2].getAttribute('cy'), 12551 r: _seriesEls[_i2].getAttribute('r') 12552 }); 12553 } 12554 12555 w.globals.previousPaths.push(_dArr); 12556 } 12557 } 12558 12559 var heatmapColors = w.globals.dom.baseEl.querySelectorAll('.apexcharts-heatmap .apexcharts-series'); 12560 12561 if (heatmapColors.length > 0) { 12562 for (var h = 0; h < heatmapColors.length; h++) { 12563 var _seriesEls2 = w.globals.dom.baseEl.querySelectorAll(".apexcharts-heatmap .apexcharts-series[data\\:realIndex='".concat(h, "'] rect")); 12564 12565 var _dArr2 = []; 12566 12567 for (var _i3 = 0; _i3 < _seriesEls2.length; _i3++) { 12568 _dArr2.push({ 12569 color: _seriesEls2[_i3].getAttribute('color') 12570 }); 12571 } 12572 12573 w.globals.previousPaths.push(_dArr2); 12574 } 12575 } 12576 12577 if (!w.globals.axisCharts) { 12578 // for non-axis charts (i.e., circular charts, pathFrom is not usable. We need whole series) 12579 w.globals.previousPaths = w.globals.series; 12580 } 12581 } 12582 }, { 12583 key: "handleNoData", 12584 value: function handleNoData() { 12585 var w = this.w; 12586 var me = this; 12587 var noDataOpts = w.config.noData; 12588 var graphics = new Graphics(me.ctx); 12589 var x = w.globals.svgWidth / 2; 12590 var y = w.globals.svgHeight / 2; 12591 var textAnchor = 'middle'; 12592 w.globals.noData = true; 12593 w.globals.animationEnded = true; 12594 12595 if (noDataOpts.align === 'left') { 12596 x = 10; 12597 textAnchor = 'start'; 12598 } else if (noDataOpts.align === 'right') { 12599 x = w.globals.svgWidth - 10; 12600 textAnchor = 'end'; 12601 } 12602 12603 if (noDataOpts.verticalAlign === 'top') { 12604 y = 50; 12605 } else if (noDataOpts.verticalAlign === 'bottom') { 12606 y = w.globals.svgHeight - 50; 12607 } 12608 12609 x = x + noDataOpts.offsetX; 12610 y = y + parseInt(noDataOpts.style.fontSize) + 2; 12611 12612 if (noDataOpts.text !== undefined && noDataOpts.text !== '') { 12613 var titleText = graphics.drawText({ 12614 x: x, 12615 y: y, 12616 text: noDataOpts.text, 12617 textAnchor: textAnchor, 12618 fontSize: noDataOpts.style.fontSize, 12619 fontFamily: noDataOpts.style.fontFamily, 12620 foreColor: noDataOpts.style.color, 12621 opacity: 1, 12622 class: 'apexcharts-text-nodata' 12623 }); 12624 titleText.node.setAttribute('class', 'apexcharts-title-text'); 12625 w.globals.dom.Paper.add(titleText); 12626 } 12627 } // When user clicks on legends, the collapsed series is filled with [0,0,0,...,0] 12628 // This is because we don't want to alter the series' length as it is used at many places 12629 12630 }, { 12631 key: "setNullSeriesToZeroValues", 12632 value: function setNullSeriesToZeroValues(series) { 12633 var w = this.w; 12634 12635 for (var sl = 0; sl < series.length; sl++) { 12636 if (series[sl].length === 0) { 12637 for (var j = 0; j < series[w.globals.maxValsInArrayIndex].length; j++) { 12638 series[sl].push(0); 12639 } 12640 } 12641 } 12642 12643 return series; 12644 } 12645 }, { 12646 key: "hasAllSeriesEqualX", 12647 value: function hasAllSeriesEqualX() { 12648 var equalLen = true; 12649 var w = this.w; 12650 var filteredSerX = this.filteredSeriesX(); 12651 12652 for (var i = 0; i < filteredSerX.length - 1; i++) { 12653 if (filteredSerX[i][0] !== filteredSerX[i + 1][0]) { 12654 equalLen = false; 12655 break; 12656 } 12657 } 12658 12659 w.globals.allSeriesHasEqualX = equalLen; 12660 return equalLen; 12661 } 12662 }, { 12663 key: "filteredSeriesX", 12664 value: function filteredSeriesX() { 12665 var w = this.w; 12666 var filteredSeriesX = w.globals.seriesX.map(function (ser, index) { 12667 if (ser.length > 0) { 12668 return ser; 12669 } else { 12670 return []; 12671 } 12672 }); 12673 return filteredSeriesX; 12674 } 12675 }]); 12676 12677 return Series; 12678 }(); 12679 12680 /** 12681 * ApexCharts Dimensions Class for calculating rects of all elements that are drawn and will be drawn. 12682 * 12683 * @module Dimensions 12684 **/ 12685 12686 var Dimensions = 12687 /*#__PURE__*/ 12688 function () { 12689 function Dimensions(ctx) { 12690 _classCallCheck(this, Dimensions); 12691 12692 this.ctx = ctx; 12693 this.w = ctx.w; 12694 this.lgRect = {}; 12695 this.yAxisWidth = 0; 12696 this.xAxisHeight = 0; 12697 this.isSparkline = this.w.config.chart.sparkline.enabled; 12698 this.xPadRight = 0; 12699 this.xPadLeft = 0; 12700 } 12701 /** 12702 * @memberof Dimensions 12703 * @param {object} w - chart context 12704 **/ 12705 12706 12707 _createClass(Dimensions, [{ 12708 key: "plotCoords", 12709 value: function plotCoords() { 12710 var w = this.w; 12711 var gl = w.globals; 12712 var lgRect = this.getLegendsRect(); 12713 12714 if (gl.axisCharts) {
12715 // for line / area / scatter / column 12716 this.setGridCoordsForAxisCharts(lgRect); 12717 } else { 12718 // for pie / donuts / circle 12719 this.setGridCoordsForNonAxisCharts(lgRect); 12720 } 12721 12722 this.titleSubtitleOffset(); // after calculating everything, apply padding set by user 12723 12724 gl.gridHeight = gl.gridHeight - w.config.grid.padding.top - w.config.grid.padding.bottom; 12725 gl.gridWidth = gl.gridWidth - w.config.grid.padding.left - w.config.grid.padding.right - this.xPadRight - this.xPadLeft; 12726 gl.translateX = gl.translateX + w.config.grid.padding.left + this.xPadLeft; 12727 gl.translateY = gl.translateY + w.config.grid.padding.top; 12728 } 12729 }, { 12730 key: "conditionalChecksForAxisCoords", 12731 value: function conditionalChecksForAxisCoords(xaxisLabelCoords, xtitleCoords) { 12732 var w = this.w; 12733 this.xAxisHeight = (xaxisLabelCoords.height + xtitleCoords.height) * w.globals.LINE_HEIGHT_RATIO + 15; 12734 this.xAxisWidth = xaxisLabelCoords.width; 12735 12736 if (this.xAxisHeight - xtitleCoords.height > w.config.xaxis.labels.maxHeight) { 12737 this.xAxisHeight = w.config.xaxis.labels.maxHeight; 12738 } 12739 12740 if (w.config.xaxis.labels.minHeight && this.xAxisHeight < w.config.xaxis.labels.minHeight) { 12741 this.xAxisHeight = w.config.xaxis.labels.minHeight; 12742 } 12743 12744 if (w.config.xaxis.floating) { 12745 this.xAxisHeight = 0; 12746 } 12747 12748 if (!w.globals.isBarHorizontal) { 12749 this.yAxisWidth = this.getTotalYAxisWidth(); 12750 } else { 12751 this.yAxisWidth = w.globals.yLabelsCoords[0].width + w.globals.yTitleCoords[0].width + 15; 12752 } 12753 12754 var minYAxisWidth = 0; 12755 var maxYAxisWidth = 0; 12756 w.config.yaxis.forEach(function (y) { 12757 minYAxisWidth += y.labels.minWidth; 12758 maxYAxisWidth += y.labels.maxWidth; 12759 }); 12760 12761 if (this.yAxisWidth < minYAxisWidth) { 12762 this.yAxisWidth = minYAxisWidth; 12763 } 12764 12765 if (this.yAxisWidth > maxYAxisWidth) { 12766 this.yAxisWidth = maxYAxisWidth; 12767 } 12768 } 12769 }, { 12770 key: "setGridCoordsForAxisCharts", 12771 value: function setGridCoordsForAxisCharts(lgRect) { 12772 var w = this.w; 12773 var gl = w.globals; 12774 var yaxisLabelCoords = this.getyAxisLabelsCoords(); 12775 var xaxisLabelCoords = this.getxAxisLabelsCoords(); 12776 var yTitleCoords = this.getyAxisTitleCoords(); 12777 var xtitleCoords = this.getxAxisTitleCoords(); 12778 w.globals.yLabelsCoords = []; 12779 w.globals.yTitleCoords = []; 12780 w.config.yaxis.map(function (yaxe, index) { 12781 // store the labels and titles coords in global vars 12782 w.globals.yLabelsCoords.push({ 12783 width: yaxisLabelCoords[index].width, 12784 index: index 12785 }); 12786 w.globals.yTitleCoords.push({ 12787 width: yTitleCoords[index].width, 12788 index: index 12789 }); 12790 }); 12791 this.conditionalChecksForAxisCoords(xaxisLabelCoords, xtitleCoords);
12792 gl.translateXAxisY = w.globals.rotateXLabels ? this.xAxisHeight / 8 : -4; 12793 gl.translateXAxisX = w.globals.rotateXLabels && w.globals.isXNumeric && w.config.xaxis.labels.rotate <= -45 ? -this.xAxisWidth / 4 : 0; 12794 12795 if (w.globals.isBarHorizontal) { 12796 gl.rotateXLabels = false; 12797 gl.translateXAxisY = -1 * (parseInt(w.config.xaxis.labels.style.fontSize) / 1.5); 12798 } 12799 12800 gl.translateXAxisY = gl.translateXAxisY + w.config.xaxis.labels.offsetY; 12801 gl.translateXAxisX = gl.translateXAxisX + w.config.xaxis.labels.offsetX; 12802 var yAxisWidth = this.yAxisWidth; 12803 var xAxisHeight = this.xAxisHeight; 12804 gl.xAxisLabelsHeight = this.xAxisHeight; 12805 gl.xAxisHeight = this.xAxisHeight; 12806 var translateY = 10; 12807 12808 if (!w.config.grid.show || w.config.chart.type === 'radar') { 12809 yAxisWidth = 0; 12810 xAxisHeight = 35; 12811 } 12812 12813 if (this.isSparkline) { 12814 lgRect = { 12815 height: 0, 12816 width: 0 12817 }; 12818 xAxisHeight = 0; 12819 yAxisWidth = 0; 12820 translateY = 0; 12821 } 12822 12823 this.additionalPaddingXLabels(xaxisLabelCoords);
12824 12825 switch (w.config.legend.position) { 12826 case 'bottom': 12827 gl.translateY = translateY; 12828 gl.translateX = yAxisWidth; 12829 gl.gridHeight = gl.svgHeight - lgRect.height - xAxisHeight - (!this.isSparkline ? w.globals.rotateXLabels ? 10 : 15 : 0); 12830 gl.gridWidth = gl.svgWidth - yAxisWidth; 12831 break; 12832 12833 case 'top': 12834 gl.translateY = lgRect.height + translateY; 12835 gl.translateX = yAxisWidth; 12836 gl.gridHeight = gl.svgHeight - lgRect.height - xAxisHeight - (!this.isSparkline ? w.globals.rotateXLabels ? 10 : 15 : 0); 12837 gl.gridWidth = gl.svgWidth - yAxisWidth; 12838 break; 12839 12840 case 'left': 12841 gl.translateY = translateY; 12842 gl.translateX = lgRect.width + yAxisWidth; 12843 gl.gridHeight = gl.svgHeight - xAxisHeight - 12; 12844 gl.gridWidth = gl.svgWidth - lgRect.width - yAxisWidth; 12845 break; 12846 12847 case 'right': 12848 gl.translateY = translateY; 12849 gl.translateX = yAxisWidth; 12850 gl.gridHeight = gl.svgHeight - xAxisHeight - 12; 12851 gl.gridWidth = gl.svgWidth - lgRect.width - yAxisWidth - 5; 12852 break; 12853 12854 default: 12855 throw new Error('Legend position not supported'); 12856 } 12857 12858 this.setGridXPosForDualYAxis(yTitleCoords, yaxisLabelCoords); // after drawing everything, set the Y axis positions 12859 12860 var objyAxis = new YAxis(this.ctx); 12861 objyAxis.setYAxisXPosition(yaxisLabelCoords, yTitleCoords);
12862 } 12863 }, { 12864 key: "setGridCoordsForNonAxisCharts", 12865 value: function setGridCoordsForNonAxisCharts(lgRect) { 12866 var w = this.w; 12867 var gl = w.globals; 12868 var xPad = 0; 12869 12870 if (w.config.legend.show && !w.config.legend.floating) { 12871 xPad = 20; 12872 } 12873 12874 var offY = 10; 12875 var offX = 0; 12876 12877 if (w.config.chart.type === 'pie' || w.config.chart.type === 'donut') { 12878 offY = offY + w.config.plotOptions.pie.offsetY; 12879 offX = offX + w.config.plotOptions.pie.offsetX; 12880 } else if (w.config.chart.type === 'radialBar') { 12881 offY = offY + w.config.plotOptions.radialBar.offsetY; 12882 offX = offX + w.config.plotOptions.radialBar.offsetX; 12883 } 12884 12885 if (!w.config.legend.show) { 12886 gl.gridHeight = gl.svgHeight - 35; 12887 gl.gridWidth = gl.gridHeight; 12888 gl.translateY = offY - 10; 12889 gl.translateX = offX + (gl.svgWidth - gl.gridWidth) / 2; 12890 return; 12891 } 12892 12893 switch (w.config.legend.position) { 12894 case 'bottom': 12895 gl.gridHeight = gl.svgHeight - lgRect.height - 35; 12896 gl.gridWidth = gl.gridHeight; 12897 gl.translateY = offY - 20; 12898 gl.translateX = offX + (gl.svgWidth - gl.gridWidth) / 2; 12899 break; 12900 12901 case 'top': 12902 gl.gridHeight = gl.svgHeight - lgRect.height - 35; 12903 gl.gridWidth = gl.gridHeight; 12904 gl.translateY = lgRect.height + offY; 12905 gl.translateX = offX + (gl.svgWidth - gl.gridWidth) / 2; 12906 break; 12907 12908 case 'left': 12909 gl.gridWidth = gl.svgWidth - lgRect.width - xPad; 12910 gl.gridHeight = gl.gridWidth; 12911 gl.translateY = offY; 12912 gl.translateX = offX + lgRect.width + xPad; 12913 break; 12914 12915 case 'right': 12916 gl.gridWidth = gl.svgWidth - lgRect.width - xPad - 5; 12917 gl.gridHeight = gl.gridWidth; 12918 gl.translateY = offY; 12919 gl.translateX = offX + 10; 12920 break; 12921 12922 default: 12923 throw new Error('Legend position not supported'); 12924 } 12925 } 12926 }, { 12927 key: "setGridXPosForDualYAxis", 12928 value: function setGridXPosForDualYAxis(yTitleCoords, yaxisLabelCoords) { 12929 var w = this.w; 12930 w.config.yaxis.map(function (yaxe, index) { 12931 if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1 && !w.config.yaxis[index].floating && w.config.yaxis[index].show) { 12932 if (yaxe.opposite) { 12933 w.globals.translateX = w.globals.translateX - (yaxisLabelCoords[index].width + yTitleCoords[index].width) - parseInt(w.config.yaxis[index].labels.style.fontSize) / 1.2 - 12; 12934 } 12935 } 12936 }); 12937 } // Sometimes, the last labels gets cropped in category/numeric xaxis. 12938 // Hence, we add some additional padding based on the label length to avoid the last label being cropped. 12939 // NOTE: datetime x-axis won't have any effect with this as we don't know the label length there due to many constraints. 12940 12941 }, { 12942 key: "additionalPaddingXLabels", 12943 value: function additionalPaddingXLabels(xaxisLabelCoords) { 12944 var _this = this; 12945 12946 var w = this.w; 12947 12948 if (w.config.xaxis.type === 'category' && w.globals.isBarHorizontal || w.config.xaxis.type === 'numeric' || w.config.xaxis.type === 'datetime') { 12949 var rightPad = function rightPad(labels) { 12950 if (_this.timescaleLabels) { 12951 // for timeline labels, we take the last label and check if it exceeds gridWidth 12952 var lastTimescaleLabel = _this.timescaleLabels[_this.timescaleLabels.length - 1]; 12953 var labelPosition = lastTimescaleLabel.position + labels.width; 12954 12955 if (labelPosition > w.globals.gridWidth) { 12956 w.globals.skipLastTimelinelabel = true; 12957 } else { 12958 // we have to make it false again in case of zooming/panning 12959 w.globals.skipLastTimelinelabel = false; 12960 } 12961 } else if (w.config.xaxis.type !== 'datetime') { 12962 if (w.config.grid.padding.right < labels.width) { 12963 _this.xPadRight = labels.width / 2 + 1; 12964 } 12965 } 12966 }; 12967 12968 var leftPad = function leftPad(labels) { 12969 if (w.config.grid.padding.left < labels.width) { 12970 _this.xPadLeft = labels.width / 2 + 1; 12971 } 12972 }; 12973 12974 var isXNumeric = w.globals.isXNumeric; 12975 w.config.yaxis.forEach(function (yaxe, i) { 12976 var shouldPad = !yaxe.show || yaxe.floating || w.globals.collapsedSeriesIndices.indexOf(i) !== -1 || isXNumeric || yaxe.opposite && w.globals.isBarHorizontal; 12977 12978 if (shouldPad) { 12979 if (isXNumeric && w.globals.isMultipleYAxis && w.globals.collapsedSeriesIndices.indexOf(i) !== -1 || w.globals.isBarHorizontal && yaxe.opposite) { 12980 leftPad(xaxisLabelCoords);
12981 } 12982 12983 if (!w.globals.isBarHorizontal && yaxe.opposite && w.globals.collapsedSeriesIndices.indexOf(i) !== -1 || isXNumeric && !w.globals.isMultipleYAxis) { 12984 rightPad(xaxisLabelCoords); 12985 } 12986 } 12987 }); 12988 } 12989 } 12990 }, { 12991 key: "titleSubtitleOffset", 12992 value: function titleSubtitleOffset() { 12993 var w = this.w; 12994 var gl = w.globals; 12995 var gridShrinkOffset = this.isSparkline || !w.globals.axisCharts ? 0 : 10; 12996 12997 if (w.config.title.text !== undefined) { 12998 gridShrinkOffset += w.config.title.margin; 12999 } else { 13000 gridShrinkOffset += this.isSparkline || !w.globals.axisCharts ? 0 : 5; 13001 } 13002 13003 if (w.config.subtitle.text !== undefined) { 13004 gridShrinkOffset += w.config.subtitle.margin; 13005 } else { 13006 gridShrinkOffset += this.isSparkline || !w.globals.axisCharts ? 0 : 5; 13007 } 13008 13009 if (w.config.legend.show && w.config.legend.position === 'bottom' && !w.config.legend.floating && w.config.series.length > 1) { 13010 gridShrinkOffset += 10; 13011 } 13012 13013 var titleCoords = this.getTitleSubtitleCoords('title'); 13014 var subtitleCoords = this.getTitleSubtitleCoords('subtitle'); 13015 gl.gridHeight = gl.gridHeight - titleCoords.height - subtitleCoords.height - gridShrinkOffset; 13016 gl.translateY = gl.translateY + titleCoords.height + subtitleCoords.height + gridShrinkOffset; 13017 } 13018 }, { 13019 key: "getTotalYAxisWidth", 13020 value: function getTotalYAxisWidth() { 13021 var w = this.w; 13022 var yAxisWidth = 0; 13023 var padding = 10; 13024 13025 var isHiddenYAxis = function isHiddenYAxis(index) { 13026 return w.globals.ignoreYAxisIndexes.indexOf(index) > -1; 13027 }; 13028 13029 w.globals.yLabelsCoords.map(function (yLabelCoord, index) { 13030 var floating = w.config.yaxis[index].floating; 13031 13032 if (yLabelCoord.width > 0 && !floating) { 13033 yAxisWidth = yAxisWidth + yLabelCoord.width + padding; 13034 13035 if (isHiddenYAxis(index)) { 13036 yAxisWidth = yAxisWidth - yLabelCoord.width - padding; 13037 } 13038 } else { 13039 yAxisWidth = yAxisWidth + (floating || !w.config.yaxis[index].show ? 0 : 5); 13040 } 13041 }); 13042 w.globals.yTitleCoords.map(function (yTitleCoord, index) { 13043 var floating = w.config.yaxis[index].floating; 13044 padding = parseInt(w.config.yaxis[index].title.style.fontSize); 13045 13046 if (yTitleCoord.width > 0 && !floating) { 13047 yAxisWidth = yAxisWidth + yTitleCoord.width + padding; 13048 13049 if (isHiddenYAxis(index)) { 13050 yAxisWidth = yAxisWidth - yTitleCoord.width - padding; 13051 } 13052 } else { 13053 yAxisWidth = yAxisWidth + (floating || !w.config.yaxis[index].show ? 0 : 5); 13054 } 13055 }); 13056 return yAxisWidth; 13057 } 13058 }, { 13059 key: "getxAxisTimeScaleLabelsCoords", 13060 value: function getxAxisTimeScaleLabelsCoords() { 13061 var w = this.w; 13062 var rect; 13063 this.timescaleLabels = w.globals.timelineLabels.slice(); 13064 13065 if (w.globals.isBarHorizontal && w.config.xaxis.type === 'datetime') { 13066 this.timescaleLabels = w.globals.invertedTimelineLabels.slice(); 13067 } 13068 13069 var labels = this.timescaleLabels.map(function (label) { 13070 return label.value; 13071 }); // get the longest string from the labels array and also apply label formatter to it 13072 13073 var val = labels.reduce(function (a, b) { 13074 // if undefined, maybe user didn't pass the datetime(x) values 13075 if (typeof a === 'undefined') { 13076 console.error('You have possibly supplied invalid Date format. Please supply a valid JavaScript Date'); 13077 return 0; 13078 } else { 13079 return a.length > b.length ? a : b; 13080 } 13081 }, 0); 13082 var graphics = new Graphics(this.ctx); 13083 rect = graphics.getTextRects(val, w.config.xaxis.labels.style.fontSize); 13084 var totalWidthRotated = rect.width * 1.05 * labels.length; 13085 13086 if (totalWidthRotated > w.globals.gridWidth && w.config.xaxis.labels.rotate !== 0) { 13087 w.globals.overlappingXLabels = true; 13088 } 13089 13090 return rect; 13091 } 13092 /** 13093 * Get X Axis Dimensions 13094 * @memberof Dimensions 13095 * @return {{width, height}} 13096 **/ 13097 13098 }, { 13099 key: "getxAxisLabelsCoords", 13100 value: function getxAxisLabelsCoords() { 13101 var w = this.w; 13102 var xaxisLabels = w.globals.labels.slice(); 13103 var rect; 13104 13105 if (w.globals.timelineLabels.length > 0) { 13106 var coords = this.getxAxisTimeScaleLabelsCoords(); 13107 rect = { 13108 width: coords.width, 13109 height: coords.height 13110 }; 13111 } else { 13112 var lgWidthForSideLegends = w.config.legend.position === 'left' && w.config.legend.position === 'right' && !w.config.legend.floating ? this.lgRect.width : 0; // get the longest string from the labels array and also apply label formatter 13113 13114 var xlbFormatter = w.globals.xLabelFormatter; // prevent changing xaxisLabels to avoid issues in multi-yaxies - fix #522 13115 13116 var val = xaxisLabels.reduce(function (a, b) { 13117 return a.length > b.length ? a : b; 13118 }, 0); // the labels gets changed for bar charts 13119 13120 if (w.globals.isBarHorizontal) { 13121 val = w.globals.yAxisScale[0].result.reduce(function (a, b) { 13122 return a.length > b.length ? a : b; 13123 }, 0); 13124 } 13125 13126 var xFormat = new Formatters(this.ctx); 13127 val = xFormat.xLabelFormat(xlbFormatter, val); 13128 var graphics = new Graphics(this.ctx); 13129 var xLabelrect = graphics.getTextRects(val, w.config.xaxis.labels.style.fontSize); 13130 rect = { 13131 width: xLabelrect.width, 13132 height: xLabelrect.height 13133 }; 13134 13135 if (rect.width * xaxisLabels.length > w.globals.svgWidth - lgWidthForSideLegends - this.yAxisWidth && w.config.xaxis.labels.rotate !== 0) { 13136 if (!w.globals.isBarHorizontal) { 13137 w.globals.rotateXLabels = true; 13138 xLabelrect = graphics.getTextRects(val, w.config.xaxis.labels.style.fontSize, w.c
13138onfig.xaxis.labels.style.fontFamily, "rotate(".concat(w.config.xaxis.labels.rotate, " 0 0)"), false); 13139 rect.height = xLabelrect.height / 1.66; 13140 } 13141 } else { 13142 w.globals.rotateXLabels = false; 13143 } 13144 } 13145 13146 if (!w.config.xaxis.labels.show) { 13147 rect = { 13148 width: 0, 13149 height: 0 13150 }; 13151 } 13152 13153 return { 13154 width: rect.width, 13155 height: rect.height 13156 }; 13157 } 13158 /** 13159 * Get Y Axis Dimensions 13160 * @memberof Dimensions 13161 * @return {{width, height}} 13162 **/ 13163 13164 }, { 13165 key: "getyAxisLabelsCoords", 13166 value: function getyAxisLabelsCoords() { 13167 var _this2 = this; 13168 13169 var w = this.w; 13170 var width = 0; 13171 var height = 0; 13172 var ret = []; 13173 var labelPad = 10; 13174 w.config.yaxis.map(function (yaxe, index) { 13175 if (yaxe.show && yaxe.labels.show && w.globals.yAxisScale[index].result.length) { 13176 var lbFormatter = w.globals.yLabelFormatters[index]; // the second parameter -1 is the index of tick which user can use in the formatter 13177 13178 var val = lbFormatter(w.globals.yAxisScale[index].niceMax, -1); // if user has specified a custom formatter, and the result is null or empty, we need to discard the formatter and take the value as it is. 13179 13180 if (typeof val === 'undefined' || val.length === 0) { 13181 val = w.globals.yAxisScale[index].niceMax; 13182 } 13183 13184 if (w.globals.isBarHorizontal) { 13185 labelPad = 0; 13186 var barYaxisLabels = w.globals.labels.slice(); // get the longest string from the labels array and also apply label formatter to it 13187 13188 val = barYaxisLabels.reduce(function (a, b) { 13189 return a.length > b.length ? a : b; 13190 }, 0); 13191 val = lbFormatter(val, -1); 13192 } 13193 13194 var graphics = new Graphics(_this2.ctx); 13195 var rect = graphics.getTextRects(val, yaxe.labels.style.fontSize); 13196 ret.push({ 13197 width: rect.width + labelPad, 13198 height: rect.height 13199 }); 13200 } else { 13201 ret.push({ 13202 width: width, 13203 height: height 13204 }); 13205 } 13206 }); 13207 return ret; 13208 } 13209 /** 13210 * Get X Axis Title Dimensions 13211 * @memberof Dimensions 13212 * @return {{width, height}} 13213 **/ 13214 13215 }, { 13216 key: "getxAxisTitleCoords", 13217 value: function getxAxisTitleCoords() { 13218 var w = this.w; 13219 var width = 0; 13220 var height = 0; 13221 13222 if (w.config.xaxis.title.text !== undefined) { 13223 var graphics = new Graphics(this.ctx); 13224 var rect = graphics.getTextRects(w.config.xaxis.title.text, w.config.xaxis.title.style.fontSize); 13225 width = rect.width; 13226 height = rect.height; 13227 } 13228 13229 return { 13230 width: width, 13231 height: height 13232 }; 13233 } 13234 /** 13235 * Get Y Axis Dimensions 13236 * @memberof Dimensions 13237 * @return {{width, height}} 13238 **/ 13239 13240 }, { 13241 key: "getyAxisTitleCoords", 13242 value: function getyAxisTitleCoords() { 13243 var _this3 = this; 13244 13245 var w = this.w; 13246 var ret = []; 13247 w.config.yaxis.map(function (yaxe, index) { 13248 if (yaxe.show && yaxe.title.text !== undefined) { 13249 var graphics = new Graphics(_this3.ctx); 13250 var rect = graphics.getTextRects(yaxe.title.text, yaxe.title.style.fontSize, yaxe.title.style.fontFamily, 'rotate(-90 0 0)', false); 13251 ret.push({ 13252 width: rect.width, 13253 height: rect.height 13254 }); 13255 } else { 13256 ret.push({ 13257 width: 0, 13258 height: 0 13259 }); 13260 } 13261 }); 13262 return ret; 13263 } 13264 /** 13265 * Get Chart Title/Subtitle Dimensions 13266 * @memberof Dimensions 13267 * @return {{width, height}} 13268 **/ 13269 13270 }, { 13271 key: "getTitleSubtitleCoords", 13272 value: function getTitleSubtitleCoords(type) { 13273 var w = this.w; 13274 var width = 0; 13275 var height = 0; 13276 var floating = type === 'title' ? w.config.title.floating : w.config.subtitle.floating; 13277 var el = w.globals.dom.baseEl.querySelector(".apexcharts-".concat(type, "-text")); 13278 13279 if (el !== null && !floating) { 13280 var coord = el.getBoundingClientRect(); 13281 width = coord.width; 13282 height = w.globals.axisCharts ? coord.height + 5 : coord.height; 13283 } 13284 13285 return { 13286 width: width, 13287 height: height 13288 }; 13289 } 13290 }, { 13291 key: "getLegendsRect", 13292 value: function getLegendsRect() { 13293 var w = this.w; 13294 var elLegendWrap = w.globals.dom.baseEl.querySelector('.apexcharts-legend'); 13295 var lgRect = Object.assign({}, Utils.getBoundingClientRect(elLegendWrap)); 13296 13297 if (elLegendWrap !== null && !w.config.legend.floating && w.config.legend.show) { 13298 this.lgRect = { 13299 x: lgRect.x, 13300 y: lgRect.y, 13301 height: lgRect.height, 13302 width: lgRect.height === 0 ? 0 : lgRect.width 13303 }; 13304 } else { 13305 this.lgRect = { 13306 x: 0, 13307 y: 0, 13308 height: 0, 13309 width: 0 13310 }; 13311 } 13312 13313 return this.lgRect; 13314 } 13315 }]); 13316 13317 return Dimensions; 13318 }(); 13319 13320 /** 13321 * ApexCharts TimeScale Class for generating time ticks for x-axis. 13322 * 13323 * @module TimeScale 13324 **/ 13325 13326 var TimeScale = 13327 /*#__PURE__*/ 13328 function () { 13329 function TimeScale(ctx) { 13330 _classCallCheck(this, TimeScale); 13331 13332 this.ctx = ctx; 13333 this.w = ctx.w; 13334 this.timeScaleArray = []; 13335 } 13336 13337 _createClass(TimeScale, [{ 13338 key: "calculateTimeScaleTicks", 13339 value: function calculateTimeScaleTicks(minX, maxX) { 13340 var _this = this; 13341 13342 var w = this.w; // null check when no series to show 13343 13344 if (w.globals.allSeriesCollapsed) { 13345 w.globals.labels = []; 13346 w.globals.timelineLabels = []; 13347 return []; 13348 } 13349 13350 var dt = new DateTime(this.ctx); 13351 var daysDiff = (maxX - minX) / (1000 * 60 * 60 * 24); 13352 this.determineInterval(daysDiff); 13353 w.globals.disableZoomIn = false; 13354 w.globals.disableZoomOut = false; 13355 13356 if (daysDiff < 0.005) { 13357 w.globals.disableZoomIn = true; 13358 } else if (daysDiff > 50000) { 13359 w.globals.disableZoomOut = true; 13360 } 13361 13362 var timeIntervals = dt.getTimeUnitsfromTimestamp(minX, maxX); 13363 var daysWidthOnXAxis = w.globals.gridWidth / daysDiff; 13364 var hoursWidthOnXAxis = daysWidthOnXAxis / 24; 13365 var minutesWidthOnXAxis = hoursWidthOnXAxis / 60; 13366 var numberOfHours = Math.floor(daysDiff * 24); 13367 var numberOfMinutes = Math.floor(daysDiff * 24 * 60); 13368 var numberOfDays = Math.floor(daysDiff); 13369 var numberOfMonths = Math.floor(daysDiff / 30); 13370 var numberOfYears = Math.floor(daysDiff / 365); 13371 var firstVal = { 13372 minMinute: timeIntervals.minMinute, 13373 minHour: timeIntervals.minHour, 13374 minDate: timeIntervals.minDate, 13375 minMonth: timeIntervals.minMonth, 13376 minYear: timeIntervals.minYear 13377 }; 13378 var currentMinute = firstVal.minMinute; 13379 var currentHour = firstVal.minHour; 13380 var currentMonthDate = firstVal.minDate; 13381 var currentDate = firstVal.minDate; 13382 var currentMonth = firstVal.minMonth; 13383 var currentYear = firstVal.minYear; 13384 var params = { 13385 firstVal: firstVal, 13386 currentMinute: currentMinute, 13387 currentHour: currentHour, 13388 currentMonthDate: currentMonthDate, 13389 currentDate: currentDate, 13390 currentMonth: currentMonth, 13391 currentYear: currentYear, 13392 daysWidthOnXAxis: daysWidthOnXAxis, 13393 hoursWidthOnXAxis: hoursWidthOnXAxis, 13394 minutesWidthOnXAxis: minutesWidthOnXAxis, 13395 numberOfMinutes: numberOfMinutes, 13396 numberOfHours: numberOfHours, 13397 numberOfDays: numberOfDays, 13398 numberOfMonths: numberOfMonths, 13399 numberOfYears: numberOfYears 13400 }; 13401 13402 switch (this.tickInterval) { 13403 case 'years': 13404 { 13405 this.generateYearScale(params); 13406 break; 13407 } 13408 13409 case 'months': 13410 case 'half_year': 13411 { 13412 this.generateMonthScale(params); 13413 break; 13414 } 13415 13416 case 'months_days': 13417 case 'months_fortnight': 13418 case 'days': 13419 case 'week_days': 13420 { 13421 this.generateDayScale(params); 13422 break; 13423 } 13424 13425 case 'hours': 13426 { 13427 this.generateHourScale(params); 13428 break; 13429 } 13430 13431 case 'minutes': 13432 this.generateMinuteScale(params); 13433 break; 13434 }
13434 // first, we will adjust the month values index 13435 // as in the upper function, it is starting from 0 13436 // we will start them from 1 13437 13438 13439 var adjustedMonthInTimeScaleArray = this.timeScaleArray.map(function (ts) { 13440 var defaultReturn = { 13441 position: ts.position, 13442 unit: ts.unit, 13443 year: ts.year, 13444 day: ts.day ? ts.day : 1, 13445 hour: ts.hour ? ts.hour : 0, 13446 month: ts.month + 1 13447 }; 13448 13449 if (ts.unit === 'month') { 13450 return _objectSpread({}, defaultReturn, { 13451 value: ts.value + 1 13452 }); 13453 } else if (ts.unit === 'day' || ts.unit === 'hour') { 13454 return _objectSpread({}, defaultReturn, { 13455 value: ts.value 13456 }); 13457 } else if (ts.unit === 'minute') { 13458 return _objectSpread({}, defaultReturn, { 13459 value: ts.value, 13460 minute: ts.value 13461 }); 13462 } 13463 13464 return ts; 13465 }); 13466 var filteredTimeScale = adjustedMonthInTimeScaleArray.filter(function (ts) { 13467 var modulo = 1; 13468 var ticks = Math.ceil(w.globals.gridWidth / 120); 13469 var value = ts.value; 13470 13471 if (w.config.xaxis.tickAmount !== undefined) { 13472 ticks = w.config.xaxis.tickAmount; 13473 } 13474 13475 if (adjustedMonthInTimeScaleArray.length > ticks) { 13476 modulo = Math.floor(adjustedMonthInTimeScaleArray.length / ticks); 13477 } 13478 13479 var shouldNotSkipUnit = false; // there is a big change in unit i.e days to months 13480 13481 var shouldNotPrint = false; // should skip these values 13482 13483 switch (_this.tickInterval) { 13484 case 'half_year': 13485 modulo = 7; 13486 13487 if (ts.unit === 'year') { 13488 shouldNotSkipUnit = true; 13489 } 13490 13491 break; 13492 13493 case 'months': 13494 modulo = 1; 13495 13496 if (ts.unit === 'year') { 13497 shouldNotSkipUnit = true; 13498 } 13499 13500 break; 13501 13502 case 'months_fortnight': 13503 modulo = 15; 13504 13505 if (ts.unit === 'year' || ts.unit === 'month') { 13506 shouldNotSkipUnit = true; 13507 } 13508 13509 if (value === 30) { 13510 shouldNotPrint = true; 13511 } 13512 13513 break; 13514 13515 case 'months_days': 13516 modulo = 10; 13517 13518 if (ts.unit === 'month') { 13519 shouldNotSkipUnit = true; 13520 } 13521 13522 if (value === 30) { 13523 shouldNotPrint = true; 13524 } 13525 13526 break; 13527 13528 case 'week_days': 13529 modulo = 8; 13530 13531 if (ts.unit === 'month') { 13532 shouldNotSkipUnit = true; 13533 } 13534 13535 break; 13536 13537 case 'days': 13538 modulo = 1; 13539 13540 if (ts.unit === 'month') { 13541 shouldNotSkipUnit = true; 13542 } 13543 13544 break; 13545 13546 case 'hours': 13547 if (ts.unit === 'day') { 13548 shouldNotSkipUnit = true; 13549 } 13550 13551 break; 13552 13553 case 'minutes': 13554 if (value % 5 !== 0) { 13555 shouldNotPrint = true; 13556 } 13557 13558 break; 13559 } 13560 13561 if (_this.tickInterval === 'minutes' || _this.tickInterval === 'hours') { 13562 if (!shouldNotPrint) { 13563 return true; 13564 } 13565 } else { 13566 if ((value % modulo === 0 || shouldNotSkipUnit) && !shouldNotPrint) { 13567 return true; 13568 } 13569 } 13570 }); 13571 return filteredTimeScale; 13572 } 13573 }, { 13574 key: "recalcDimensionsBasedOnFormat", 13575 value: function recalcDimensionsBasedOnFormat(filteredTimeScale, inverted) { 13576 var w = this.w; 13577 var reformattedTimescaleArray = this.formatDates(filteredTimeScale); 13578 var removedOverlappingTS = this.removeOverlappingTS(reformattedTimescaleArray); 13579 13580 if (!inverted) { 13581 w.globals.timelineLabels = removedOverlappingTS.slice(); 13582 } else { 13583 w.globals.invertedTimelineLabels = removedOverlappingTS.slice(); 13584 } // at this stage, we need to re-calculate coords of the grid as timeline labels may have altered the xaxis labels coords
13585 // The reason we can't do this prior to this stage is because timeline labels depends on gridWidth, and as the ticks are calculated based on available gridWidth, there can be unknown number of ticks generated for different minX and maxX 13586 // Dependency on Dimensions(), need to refactor correctly 13587 // TODO - find an alternate way to avoid calling this Heavy method twice 13588 13589 13590 var dimensions = new Dimensions(this.ctx); 13591 dimensions.plotCoords(); 13592 } 13593 }, { 13594 key: "determineInterval", 13595 value: function determineInterval(daysDiff) { 13596 switch (true) { 13597 case daysDiff > 1825: 13598 // difference is more than 5 years 13599 this.tickInterval = 'years'; 13600 break; 13601 13602 case daysDiff > 800 && daysDiff <= 1825: 13603 this.tickInterval = 'half_year'; 13604 break; 13605 13606 case daysDiff > 180 && daysDiff <= 800: 13607 this.tickInterval = 'months'; 13608 break; 13609 13610 case daysDiff > 90 && daysDiff <= 180: 13611 this.tickInterval = 'months_fortnight'; 13612 break; 13613 13614 case daysDiff > 60 && daysDiff <= 90: 13615 this.tickInterval = 'months_days'; 13616 break; 13617 13618 case daysDiff > 30 && daysDiff <= 60: 13619 this.tickInterval = 'week_days'; 13620 break; 13621 13622 case daysDiff > 2 && daysDiff <= 30: 13623 this.tickInterval = 'days'; 13624 break; 13625 13626 case daysDiff > 0.1 && daysDiff <= 2: 13627 // less than 2 days 13628 this.tickInterval = 'hours'; 13629 break; 13630 13631 case daysDiff < 0.1: 13632 this.tickInterval = 'minutes'; 13633 break; 13634 13635 default: 13636 this.tickInterval = 'days'; 13637 break; 13638 } 13639 } 13640 }, { 13641 key: "generateYearScale", 13642 value: function generateYearScale(params) { 13643 var firstVal = params.firstVal, 13644 currentMonth = params.currentMonth, 13645 currentYear = params.currentYear, 13646 daysWidthOnXAxis = params.daysWidthOnXAxis, 13647 numberOfYears = params.numberOfYears; 13648 var firstTickValue = firstVal.minYear; 13649 var firstTickPosition = 0; 13650 var dt = new DateTime(this.ctx); 13651 var unit = 'year'; 13652 13653 if (firstVal.minDate > 1 && firstVal.minMonth > 0) { 13654 var remainingDays = dt.determineRemainingDaysOfYear(firstVal.minYear, firstVal.minMonth, firstVal.minDate); // remainingDaysofFirstMonth is used to reacht the 2nd tick position 13655 13656 var remainingDaysOfFirstYear = dt.determineDaysOfYear(firstVal.minYear) - remainingDays + 1; // calculate the first tick position 13657 13658 firstTickPosition = remainingDaysOfFirstYear * daysWidthOnXAxis; 13659 firstTickValue = firstVal.minYear + 1; // push the first tick in the array 13660 13661 this.timeScaleArray.push({ 13662 position: firstTickPosition, 13663 value: firstTickValue, 13664 unit: unit, 13665 year: firstTickValue, 13666 month: Utils.monthMod(currentMonth + 1) 13667 }); 13668 } else if (firstVal.minDate === 1 && firstVal.minMonth === 0) { 13669 // push the first tick in the array 13670 this.timeScaleArray.push({ 13671 position: firstTickPosition, 13672 value: firstTickValue, 13673 unit: unit, 13674 year: currentYear, 13675 month: Utils.monthMod(currentMonth + 1) 13676 }); 13677 } 13678 13679 var year = firstTickValue; 13680 var pos = firstTickPosition; // keep drawing rest of the ticks 13681 13682 for (var i = 0; i < numberOfYears; i++) { 13683 year++; 13684 pos = dt.determineDaysOfYear(year - 1) * daysWidthOnXAxis + pos; 13685 this.timeScaleArray.push({ 13686 position: pos, 13687 value: year, 13688 unit: unit, 13689 year: year, 13690 month: 1 13691 }); 13692 } 13693 } 13694 }, { 13695 key: "generateMonthScale", 13696 value: function generateMonthScale(params) { 13697 var firstVal = params.firstVal, 13698 currentMonthDate = params.currentMonthDate, 13699 currentMonth = params.currentMonth, 13700 currentYear = params.currentYear, 13701 daysWidthOnXAxis = params.daysWidthOnXAxis, 13702 numberOfMonths = params.numberOfMonths; 13703 var firstTickValue = currentMonth; 13704 var firstTickPosition = 0; 13705 var dt = new DateTime(this.ctx); 13706 var unit = 'month'; 13707 var yrCounter = 0; 13708 13709 if (firstVal.minDate > 1) { 13710 // remainingDaysofFirstMonth is used to reacht the 2nd tick position 13711 var remainingDaysOfFirstMonth = dt.determineDaysOfMonths(currentMonth + 1, firstVal.minYear) - currentMonthDate + 1; // calculate the first tick position 13712 13713 firstTickPosition = remainingDaysOfFirstMonth * daysWidthOnXAxis; 13714 firstTickValue = Utils.monthMod(currentMonth + 1); 13715 var year = currentYear + yrCounter; 13716
13717 var _month = Utils.monthMod(firstTickValue); 13718 13719 var value = firstTickValue; // it's Jan, so update the year 13720 13721 if (firstTickValue === 0) { 13722 unit = 'year'; 13723 value = year; 13724 _month = 1; 13725 yrCounter += 1; 13726 year = year + yrCounter; 13727 } // push the first tick in the array 13728 13729 13730 this.timeScaleArray.push({ 13731 position: firstTickPosition, 13732 value: value, 13733 unit: unit, 13734 year: year, 13735 month: _month 13736 }); 13737 } else { 13738 // push the first tick in the array 13739 this.timeScaleArray.push({ 13740 position: firstTickPosition, 13741 value: firstTickValue, 13742 unit: unit, 13743 year: currentYear, 13744 month: Utils.monthMod(currentMonth) 13745 }); 13746 } 13747 13748 var month = firstTickValue + 1; 13749 var pos = firstTickPosition; // keep drawing rest of the ticks 13750 13751 for (var i = 0, j = 1; i < numberOfMonths; i++, j++) { 13752 month = Utils.monthMod(month); 13753 13754 if (month === 0) { 13755 unit = 'year'; 13756 yrCounter += 1; 13757 } else { 13758 unit = 'month'; 13759 } 13760 13761 var _year = currentYear + Math.floor(month / 12) + yrCounter; 13762 13763 pos = dt.determineDaysOfMonths(month, _year) * daysWidthOnXAxis + pos; 13764 var monthVal = month === 0 ? _year : month; 13765 this.timeScaleArray.push({ 13766 position: pos, 13767 value: monthVal, 13768 unit: unit, 13769 year: _year, 13770 month: month === 0 ? 1 : month 13771 }); 13772 month++; 13773 } 13774 } 13775 }, { 13776 key: "generateDayScale", 13777 value: function generateDayScale(params) { 13778 var firstVal = params.firstVal, 13779 currentMonth = params.currentMonth, 13780 currentYear = params.currentYear, 13781 hoursWidthOnXAxis = params.hoursWidthOnXAxis, 13782 numberOfDays = params.numberOfDays; 13783 var dt = new DateTime(this.ctx); 13784 var unit = 'day'; 13785 var remainingHours = 24 - firstVal.minHour; 13786 var yrCounter = 0; // calculate the first tick position 13787 13788 var firstTickPosition = remainingHours * hoursWidthOnXAxis; 13789 var firstTickValue = firstVal.minDate + 1; 13790 var val = firstTickValue; 13791 13792 var changeMonth = function changeMonth(dateVal, month, year) { 13793 var monthdays = dt.determineDaysOfMonths(month + 1, year); 13794 13795 if (dateVal > monthdays) { 13796 month = month + 1; 13797 date = 1; 13798 unit = 'month'; 13799 val = month; 13800 return month; 13801 } 13802 13803 return month; 13804 }; 13805 13806 var date = firstTickValue; 13807 var month = changeMonth(date, currentMonth, currentYear); // push the first tick in the array 13808 13809 this.timeScaleArray.push({ 13810 position: firstTickPosition, 13811 value: val, 13812 unit: unit, 13813 year: currentYear, 13814 month: Utils.monthMod(month), 13815 day: date 13816 }); 13817 var pos = firstTickPosition; // keep drawing rest of the ticks 13818 13819 for (var i = 0; i < numberOfDays; i++) { 13820 date += 1; 13821 unit = 'day'; 13822 month = changeMonth(date, month, currentYear + Math.floor(month / 12) + yrCounter); 13823 var year = currentYear + Math.floor(month / 12) + yrCounter; 13824 pos = 24 * hoursWidthOnXAxis + pos; 13825 13826 var _val = date === 1 ? Utils.monthMod(month) : date; 13827 13828 this.timeScaleArray.push({ 13829 position: pos, 13830 value: _val, 13831 unit: unit, 13832 year: year, 13833 month: Utils.monthMod(month), 13834 day: _val 13835 }); 13836 } 13837 } 13838 }, { 13839 key: "generateHourScale", 13840 value: function generateHourScale(params) { 13841 var firstVal = params.firstVal, 13842 currentDate = params.currentDate, 13843 currentMonth = params.currentMonth, 13844 currentYear = params.currentYear, 13845 minutesWidthOnXAxis = params.minutesWidthOnXAxis, 13846 numberOfHours = params.numberOfHours; 13847 var dt = new DateTime(this.ctx); 13848 var yrCounter = 0; 13849 var unit = 'hour'; 13850 13851 var changeDate = function changeDate(dateVal, month) { 13852 var monthdays = dt.determineDaysOfMonths(month + 1, currentYear); 13853 13854 if (dateVal > monthdays) { 13855 date = 1;
13856 month = month + 1; 13857 } 13858 13859 return { 13860 month: month, 13861 date: date 13862 }; 13863 }; 13864 13865 var changeMonth = function changeMonth(dateVal, month) { 13866 var monthdays = dt.determineDaysOfMonths(month + 1, currentYear); 13867 13868 if (dateVal > monthdays) { 13869 month = month + 1; 13870 return month; 13871 } 13872 13873 return month; 13874 }; 13875 13876 var remainingMins = 60 - firstVal.minMinute; 13877 var firstTickPosition = remainingMins * minutesWidthOnXAxis; 13878 var firstTickValue = firstVal.minHour + 1; 13879 var hour = firstTickValue + 1; 13880 13881 if (remainingMins === 60) { 13882 firstTickPosition = 0; 13883 firstTickValue = firstVal.minHour; 13884 hour = firstTickValue + 1; 13885 } 13886 13887 var date = currentDate; 13888 var month = changeMonth(date, currentMonth); // push the first tick in the array 13889 13890 this.timeScaleArray.push({ 13891 position: firstTickPosition, 13892 value: firstTickValue, 13893 unit: unit, 13894 day: date, 13895 hour: hour, 13896 year: currentYear, 13897 month: Utils.monthMod(month) 13898 }); 13899 var pos = firstTickPosition; // keep drawing rest of the ticks 13900 13901 for (var i = 0; i < numberOfHours; i++) { 13902 unit = 'hour'; 13903 13904 if (hour >= 24) { 13905 hour = 0; 13906 date += 1; 13907 unit = 'day'; 13908 var checkNextMonth = changeDate(date, month); 13909 month = checkNextMonth.month; 13910 month = changeMonth(date, month); 13911 } 13912 13913 var year = currentYear + Math.floor(month / 12) + yrCounter; 13914 pos = hour === 0 && i === 0 ? remainingMins * minutesWidthOnXAxis : 60 * minutesWidthOnXAxis + pos; 13915 var val = hour === 0 ? date : hour; 13916 this.timeScaleArray.push({ 13917 position: pos, 13918 value: val, 13919 unit: unit, 13920 hour: hour, 13921 day: date, 13922 year: year, 13923 month: Utils.monthMod(month) 13924 }); 13925 hour++; 13926 } 13927 } 13928 }, { 13929 key: "generateMinuteScale", 13930 value: function generateMinuteScale(params) { 13931 var firstVal = params.firstVal, 13932 currentMinute = params.currentMinute, 13933 currentHour = params.currentHour, 13934 currentDate = params.currentDate, 13935 currentMonth = params.currentMonth, 13936 currentYear = params.currentYear, 13937 minutesWidthOnXAxis = params.minutesWidthOnXAxis, 13938 numberOfMinutes = params.numberOfMinutes; 13939 var yrCounter = 0; 13940 var unit = 'minute'; 13941 var remainingMins = currentMinute - firstVal.minMinute; 13942 var firstTickPosition = minutesWidthOnXAxis - remainingMins; 13943 var firstTickValue = firstVal.minMinute + 1; 13944 var minute = firstTickValue + 1; 13945 var date = currentDate; 13946 var month = currentMonth; 13947 var year = currentYear; 13948 var hour = currentHour; // push the first tick in the array 13949 13950 this.timeScaleArray.push({ 13951 position: firstTickPosition, 13952 value: firstTickValue, 13953 unit: unit, 13954 day: date, 13955 hour: hour, 13956 minute: minute, 13957 year: year, 13958 month: Utils.monthMod(month) 13959 }); 13960 var pos = firstTickPosition; // keep drawing rest of the ticks 13961 13962 for (var i = 0; i < numberOfMinutes; i++) { 13963 if (minute >= 60) { 13964 minute = 0; 13965 hour += 1; 13966 13967 if (hour === 24) { 13968 hour = 0; 13969 } 13970 } 13971 13972 var _year2 = currentYear + Math.floor(month / 12) + yrCounter; 13973 13974 pos = minutesWidthOnXAxis + pos; 13975 var val = minute; 13976 this.timeScaleArray.push({ 13977 position: pos, 13978 value: val, 13979 unit: unit, 13980 hour: hour, 13981 minute: minute, 13982 day: date, 13983 year: _year2, 13984 month: Utils.monthMod(month) 13985 }); 13986 minute++; 13987 } 13988 } 13989 }, { 13990 key: "createRawDateString", 13991 value: function createRawDateString(ts, value) { 13992 var raw = ts.year; 13993 raw += '-' + ('0' + ts.month.toString()).slice(-2); // unit is day 13994 13995 if (ts.unit === 'day') { 13996 raw += ts.unit === 'day' ? '-' + ('0' + value).slice(-2) : '-01'; 13997 } else { 13998 raw += '-' + ('0' + (ts.day ? ts.day : '1')).slice(-2); 13999 } // unit is hour
14000 14001 14002 if (ts.unit === 'hour') { 14003 raw += ts.unit === 'hour' ? 'T' + ('0' + value).slice(-2) : 'T00'; 14004 } else { 14005 raw += 'T' + ('0' + (ts.hour ? ts.hour : '0')).slice(-2); 14006 } // unit is minute 14007 14008 14009 raw += ts.unit === 'minute' ? ':' + ('0' + value).slice(-2) + ':00.000Z' : ':00:00.000Z'; 14010 return raw; 14011 } 14012 }, { 14013 key: "formatDates", 14014 value: function formatDates(filteredTimeScale) { 14015 var _this2 = this; 14016 14017 var w = this.w; 14018 var reformattedTimescaleArray = filteredTimeScale.map(function (ts) { 14019 var value = ts.value.toString(); 14020 var dt = new DateTime(_this2.ctx); 14021 14022 var raw = _this2.createRawDateString(ts, value); // parse the whole ISO datestring 14023 14024 14025 var dateString = new Date(Date.parse(raw)); 14026 14027 if (w.config.xaxis.labels.format === undefined) { 14028 var customFormat = 'dd MMM'; 14029 var dtFormatter = w.config.xaxis.labels.datetimeFormatter; 14030 if (ts.unit === 'year') customFormat = dtFormatter.year; 14031 if (ts.unit === 'month') customFormat = dtFormatter.month; 14032 if (ts.unit === 'day') customFormat = dtFormatter.day; 14033 if (ts.unit === 'hour') customFormat = dtFormatter.hour; 14034 if (ts.unit === 'minute') customFormat = dtFormatter.minute; 14035 value = dt.formatDate(dateString, customFormat, true, false); 14036 } else { 14037 value = dt.formatDate(dateString, w.config.xaxis.labels.format); 14038 } 14039 14040 return { 14041 dateString: raw, 14042 position: ts.position, 14043 value: value, 14044 unit: ts.unit, 14045 year: ts.year, 14046 month: ts.month 14047 }; 14048 }); 14049 return reformattedTimescaleArray; 14050 } 14051 }, { 14052 key: "removeOverlappingTS", 14053 value: function removeOverlappingTS(arr) { 14054 var _this3 = this; 14055 14056 var graphics = new Graphics(this.ctx); 14057 var lastDrawnIndex = 0; 14058 var filteredArray = arr.map(function (item, index) { 14059 if (index > 0 && _this3.w.config.xaxis.labels.hideOverlappingLabels) { 14060 var prevLabelWidth = graphics.getTextRects(arr[lastDrawnIndex].value).width; 14061 var prevPos = arr[lastDrawnIndex].position; 14062 var pos = item.position; 14063 14064 if (pos > prevPos + prevLabelWidth + 10) { 14065 lastDrawnIndex = index; 14066 return item; 14067 } else { 14068 return null; 14069 } 14070 } else { 14071 return item; 14072 } 14073 }); 14074 filteredArray = filteredArray.filter(function (f) { 14075 return f !== null; 14076 }); 14077 return filteredArray; 14078 } 14079 }]); 14080 14081 return TimeScale; 14082 }(); 14083 14084 /** 14085 * ApexCharts Core Class responsible for major calculations and creating elements. 14086 * 14087 * @module Core 14088 **/ 14089 14090 var Core = 14091 /*#__PURE__*/ 14092 function () { 14093 function Core(el, ctx) { 14094 _classCallCheck(this, Core); 14095 14096 this.ctx = ctx; 14097 this.w = ctx.w; 14098 this.el = el; 14099 this.coreUtils = new CoreUtils(this.ctx); 14100 this.twoDSeries = []; 14101 this.threeDSeries = []; 14102 this.twoDSeriesX = []; 14103 } // get data and store into appropriate vars 14104 14105 14106 _createClass(Core, [{ 14107 key: "setupElements", 14108 value: function setupElements() { 14109 var gl = this.w.globals; 14110 var cnf = this.w.config; // const graphics = new Graphics(this.ctx) 14111 14112 var ct = cnf.chart.type; 14113 var axisChartsArrTypes = ['line', 'area', 'bar', 'rangeBar', // 'rangeArea', 14114 'candlestick', 'radar', 'scatter', 'bubble', 'heatmap']; 14115 var xyChartsArrTypes = ['line', 'area', 'bar', 'rangeBar', // 'rangeArea', 14116 'candlestick', 'scatter', 'bubble']; 14117 gl.axisCharts = axisChartsArrTypes.indexOf(ct) > -1; 14118 gl.xyCharts = xyChartsArrTypes.indexOf(ct) > -1; 14119 gl.isBarHorizontal = (cnf.chart.type === 'bar' || cnf.chart.type === 'rangeBar') && cnf.plotOptions.bar.horizontal; 14120 gl.chartClass = '.apexcharts' + gl.cuid; 14121 gl.dom.baseEl = this.el; 14122 gl.dom.elWrap = document.createElement('div'); 14123 Graphics.setAttrs(gl.dom.elWrap, { 14124 id: gl.chartClass.substring(1), 14125 class: 'apexcharts-canvas ' + gl.chartClass.substring(1) 14126 }); 14127 this.el.appendChild(gl.dom.elWrap); 14128 gl.dom.Paper = new window.SVG.Doc(gl.dom.elWrap); 14129 gl.dom.Paper.attr({ 14130 class: 'apexcharts-svg', 14131 'xmlns:data': 'ApexChartsNS', 14132 transform: "translate(".concat(cnf.chart.offsetX, ", ").concat(cnf.chart.offsetY, ")") 14133 }); 14134 gl.dom.Paper.node.style.background = cnf.chart.background; 14135 this.setSVGDimensions(); 14136 gl.dom.elGraphical = gl.dom.Paper.group().attr({ 14137 class: 'apexcharts-inner apexcharts-graphical' 14138 });
14139 gl.dom.elDefs = gl.dom.Paper.defs(); 14140 gl.dom.elLegendWrap = document.createElement('div'); 14141 gl.dom.elLegendWrap.classList.add('apexcharts-legend'); 14142 gl.dom.elWrap.appendChild(gl.dom.elLegendWrap); // gl.dom.Paper.add(gl.dom.elLegendWrap) 14143 14144 gl.dom.Paper.add(gl.dom.elGraphical); 14145 gl.dom.elGraphical.add(gl.dom.elDefs); 14146 } 14147 }, { 14148 key: "plotChartType", 14149 value: function plotChartType(ser, xyRatios) { 14150 var w = this.w; 14151 var cnf = w.config; 14152 var gl = w.globals; 14153 var lineSeries = { 14154 series: [], 14155 i: [] 14156 }; 14157 var areaSeries = { 14158 series: [], 14159 i: [] 14160 }; 14161 var scatterSeries = { 14162 series: [], 14163 i: [] 14164 }; 14165 var columnSeries = { 14166 series: [], 14167 i: [] 14168 }; 14169 var candlestickSeries = { 14170 series: [], 14171 i: [] 14172 }; 14173 gl.series.map(function (series, st) { 14174 // if user has specified a particular type for particular series 14175 if (typeof ser[st].type !== 'undefined') { 14176 if (ser[st].type === 'column' || ser[st].type === 'bar') { 14177 w.config.plotOptions.bar.horizontal = false; // horizontal bars not supported in mixed charts, hence forcefully set to false 14178
14179 columnSeries.series.push(series); 14180 columnSeries.i.push(st); 14181 } else if (ser[st].type === 'area') { 14182 areaSeries.series.push(series); 14183 areaSeries.i.push(st); 14184 } else if (ser[st].type === 'line') { 14185 lineSeries.series.push(series); 14186 lineSeries.i.push(st); 14187 } else if (ser[st].type === 'scatter') { 14188 scatterSeries.series.push(series); 14189 scatterSeries.i.push(st); 14190 } else if (ser[st].type === 'bubble') ; else if (ser[st].type === 'candlestick') { 14191 candlestickSeries.series.push(series); 14192 candlestickSeries.i.push(st); 14193 } else { 14194 // user has specified type, but it is not valid (other than line/area/column) 14195 console.warn('You have specified an unrecognized chart type. Available types for this propery are line/area/column/bar/scatter/bubble'); 14196 } 14197 14198 gl.comboCharts = true; 14199 } else {
14200 lineSeries.series.push(series); 14201 lineSeries.i.push(st); 14202 } 14203 }); 14204 var line = new Line(this.ctx, xyRatios); 14205 var candlestick = new CandleStick(this.ctx, xyRatios); 14206 var pie = new Pie(this.ctx); 14207 var radialBar = new Radial(this.ctx); 14208 var rangeBar = new RangeBar(this.ctx, xyRatios); 14209 var radar = new Radar(this.ctx); 14210 var elGraph = []; 14211 14212 if (gl.comboCharts) { 14213 if (areaSeries.series.length > 0) { 14214 elGraph.push(line.draw(areaSeries.series, 'area', areaSeries.i)); 14215 } 14216 14217 if (columnSeries.series.length > 0) { 14218 if (w.config.chart.stacked) { 14219 var barStacked = new BarStacked(this.ctx, xyRatios); 14220 elGraph.push(barStacked.draw(columnSeries.series, columnSeries.i)); 14221 } else { 14222 var bar = new Bar(this.ctx, xyRatios); 14223 elGraph.push(bar.draw(columnSeries.series, columnSeries.i)); 14224 } 14225 } 14226 14227 if (lineSeries.series.length > 0) { 14228 elGraph.push(line.draw(lineSeries.series, 'line', lineSeries.i)); 14229 } 14230 14231 if (candlestickSeries.series.length > 0) { 14232 elGraph.push(candlestick.draw(candlestickSeries.series, candlestickSeries.i)); 14233 } 14234 14235 if (scatterSeries.series.length > 0) { 14236 var scatterLine = new Line(this.ctx, xyRatios, true); 14237 elGraph.push(scatterLine.draw(scatterSeries.series, 'scatter', scatterSeries.i)); 14238 } // TODO: allow bubble series in a combo chart 14239 // if (bubbleSeries.series.length > 0) { 14240 // const bubbleLine = new Line(this.ctx, xyRatios, true) 14241 // elGraph.push( 14242 // bubbleLine.draw(bubbleSeries.series, 'bubble', bubbleSeries.i) 14243 // ) 14244 // } 14245 14246 } else { 14247 switch (cnf.chart.type) { 14248 case 'line': 14249 elGraph = line.draw(gl.series, 'line'); 14250 break; 14251 14252 case 'area': 14253 elGraph = line.draw(gl.series, 'area'); 14254 break; 14255 14256 case 'bar': 14257 if (cnf.chart.stacked) { 14258 var _barStacked = new BarStacked(this.ctx, xyRatios); 14259 14260 elGraph = _barStacked.draw(gl.series); 14261 } else { 14262 var _bar = new Bar(this.ctx, xyRatios); 14263 14264 elGraph = _bar.draw(gl.series); 14265 } 14266 14267 break; 14268 14269 case 'candlestick': 14270 var candleStick = new CandleStick(this.ctx, xyRatios); 14271 elGraph = candleStick.draw(gl.series); 14272 break; 14273 14274 case 'rangeBar': 14275 elGraph = rangeBar.draw(gl.series); 14276 break; 14277 14278 case 'heatmap': 14279 var heatmap = new HeatMap(this.ctx, xyRatios); 14280 elGraph = heatmap.draw(gl.series); 14281 break; 14282 14283 case 'pie': 14284 case 'donut': 14285 elGraph = pie.draw(gl.series); 14286 break; 14287 14288 case 'radialBar': 14289 elGraph = radialBar.draw(gl.series); 14290 break; 14291 14292 case 'radar': 14293 elGraph = radar.draw(gl.series); 14294 break; 14295 14296 default: 14297 elGraph = line.draw(gl.series); 14298 } 14299 } 14300 14301 return elGraph; 14302 } 14303 }, { 14304 key: "setSVGDimensions", 14305 value: function setSVGDimensions() { 14306 var gl = this.w.globals; 14307 var cnf = this.w.config; 14308 gl.svgWidth = cnf.chart.width; 14309 gl.svgHeight = cnf.chart.height; 14310 var elDim = Utils.getDimensions(this.el); 14311 var widthUnit = cnf.chart.width.toString().split(/[0-9]+/g).pop(); 14312 14313 if (widthUnit === '%') { 14314 if (Utils.isNumber(elDim[0])) { 14315 if (elDim[0].width === 0) { 14316 elDim = Utils.getDimensions(this.el.parentNode); 14317 } 14318 14319 gl.svgWidth = elDim[0] * parseInt(cnf.chart.width) / 100; 14320 } 14321 } else if (widthUnit === 'px' || widthUnit === '') { 14322 gl.svgWidth = parseInt(cnf.chart.width); 14323 } 14324 14325 if (gl.svgHeight !== 'auto' && gl.svgHeight !== '') { 14326 var heightUnit = cnf.chart.height.toString().split(/[0-9]+/g).pop(); 14327 14328 if (heightUnit === '%') { 14329 var elParentDim = Utils.getDimensions(this.el.parentNode); 14330 gl.svgHeight = elParentDim[1] * parseInt(cnf.chart.height) / 100; 14331 } else { 14332 gl.svgHeight = parseInt(cnf.chart.height); 14333 } 14334 } else { 14335 if (gl.axisCharts) { 14336 gl.svgHeight = gl.svgWidth / 1.61; 14337 } else { 14338 gl.svgHeight = gl.svgWidth; 14339 } 14340 } 14341 14342 Graphics.setAttrs(gl.dom.Paper.node, { 14343 width: gl.svgWidth, 14344 height: gl.svgHeight 14345 }); // gl.dom.Paper.node.parentNode.parentNode.style.minWidth = gl.svgWidth + "px"; 14346 14347 var offsetY = cnf.chart.sparkline.enabled ? 0 : gl.axisCharts ? cnf.chart.parentHeightOffset : 0; 14348 gl.dom.Paper.node.parentNode.parentNode.style.minHeight = gl.svgHeight + offsetY + 'px'; 14349 gl.dom.elWrap.style.width = gl.svgWidth + 'px'; 14350 gl.dom.elWrap.style.height = gl.svgHeight + 'px'; 14351 } 14352 }, { 14353 key: "shiftGraphPosition", 14354 value: function shiftGraphPosition() { 14355 var gl = this.w.globals; 14356 var tY = gl.translateY; 14357 var tX = gl.translateX; 14358 var scalingAttrs = { 14359 transform: 'translate(' + tX + ', ' + tY + ')' 14360 }; 14361 Graphics.setAttrs(gl.dom.elGraphical.node, scalingAttrs); 14362 } 14363 /* 14364 ** All the calculations for setting range in charts will be done here 14365 */ 14366 14367 }, { 14368 key: "coreCalculations", 14369 value: function coreCalculations() { 14370 var range = new Range$1(this.ctx);
14371 range.init(); 14372 } 14373 }, { 14374 key: "resetGlobals", 14375 value: function resetGlobals() { 14376 var _this = this; 14377 14378 var gl = this.w.globals; 14379 gl.series = []; 14380 gl.seriesCandleO = []; 14381 gl.seriesCandleH = []; 14382 gl.seriesCandleL = []; 14383 gl.seriesCandleC = []; 14384 gl.seriesRangeStart = []; 14385 gl.seriesRangeEnd = []; 14386 gl.seriesPercent = []; 14387 gl.seriesX = []; 14388 gl.seriesZ = []; 14389 gl.seriesNames = []; 14390 gl.seriesTotals = []; 14391 gl.stackedSeriesTotals = []; 14392 gl.labels = []; 14393 gl.timelineLabels = []; 14394 gl.noLabelsProvided = false; 14395 gl.timescaleTicks = []; 14396 gl.resizeTimer = null; 14397 gl.selectionResizeTimer = null; 14398 14399 gl.seriesXvalues = function () { 14400 return _this.w.config.series.map(function (s) { 14401 return []; 14402 }); 14403 }(); 14404 14405 gl.seriesYvalues = function () { 14406 return _this.w.config.series.map(function (s) { 14407 return []; 14408 }); 14409 }(); 14410 14411 gl.delayedElements = []; 14412 gl.pointsArray = []; 14413 gl.dataLabelsRects = []; 14414 gl.isXNumeric = false; 14415 gl.isDataXYZ = false; 14416 gl.maxY = -Number.MAX_VALUE; 14417 gl.minY = Number.MIN_VALUE; 14418 gl.minYArr = []; 14419 gl.maxYArr = []; 14420 gl.maxX = -Number.MAX_VALUE; 14421 gl.minX = Number.MAX_VALUE; 14422 gl.initialmaxX = -Number.MAX_VALUE; 14423 gl.initialminX = Number.MAX_VALUE; 14424 gl.maxDate = 0; 14425 gl.minDate = Number.MAX_VALUE; 14426 gl.minZ = Number.MAX_VALUE; 14427 gl.maxZ = -Number.MAX_VALUE; 14428 gl.minXDiff = Number.MAX_VALUE; 14429 gl.yAxisScale = []; 14430 gl.xAxisScale = null; 14431 gl.xAxisTicksPositions = []; 14432 gl.yLabelsCoords = []; 14433 gl.yTitleCoords = []; 14434 gl.xRange = 0; 14435 gl.yRange = []; 14436 gl.zRange = 0; 14437 gl.dataPoints = 0; 14438 } 14439 }, { 14440 key: "isMultipleY", 14441 value: function isMultipleY() { 14442 // user has supplied an array in yaxis property. So, turn on multipleYAxis flag 14443 if (this.w.config.yaxis.constructor === Array && this.w.config.yaxis.length > 1) { 14444 // first, turn off stacking if multiple y axis 14445 this.w.config.chart.stacked = false; 14446 this.w.globals.isMultipleYAxis = true; 14447 return true; 14448 } 14449 } 14450 }, { 14451 key: "excludeCollapsedSeriesInYAxis", 14452 value: function excludeCollapsedSeriesInYAxis() { 14453 var _this2 = this; 14454 14455 var w = this.w; 14456 w.globals.ignoreYAxisIndexes = w.globals.collapsedSeries.map(function (collapsed, i) { 14457 if (_this2.w.globals.isMultipleYAxis) { 14458 return collapsed.index; 14459 } 14460 }); 14461 } 14462 }, { 14463 key: "isMultiFormat", 14464 value: function isMultiFormat() { 14465 return this.isFormatXY() || this.isFormat2DArray(); 14466 } // given format is [{x, y}, {x, y}] 14467 14468 }, { 14469 key: "isFormatXY", 14470 value: function isFormatXY() { 14471 var series = this.w.config.series.slice(); 14472 var sr = new Series(this.ctx); 14473 this.activeSeriesIndex = sr.getActiveConfigSeriesIndex(); 14474 14475 if (typeof series[this.activeSeriesIndex].data !== 'undefined' && series[this.activeSeriesIndex].data.length > 0 && series[this.activeSeriesIndex].data[0] !== null && typeof series[this.activeSeriesIndex].data[0].x !== 'undefined' && series[this.activeSeriesIndex].data[0] !== null) { 14476 return true; 14477 } 14478 } // given format is [[x, y], [x, y]] 14479 14480 }, { 14481 key: "isFormat2DArray", 14482 value: function isFormat2DArray() { 14483 var series = this.w.config.series.slice(); 14484 var sr = new Series(this.ctx); 14485 this.activeSeriesIndex = sr.getActiveConfigSeriesIndex(); 14486 14487 if (typeof series[this.activeSeriesIndex].data !== 'undefined' && series[this.activeSeriesIndex].data.length > 0 && typeof series[this.activeSeriesIndex].data[0] !== 'undefined' && series[this.activeSeriesIndex].data[0] !== null && series[this.activeSeriesIndex].data[0].constructor === Array) { 14488 return true; 14489 } 14490 } 14491 }, { 14492 key: "handleFormat2DArray", 14493 value: function handleFormat2DArray(ser, i) { 14494 var cnf = this.w.config; 14495 var gl = this.w.globals; 14496 14497 for (var j = 0; j < ser[i].data.length; j++) { 14498 if (typeof ser[i].data[j][1] !== 'undefined') { 14499 if (Array.isArray(ser[i].data[j][1]) && ser[i].data[j][1].length === 4) { 14500 this.twoDSeries.push(Utils.parseNumber(ser[i].data[j][1][3])); 14501 } else { 14502 this.twoDSeries.push(Utils.parseNumber(ser[i].data[j][1])); 14503 } 14504 14505 gl.dataFormatXNumeric = true; 14506 } 14507 14508 if (cnf.xaxis.type === 'datetime') { 14509 // if timestamps are provided and xaxis type is datettime, 14510 var ts = new Date(ser[i].data[j][0]); 14511 ts = new Date(ts).getTime(); 14512 this.twoDSeriesX.push(ts); 14513 } else { 14514 this.twoDSeriesX.push(ser[i].data[j][0]); 14515 } 14516 } 14517 14518 for (var _j = 0; _j < ser[i].data.length; _j++) { 14519 if (typeof ser[i].data[_j][2] !== 'undefined') { 14520 this.threeDSeries.push(ser[i].data[_j][2]); 14521 gl.isDataXYZ = true; 14522 } 14523 } 14524 } 14525 }, { 14526 key: "handleFormatXY", 14527 value: function handleFormatXY(ser, i) { 14528 var cnf = this.w.config; 14529 var gl = this.w.globals; 14530 var dt = new DateTime(this.ctx); 14531 var activeI = i; 14532 14533 if (gl.collapsedSeriesIndices.indexOf(i) > -1) { 14534 // fix #368 14535 activeI = this.activeSeriesIndex; 14536 } // get series 14537 14538 14539 for (var j = 0; j < ser[i].data.length; j++) { 14540 if (typeof ser[i].data[j].y !== 'undefined') { 14541 if (Array.isArray(ser[i].data[j].y)) { 14542 this.twoDSeries.push(Utils.parseNumber(ser[i].data[j].y[ser[i].data[j].y.length - 1])); 14543 } else { 14544 this.twoDSeries.push(Utils.parseNumber(ser[i].data[j].y)); 14545 } 14546 } 14547 } // get seriesX 14548 14549 14550 for (var _j2 = 0; _j2 < ser[activeI].data.length; _j2++) { 14551 var isXString = typeof ser[activeI].data[_j2].x === 'string'; 14552 var isXDate = !!dt.isValidDate(ser[activeI].data[_j2].x.toString()); 14553 14554 if (isXString || isXDate) { 14555 // user supplied '01/01/2017' or a date string (a JS date object is not supported) 14556 if (isXString) { 14557 if (cnf.xaxis.type === 'datetime' && !gl.isRangeData) { 14558 this.twoDSeriesX.push(dt.parseDate(ser[activeI].data[_j2].x)); 14559 } else { 14560 // a category and not a numeric x value 14561 this.fallbackToCategory = true; 14562 this.twoDSeriesX.push(ser[activeI].data[_j2].x); 14563 } 14564 } else { 14565 if (cnf.xaxis.type === 'datetime') { 14566 this.twoDSeriesX.push(dt.parseDate(ser[activeI].data[_j2].x.toString())); 14567 } else { 14568 gl.dataFormatXNumeric = true; 14569 gl.isXNumeric = true; 14570 this.twoDSeriesX.push(parseFloat(ser[activeI].data[_j2].x)); 14571 } 14572 } 14573 } else { 14574 // a numeric value in x property 14575 gl.isXNumeric = true; 14576 gl.dataFormatXNumeric = true; 14577 this.twoDSeriesX.push(ser[activeI].data[_j2].x); 14578 } 14579 } 14580 14581 if (ser[i].data[0] && typeof ser[i].data[0].z !== 'undefined') { 14582 for (var t = 0; t < ser[i].data.length; t++) { 14583 this.threeDSeries.push(ser[i].data[t].z); 14584 } 14585 14586 gl.isDataXYZ = true; 14587 } 14588 } 14589 }, { 14590 key: "handleRangeData", 14591 value: function handleRangeData(ser, i) { 14592 var gl = this.w.globals; 14593 var range = {}; 14594 14595 if (this.isFormat2DArray()) { 14596 range = this.handleRangeDataFormat('array', ser, i); 14597 } else if (this.isFormatXY()) { 14598 range = this.handleRangeDataFormat('xy', ser, i); 14599 } 14600 14601 gl.seriesRangeStart.push(range.start); 14602 gl.seriesRangeEnd.push(range.end); 14603 return range; 14604 } 14605 }, { 14606 key: "handleCandleStickData", 14607 value: function handleCandleStickData(ser, i) { 14608 var gl = this.w.globals; 14609 var ohlc = {}; 14610 14611 if (this.isFormat2DArray()) { 14612 ohlc = this.handleCandleStickDataFormat('array', ser, i); 14613 } else if (this.isFormatXY()) { 14614 ohlc = this.handleCandleStickDataFormat('xy', ser, i); 14615 } 14616 14617 gl.seriesCandleO.push(ohlc.o); 14618 gl.seriesCandleH.push(ohlc.h); 14619 gl.seriesCandleL.push(ohlc.l); 14620 gl.seriesCandleC.push(ohlc.c); 14621 return ohlc; 14622 } 14623 }, { 14624 key: "handleRangeDataFormat", 14625 value: function handleRangeDataFormat(format, ser, i) { 14626 var rangeStart = []; 14627 var rangeEnd = []; 14628 var err = 'Please provide [Start, End] values in valid format. Read more https://apexcharts.com/docs/series/#rangecharts'; 14629 var serObj = new Series(this.ctx); 14630 var activeIndex = serObj.getActiveConfigSeriesIndex(); 14631 14632 if (format === 'array') { 14633 if (ser[activeIndex].data[0][1].length !== 2) { 14634 throw new Error(err); 14635 } 14636 14637 for (var j = 0; j < ser[i].data.length; j++) { 14638 rangeStart.push(ser[i].data[j][1][0]); 14639 rangeEnd.push(ser[i].data[j][1][1]); 14640 } 14641 } else if (format === 'xy') { 14642 if (ser[activeIndex].data[0].y.length !== 2) { 14643 throw new Error(err); 14644 } 14645 14646 for (var _j3 = 0; _j3 < ser[i].data.length; _j3++) { 14647 rangeStart.push(ser[i].data[_j3].y[0]); 14648 rangeEnd.push(ser[i].data[_j3].y[1]); 14649 } 14650 } 14651 14652 return { 14653 start: rangeStart, 14654 end: rangeEnd 14655 }; 14656 } 14657 }, { 14658 key: "handleCandleStickDataFormat", 14659 value: function handleCandleStickDataFormat(format, ser, i) { 14660 var serO = []; 14661 var serH = []; 14662 var serL = []; 14663 var serC = []; 14664 var err = 'Please provide [Open, High, Low and Close] values in valid format. Read more https://apexcharts.com/docs/series/#candlestick'; 14665 14666 if (format === 'array') { 14667 if (ser[i].data[0][1].length !== 4) { 14668 throw new Error(err); 14669 } 14670 14671 for (var j = 0; j < ser[i].data.length; j++) { 14672 serO.push(ser[i].data[j][1][0]); 14673 serH.push(ser[i].data[j][1][1]); 14674 serL.push(ser[i].data[j][1][2]); 14675 serC.push(ser[i].data[j][1][3]); 14676 } 14677 } else if (format === 'xy') { 14678 if (ser[i].data[0].y.length !== 4) { 14679 throw new Error(err); 14680 } 14681 14682 for (var _j4 = 0; _j4 < ser[i].data.length; _j4++) { 14683 serO.push(ser[i].data[_j4].y[0]); 14684 serH.push(ser[i].data[_j4].y[1]); 14685 serL.push(ser[i].data[_j4].y[2]); 14686 serC.push(ser[i].data[_j4].y[3]); 14687 } 14688 } 14689 14690 return { 14691 o: serO, 14692 h: serH, 14693 l: serL, 14694 c: serC 14695 }; 14696 } 14697 }, { 14698 key: "parseDataAxisCharts", 14699 value: function parseDataAxisCharts(ser) { 14700 var ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.ctx; 14701 var cnf = this.w.config; 14702 var gl = this.w.globals; 14703 var dt = new DateTime(ctx); 14704 14705 for (var i = 0; i < ser.length; i++) { 14706 this.twoDSeries = []; 14707 this.twoDSeriesX = []; 14708 this.threeDSeries = []; 14709 14710 if (typeof ser[i].data === 'undefined') { 14711 console.error("It is a possibility that you may have not included 'data' property in series."); 14712 return; 14713 } 14714 14715 if (cnf.chart.type === 'rangeBar' || cnf.chart.type === 'rangeArea' || ser[i].type === 'rangeBar' || ser[i].type === 'rangeArea') { 14716 gl.isRangeData = true; 14717 this.handleRangeData(ser, i); 14718 } 14719 14720 if (this.isMultiFormat()) { 14721 if (this.isFormat2DArray()) { 14722 this.handleFormat2DArray(ser, i); 14723 } else if (this.isFormatXY()) { 14724 this.handleFormatXY(ser, i); 14725 } 14726 14727 if (cnf.chart.type === 'candlestick' || ser[i].type === 'candlestick') { 14728 this.handleCandleStickData(ser, i); 14729 } 14730 14731 gl.series.push(this.twoDSeries); 14732 gl.labels.push(this.twoDSeriesX); 14733 gl.seriesX.push(this.twoDSeriesX); 14734 14735 if (!this.fallbackToCategory) { 14736 gl.isXNumeric = true; 14737 } 14738 } else { 14739 if (cnf.xaxis.type === 'datetime') { 14740 // user didn't supplied [{x,y}] or [[x,y]], but single array in data. 14741 // Also labels/categories were supplied differently 14742 gl.isXNumeric = true; 14743 var dates = cnf.labels.length > 0 ? cnf.labels.slice() : cnf.xaxis.categories.slice(); 14744 14745 for (var j = 0; j < dates.length; j++) { 14746 if (typeof dates[j] === 'string') { 14747 var isDate = dt.isValidDate(dates[j]); 14748 14749 if (isDate) { 14750 this.twoDSeriesX.push(dt.parseDate(dates[j])); 14751 } else {
14752 throw new Error('You have provided invalid Date format. Please provide a valid JavaScript Date'); 14753 } 14754 } 14755 } 14756 14757 gl.seriesX.push(this.twoDSeriesX); 14758 } else if (cnf.xaxis.type === 'numeric') { 14759 gl.isXNumeric = true; 14760 var x = cnf.labels.length > 0 ? cnf.labels.slice() : cnf.xaxis.categories.slice(); 14761 14762 if (x.length > 0) { 14763 this.twoDSeriesX = x; 14764 gl.seriesX.push(this.twoDSeriesX); 14765 } 14766 } 14767 14768 gl.labels.push(this.twoDSeriesX); 14769 var singleArray = ser[i].data.map(function (d) { 14770 return Utils.parseNumber(d); 14771 }); 14772 gl.series.push(singleArray); 14773 } 14774 14775 gl.seriesZ.push(this.threeDSeries); 14776 14777 if (ser[i].name !== undefined) { 14778 gl.seriesNames.push(ser[i].name); 14779 } else { 14780 gl.seriesNames.push('series-' + parseInt(i + 1)); 14781 } 14782 } 14783 14784 return this.w; 14785 } 14786 }, { 14787 key: "parseDataNonAxisCharts", 14788 value: function parseDataNonAxisCharts(ser) { 14789 var gl = this.w.globals; 14790 var cnf = this.w.config; 14791 gl.series = ser.slice(); 14792 gl.seriesNames = cnf.labels.slice(); 14793 14794 for (var i = 0; i < gl.series.length; i++) { 14795 if (gl.seriesNames[i] === undefined) { 14796 gl.seriesNames.push('series-' + (i + 1)); 14797 } 14798 } 14799 14800 return this.w; 14801 } 14802 /** User possibly set string categories in xaxis.categories or labels prop 14803 * Or didn't set xaxis labels at all - in which case we manually do it. 14804 * If user passed series data as [[3, 2], [4, 5]] or [{ x: 3, y: 55 }], 14805 * this shouldn't be called 14806 * @param {array} ser - the series which user passed to the config 14807 */ 14808 14809 }, { 14810 key: "handleExternalLabelsData", 14811 value: function handleExternalLabelsData(ser) { 14812 var cnf = this.w.config; 14813 var gl = this.w.globals; 14814 14815 if (cnf.xaxis.categories.length > 0) { 14816 // user provided labels in xaxis.category prop 14817 gl.labels = cnf.xaxis.categories; 14818 } else if (cnf.labels.length > 0) { 14819 // user provided labels in labels props 14820 gl.labels = cnf.labels.slice(); 14821 } else if (this.fallbackToCategory) { 14822 // user provided labels in x prop in [{ x: 3, y: 55 }] data, and those labels are already stored in gl.labels[0], so just re-arrange the gl.labels array 14823 gl.labels = gl.labels[0]; 14824 } else { 14825 // user didn't provided any labels, fallback to 1-2-3-4-5 14826 var labelArr = []; 14827 14828 if (gl.axisCharts) { 14829 // for axis charts, we get the longest series and create labels from it 14830 for (var i = 0; i < gl.series[gl.maxValsInArrayIndex].length; i++) { 14831 labelArr.push(i + 1); 14832 } // create gl.seriesX as it will be used in calculations of x positions 14833 14834 14835 for (var _i = 0; _i < ser.length; _i++) { 14836 gl.seriesX.push(labelArr); 14837 } // turn on the isXNumeric flag to allow minX and maxX to function properly 14838 14839 14840 gl.isXNumeric = true; 14841 } // no series to pull labels from, put a 0-10 series 14842 // possibly, user collapsed all series. Hence we can't work with above calc 14843 14844 14845 if (labelArr.length === 0) { 14846 labelArr = [0, 10]; 14847 14848 for (var _i2 = 0; _i2 < ser.length; _i2++) { 14849 gl.seriesX.push(labelArr); 14850 } 14851 } // Finally, pass the labelArr in gl.labels which will be printed on x-axis 14852 14853 14854 gl.labels = labelArr; // Turn on this global flag to indicate no labels were provided by user 14855 14856 gl.noLabelsProvided = true; 14857 } 14858 } // Segregate user provided data into appropriate vars 14859 14860 }, { 14861 key: "parseData", 14862 value: function parseData(ser) { 14863 var w = this.w; 14864 var cnf = w.config; 14865 var gl = w.globals; 14866 this.excludeCollapsedSeriesInYAxis(); // If we detected string in X prop of series, we fallback to category x-axis 14867 14868 this.fallbackToCategory = false; 14869 this.resetGlobals(); 14870 this.isMultipleY(); 14871 14872 if (gl.axisCharts) { 14873 // axisCharts includes line / area / column / scatter 14874 this.parseDataAxisCharts(ser); 14875 } else { 14876 // non-axis charts are pie / donut 14877 this.parseDataNonAxisCharts(ser); 14878 } 14879 14880 this.coreUtils.getLargestSeries(); // set Null values to 0 in all series when user hides/shows some series 14881 14882 if (cnf.chart.type === 'bar' && cnf.chart.stacked) { 14883 var series = new Series(this.ctx); 14884 gl.series = series.setNullSeriesToZeroValues(gl.series); 14885 } 14886 14887 this.coreUtils.getSeriesTotals(); 14888 14889 if (gl.axisCharts) { 14890 this.coreUtils.getStackedSeriesTotals(); 14891 } 14892 14893 this.coreUtils.getPercentSeries(); 14894 14895 if (!gl.dataFormatXNumeric && (!gl.isXNumeric || cnf.xaxis.type === 'numeric' && cnf.labels.length === 0 && cnf.xaxis.categories.length === 0)) { 14896 // x-axis labels couldn't be detected; hence try searching every option in config 14897 this.handleExternalLabelsData(ser); 14898 } 14899 } 14900 }, { 14901 key: "xySettings", 14902 value: function xySettings() { 14903 var xyRatios = null; 14904 var w = this.w; 14905 14906 if (w.globals.axisCharts) { 14907 if (w.config.xaxis.crosshairs.position === 'back') { 14908 var crosshairs = new Crosshairs(this.ctx); 14909 crosshairs.drawXCrosshairs(); 14910 } 14911 14912 if (w.config.yaxis[0].crosshairs.position === 'back') { 14913 var _crosshairs = new Crosshairs(this.ctx); 14914 14915 _crosshairs.drawYCrosshairs(); 14916 } 14917 14918 xyRatios = this.coreUtils.getCalculatedRatios(); 14919 14920 if (w.config.xaxis.type === 'datetime' && w.config.xaxis.labels.formatter === undefined) { 14921 var ts = new TimeScale(this.ctx); 14922 var formattedTimeScale; 14923 14924 if (isFinite(w.globals.minX) && isFinite(w.globals.maxX) && !w.globals.isBarHorizontal) {
14925 formattedTimeScale = ts.calculateTimeScaleTicks(w.globals.minX, w.globals.maxX); 14926 ts.recalcDimensionsBasedOnFormat(formattedTimeScale, false); 14927 } else if (w.globals.isBarHorizontal) { 14928 formattedTimeScale = ts.calculateTimeScaleTicks(w.globals.minY, w.globals.maxY); 14929 ts.recalcDimensionsBasedOnFormat(formattedTimeScale, true); 14930 } 14931 } 14932 } 14933 14934 return xyRatios; 14935 } 14936 }, { 14937 key: "drawAxis", 14938 value: function drawAxis(type, xyRatios) { 14939 var gl = this.w.globals; 14940 var cnf = this.w.config; 14941 var xAxis = new XAxis(this.ctx); 14942 var yAxis = new YAxis(this.ctx); 14943 14944 if (gl.axisCharts && type !== 'radar') { 14945 var elXaxis, elYaxis; 14946 14947 if (gl.isBarHorizontal) { 14948 elYaxis = yAxis.drawYaxisInversed(0); 14949 elXaxis = xAxis.drawXaxisInversed(0); 14950 gl.dom.elGraphical.add(elXaxis); 14951 gl.dom.elGraphical.add(elYaxis); 14952 } else { 14953 elXaxis = xAxis.drawXaxis(); 14954 gl.dom.elGraphical.add(elXaxis); 14955 cnf.yaxis.map(function (yaxe, index) { 14956 if (gl.ignoreYAxisIndexes.indexOf(index) === -1) { 14957 elYaxis = yAxis.drawYaxis(index); 14958 gl.dom.Paper.add(elYaxis); 14959 } 14960 }); 14961 } 14962 } 14963 14964 cnf.yaxis.map(function (yaxe, index) { 14965 if (gl.ignoreYAxisIndexes.indexOf(index) === -1) { 14966 yAxis.yAxisTitleRotate(index, yaxe.opposite); 14967 } 14968 }); 14969 } 14970 }, { 14971 key: "setupBrushHandler", 14972 value: function setupBrushHandler() { 14973 var _this3 = this; 14974 14975 var w = this.w; // only for brush charts 14976 14977 if (!w.config.chart.brush.enabled) { 14978 return; 14979 } // if user has not defined a custom function for selection - we handle the brush chart 14980 // otherwise we leave it to the user to define the functionality for selection 14981 14982 14983 if (typeof w.config.chart.events.selection !== 'function') { 14984 var targets = w.config.chart.brush.targets || [w.config.chart.brush.target]; // retro compatibility with single target option 14985 14986 targets.forEach(function (target) { 14987 var targetChart = ApexCharts.getChartByID(target); 14988 targetChart.w.globals.brushSource = _this3.ctx; 14989 14990 var updateSourceChart = function updateSourceChart() { 14991 _this3.ctx._updateOptions({ 14992 chart: { 14993 selection: { 14994 xaxis: { 14995 min: targetChart.w.globals.minX, 14996 max: targetChart.w.globals.maxX 14997 } 14998 } 14999 } 15000 }, false, false); 15001 }; 15002 15003 if (typeof targetChart.w.config.chart.events.zoomed !== 'function') { 15004 targetChart.w.config.chart.events.zoomed = function () { 15005 updateSourceChart(); 15006 }; 15007 } 15008 15009 if (typeof targetChart.w.config.chart.events.scrolled !== 'function') { 15010 targetChart.w.config.chart.events.scrolled = function () { 15011 updateSourceChart(); 15012 }; 15013 } 15014 15015 w.config.chart.events.selection = function (chart, e) { 15016 var yaxis = Utils.clone(w.config.yaxis); 15017 15018 if (w.config.chart.brush.autoScaleYaxis) { 15019 var scale = new Range(targetChart); 15020 yaxis = scale.autoScaleY(targetChart, e); 15021 } 15022 15023 targetChart._updateOptions({ 15024 xaxis: { 15025 min: e.xaxis.min, 15026 max: e.xaxis.max 15027 }, 15028 yaxis: yaxis 15029 }, false, false, false); 15030 }; 15031 }); 15032 } 15033 } 15034 }]); 15035 15036 return Core; 15037 }(); 15038 15039 /** 15040 * @this {Promise} 15041 */ 15042 function finallyConstructor(callback) { 15043 var constructor = this.constructor; 15044 return this.then( 15045 function(value) { 15046 return constructor.resolve(callback()).then(function() { 15047 return value; 15048 }); 15049 }, 15050 function(reason) { 15051 return constructor.resolve(callback()).then(function() { 15052 return constructor.reject(reason); 15053 }); 15054 } 15055 ); 15056 } 15057 15058 // Store setTimeout reference so promise-polyfill will be unaffected by 15059 // other code modifying setTimeout (like sinon.useFakeTimers())
vendor: 5,139 bytes, lines 15060-15252
15060 var setTimeoutFunc = setTimeout; 15061 15062 function noop() {} 15063 15064 // Polyfill for Function.prototype.bind 15065 function bind(fn, thisArg) { 15066 return function() { 15067 fn.apply(thisArg, arguments); 15068 }; 15069 } 15070 15071 /** 15072 * @constructor 15073 * @param {Function} fn 15074 */ 15075 function Promise$1(fn) { 15076 if (!(this instanceof Promise$1)) 15077 throw new TypeError('Promises must be constructed via new'); 15078 if (typeof fn !== 'function') throw new TypeError('not a function'); 15079 /** @type {!number} */ 15080 this._state = 0; 15081 /** @type {!boolean} */ 15082 this._handled = false; 15083 /** @type {Promise|undefined} */ 15084 this._value = undefined; 15085 /** @type {!Array<!Function>} */ 15086 this._deferreds = []; 15087 15088 doResolve(fn, this); 15089 } 15090 15091 function handle(self, deferred) { 15092 while (self._state === 3) { 15093 self = self._value; 15094 } 15095 if (self._state === 0) { 15096 self._deferreds.push(deferred); 15097 return; 15098 } 15099 self._handled = true; 15100 Promise$1._immediateFn(function() { 15101 var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; 15102 if (cb === null) { 15103 (self._state === 1 ? resolve : reject)(deferred.promise, self._value); 15104 return; 15105 } 15106 var ret; 15107 try { 15108 ret = cb(self._value); 15109 } catch (e) { 15110 reject(deferred.promise, e); 15111 return; 15112 } 15113 resolve(deferred.promise, ret); 15114 }); 15115 } 15116 15117 function resolve(self, newValue) { 15118 try { 15119 // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure 15120 if (newValue === self) 15121 throw new TypeError('A promise cannot be resolved with itself.'); 15122 if ( 15123 newValue && 15124 (typeof newValue === 'object' || typeof newValue === 'function') 15125 ) { 15126 var then = newValue.then; 15127 if (newValue instanceof Promise$1) { 15128 self._state = 3; 15129 self._value = newValue; 15130 finale(self); 15131 return; 15132 } else if (typeof then === 'function') { 15133 doResolve(bind(then, newValue), self); 15134 return; 15135 } 15136 } 15137 self._state = 1; 15138 self._value = newValue; 15139 finale(self); 15140 } catch (e) { 15141 reject(self, e); 15142 } 15143 } 15144 15145 function reject(self, newValue) { 15146 self._state = 2; 15147 self._value = newValue; 15148 finale(self); 15149 } 15150 15151 function finale(self) { 15152 if (self._state === 2 && self._deferreds.length === 0) { 15153 Promise$1._immediateFn(function() { 15154 if (!self._handled) { 15155 Promise$1._unhandledRejectionFn(self._value); 15156 } 15157 }); 15158 } 15159 15160 for (var i = 0, len = self._deferreds.length; i < len; i++) { 15161 handle(self, self._deferreds[i]); 15162 } 15163 self._deferreds = null; 15164 } 15165 15166 /** 15167 * @constructor 15168 */ 15169 function Handler(onFulfilled, onRejected, promise) { 15170 this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; 15171 this.onRejected = typeof onRejected === 'function' ? onRejected : null; 15172 this.promise = promise; 15173 } 15174 15175 /** 15176 * Take a potentially misbehaving resolver function and make sure 15177 * onFulfilled and onRejected are only called once. 15178 * 15179 * Makes no guarantees about asynchrony. 15180 */ 15181 function doResolve(fn, self) { 15182 var done = false; 15183 try { 15184 fn( 15185 function(value) { 15186 if (done) return; 15187 done = true; 15188 resolve(self, value); 15189 }, 15190 function(reason) { 15191 if (done) return; 15192 done = true; 15193 reject(self, reason); 15194 } 15195 ); 15196 } catch (ex) { 15197 if (done) return; 15198 done = true; 15199 reject(self, ex); 15200 } 15201 } 15202 15203 Promise$1.prototype['catch'] = function(onRejected) { 15204 return this.then(null, onRejected); 15205 }; 15206 15207 Promise$1.prototype.then = function(onFulfilled, onRejected) { 15208 // @ts-ignore 15209 var prom = new this.constructor(noop); 15210 15211 handle(this, new Handler(onFulfilled, onRejected, prom)); 15212 return prom; 15213 }; 15214 15215 Promise$1.prototype['finally'] = finallyConstructor; 15216 15217 Promise$1.all = function(arr) { 15218 return new Promise$1(function(resolve, reject) { 15219 if (!arr || typeof arr.length === 'undefined') 15220 throw new TypeError('Promise.all accepts an array'); 15221 var args = Array.prototype.slice.call(arr); 15222 if (args.length === 0) return resolve([]); 15223 var remaining = args.length; 15224 15225 function res(i, val) { 15226 try { 15227 if (val && (typeof val === 'object' || typeof val === 'function')) { 15228 var then = val.then; 15229 if (typeof then === 'function') { 15230 then.call( 15231 val, 15232 function(val) { 15233 res(i, val); 15234 }, 15235 reject 15236 ); 15237 return; 15238 } 15239 } 15240 args[i] = val; 15241 if (--remaining === 0) { 15242 resolve(args); 15243 } 15244 } catch (ex) { 15245 reject(ex); 15246 } 15247 } 15248 15249 for (var i = 0; i < args.length; i++) { 15250 res(i, args[i]); 15251 } 15252 });
15253 }; 15254 15255 Promise$1.resolve = function(value) { 15256 if (value && typeof value === 'object' && value.constructor === Promise$1) { 15257 return value; 15258 } 15259 15260 return new Promise$1(function(resolve) { 15261 resolve(value); 15262 }); 15263 }; 15264 15265 Promise$1.reject = function(value) { 15266 return new Promise$1(function(resolve, reject) { 15267 reject(value); 15268 }); 15269 }; 15270 15271 Promise$1.race = function(values) { 15272 return new Promise$1(function(resolve, reject) { 15273 for (var i = 0, len = values.length; i < len; i++) { 15274 values[i].then(resolve, reject); 15275 } 15276 }); 15277 }; 15278 15279 // Use polyfill for setImmediate for performance gains 15280 Promise$1._immediateFn = 15281 (typeof setImmediate === 'function' && 15282 function(fn) { 15283 setImmediate(fn); 15284 }) || 15285 function(fn) { 15286 setTimeoutFunc(fn, 0); 15287 }; 15288 15289 Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) { 15290 if (typeof console !== 'undefined' && console) { 15291 console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console 15292 } 15293 }; 15294 15295 var Exports = 15296 /*#__PURE__*/ 15297 function () { 15298 function Exports(ctx) { 15299 _classCallCheck(this, Exports); 15300 15301 this.ctx = ctx; 15302 this.w = ctx.w; 15303 } 15304 15305 _createClass(Exports, [{ 15306 key: "getSvgString", 15307 value: function getSvgString() { 15308 return this.w.globals.dom.Paper.svg(); 15309 } 15310 }, { 15311 key: "cleanup", 15312 value: function cleanup() { 15313 var w = this.w; // hide some elements to avoid printing them on exported svg 15314 15315 var xcrosshairs = w.globals.dom.baseEl.querySelector('.apexcharts-xcrosshairs'); 15316 var ycrosshairs = w.globals.dom.baseEl.querySelector('.apexcharts-ycrosshairs'); 15317 15318 if (xcrosshairs) { 15319 xcrosshairs.setAttribute('x', -500); 15320 } 15321 15322 if (ycrosshairs) { 15323 ycrosshairs.setAttribute('y1', -100); 15324 ycrosshairs.setAttribute('y2', -100); 15325 } 15326 } 15327 }, { 15328 key: "svgUrl", 15329 value: function svgUrl() { 15330 this.cleanup(); 15331 var svgData = this.getSvgString(); 15332 var svgBlob = new Blob([svgData], { 15333 type: 'image/svg+xml;charset=utf-8' 15334 }); 15335 return URL.createObjectURL(svgBlob); 15336 } 15337 }, { 15338 key: "dataURI", 15339 value: function dataURI() { 15340 var _this = this; 15341 15342 return new Promise$1(function (resolve) { 15343 var w = _this.w; 15344 15345 _this.cleanup(); 15346 15347 var canvas = document.createElement('canvas'); 15348 canvas.width = w.globals.svgWidth; 15349 canvas.height = w.globals.svgHeight; 15350 var canvasBg = w.config.chart.background === 'transparent' ? '#fff' : w.config.chart.background; 15351 var ctx = canvas.getContext('2d'); 15352 ctx.fillStyle = canvasBg; 15353 ctx.fillRect(0, 0, canvas.width, canvas.height); 15354 var DOMURL = window.URL || window.webkitURL || window; 15355 var img = new Image(); 15356 img.crossOrigin = 'anonymous'; 15357 15358 var svgData = _this.getSvgString(); 15359 15360 var svgUrl = 'data:image/svg+xml,' + encodeURIComponent(svgData); 15361 15362 img.onload = function () { 15363 ctx.drawImage(img, 0, 0); 15364 DOMURL.revokeObjectURL(svgUrl); 15365 var imgURI = canvas.toDataURL('image/png'); 15366 resolve(imgURI); 15367 }; 15368 15369 img.src = svgUrl; 15370 }); 15371 } 15372 }, { 15373 key: "exportToSVG", 15374 value: function exportToSVG() { 15375 this.triggerDownload(this.svgUrl(), '.svg'); 15376 } 15377 }, { 15378 key: "exportToPng", 15379 value: function exportToPng() { 15380 var _this2 = this; 15381 15382 this.dataURI().then(function (imgURI) { 15383 _this2.triggerDownload(imgURI, '.png'); 15384 }); 15385 } 15386 }, { 15387 key: "triggerDownload", 15388 value: function triggerDownload(href, ext) { 15389 var downloadLink = document.createElement('a'); 15390 downloadLink.href = href; 15391 downloadLink.download = this.w.globals.chartID + ext; 15392 document.body.appendChild(downloadLink); 15393 downloadLink.click(); 15394 document.body.removeChild(downloadLink); 15395 } 15396 }]); 15397 15398 return Exports; 15399 }(); 15400 15401 /** 15402 * ApexCharts Grid Class for drawing Cartesian Grid. 15403 * 15404 * @module Grid 15405 **/ 15406 15407 var Grid = 15408 /*#__PURE__*/ 15409 function () { 15410 function Grid(ctx) { 15411 _classCallCheck(this, Grid); 15412 15413 this.ctx = ctx; 15414 this.w = ctx.w; 15415 var w = this.w; 15416 this.anim = new Animations(this.ctx); 15417 this.xaxisLabels = w.globals.labels.slice(); 15418 this.animX = w.config.grid.xaxis.lines.animate && w.config.chart.animations.enabled; 15419 this.animY = w.config.grid.yaxis.lines.animate && w.config.chart.animations.enabled; 15420 15421 if (w.globals.timelineLabels.length > 0) { 15422 // timeline labels are there 15423 this.xaxisLabels = w.globals.timelineLabels.slice(); 15424 } 15425 } // .when using sparklines or when showing no grid, we need to have a grid area which is reused at many places for other calculations as well 15426 15427 15428 _createClass(Grid, [{ 15429 key: "drawGridArea", 15430 value: function drawGridArea() { 15431 var elGrid = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 15432 var w = this.w; 15433 var graphics = new Graphics(this.ctx); 15434 15435 if (elGrid === null) { 15436 elGrid = graphics.group({ 15437 class: 'apexcharts-grid' 15438 }); 15439 } 15440 15441 var elVerticalLine = graphics.drawLine(w.globals.padHorizontal, 1, w.globals.padHorizontal, w.globals.gridHeight, 'transparent'); 15442 var elHorzLine = graphics.drawLine(w.globals.padHorizontal, w.globals.gridHeight, w.globals.gridWidth, w.globals.gridHeight, 'transparent'); 15443 elGrid.add(elHorzLine); 15444 elGrid.add(elVerticalLine); 15445 return elGrid; 15446 } 15447 }, { 15448 key: "drawGrid", 15449 value: function drawGrid() { 15450 var w = this.w; 15451 var xAxis = new XAxis(this.ctx); 15452 var yaxis = new YAxis(this.ctx); 15453 var gl = this.w.globals; 15454 var elgrid = null; 15455 15456 if (gl.axisCharts) { 15457 if (w.config.grid.show) { 15458 // grid is drawn after xaxis and yaxis are drawn 15459 elgrid = this.renderGrid(); 15460 gl.dom.elGraphical.add(elgrid.el);
15461 this.drawGridArea(elgrid.el); 15462 } else { 15463 var elgridArea = this.drawGridArea(); 15464 gl.dom.elGraphical.add(elgridArea); 15465 } 15466 15467 if (elgrid !== null) { 15468 xAxis.xAxisLabelCorrections(elgrid.xAxisTickWidth); 15469 } 15470 15471 yaxis.setYAxisTextAlignments(); 15472 } 15473 } // This mask will clip off overflowing graphics from the drawable area 15474 15475 }, { 15476 key: "createGridMask", 15477 value: function createGridMask() { 15478 var w = this.w; 15479 var gl = w.globals; 15480 var graphics = new Graphics(this.ctx); 15481 var strokeSize = Array.isArray(w.config.stroke.width) ? 0 : w.config.stroke.width; 15482 15483 if (Array.isArray(w.config.stroke.width)) { 15484 var strokeMaxSize = 0; 15485 w.config.stroke.width.forEach(function (m) { 15486 strokeMaxSize = Math.max(strokeMaxSize, m); 15487 }); 15488 strokeSize = strokeMaxSize; 15489 } 15490 15491 gl.dom.elGridRectMask = document.createElementNS(gl.SVGNS, 'clipPath'); 15492 gl.dom.elGridRectMask.setAttribute('id', "gridRectMask".concat(gl.cuid)); 15493 gl.dom.elGridRectMarkerMask = document.createElementNS(gl.SVGNS, 'clipPath'); 15494 gl.dom.elGridRectMarkerMask.setAttribute('id', "gridRectMarkerMask".concat(gl.cuid)); 15495 gl.dom.elGridRect = graphics.drawRect(-strokeSize / 2, -strokeSize / 2, gl.gridWidth + strokeSize, gl.gridHeight + strokeSize, 0, '#fff'); 15496 var coreUtils = new CoreUtils(this); 15497 coreUtils.getLargestMarkerSize(); 15498 var markerSize = w.globals.markers.largestSize + 1;
15499 gl.dom.elGridRectMarker = graphics.drawRect(-markerSize, -markerSize, gl.gridWidth + markerSize * 2, gl.gridHeight + markerSize * 2, 0, '#fff'); 15500 gl.dom.elGridRectMask.appendChild(gl.dom.elGridRect.node); 15501 gl.dom.elGridRectMarkerMask.appendChild(gl.dom.elGridRectMarker.node); 15502 var defs = gl.dom.baseEl.querySelector('defs'); 15503 defs.appendChild(gl.dom.elGridRectMask); 15504 defs.appendChild(gl.dom.elGridRectMarkerMask); 15505 } // actual grid rendering 15506 15507 }, { 15508 key: "renderGrid", 15509 value: function renderGrid() { 15510 var w = this.w; 15511 var graphics = new Graphics(this.ctx); 15512 var strokeDashArray = w.config.grid.strokeDashArray; 15513 var elg = graphics.group({ 15514 class: 'apexcharts-grid' 15515 }); 15516 var elgridLinesH = graphics.group({ 15517 class: 'apexcharts-gridlines-horizontal' 15518 }); 15519 var elgridLinesV = graphics.group({ 15520 class: 'apexcharts-gridlines-vertical' 15521 }); 15522 elg.add(elgridLinesH); 15523 elg.add(elgridLinesV); 15524 var tickAmount = 8; 15525 15526 for (var i = 0; i < w.globals.series.length; i++) { 15527 if (typeof w.globals.yAxisScale[i] !== 'undefined') { 15528 tickAmount = w.globals.yAxisScale[i].result.length - 1; 15529 } 15530 15531 if (tickAmount > 2) break; 15532 } 15533 15534 var xCount; 15535 15536 if (!w.globals.isBarHorizontal) { 15537 xCount = this.xaxisLabels.length; // draw vertical lines 15538 15539 if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) { 15540 var x1 = w.globals.padHorizontal; 15541 var y1 = 0; 15542 var x2; 15543 var y2 = w.globals.gridHeight; 15544 15545 if (w.globals.timelineLabels.length > 0) { 15546 for (var _i = 0; _i < xCount; _i++) { 15547 x1 = this.xaxisLabels[_i].position; 15548 x2 = this.xaxisLabels[_i].position; 15549 15550 if (w.config.grid.xaxis.lines.show && x1 > 0 && x1 < w.globals.gridWidth) { 15551 var line = graphics.drawLine(x1, y1, x2, y2, w.config.grid.borderColor, strokeDashArray);
15552 line.node.classList.add('apexcharts-gridline'); 15553 elgridLinesV.add(line); 15554 15555 if (this.animX) { 15556 this.animateLine(line, { 15557 x1: 0, 15558 x2: 0 15559 }, { 15560 x1: x1, 15561 x2: x2 15562 }); 15563 } 15564 } 15565 15566 var xAxis = new XAxis(this.ctx); 15567 15568 if (_i === xCount - 1) { 15569 if (!w.globals.skipLastTimelinelabel) { 15570 // skip drawing last label here 15571 xAxis.drawXaxisTicks(x1, elg); 15572 } 15573 } else { 15574 xAxis.drawXaxisTicks(x1, elg); 15575 } 15576 } 15577 } else { 15578 var xCountForCategoryCharts = xCount; 15579 15580 for (var _i2 = 0; _i2 < xCountForCategoryCharts; _i2++) { 15581 var x1Count = xCountForCategoryCharts; 15582 15583 if (w.globals.isXNumeric && w.config.chart.type !== 'bar') { 15584 x1Count -= 1;
15585 } 15586 15587 x1 = x1 + w.globals.gridWidth / x1Count; 15588 x2 = x1; // skip the last line 15589 15590 if (_i2 === x1Count - 1) break; 15591 15592 if (w.config.grid.xaxis.lines.show) { 15593 var _line = graphics.drawLine(x1, y1, x2, y2, w.config.grid.borderColor, strokeDashArray); 15594 15595 _line.node.classList.add('apexcharts-gridline'); 15596 15597 elgridLinesV.add(_line); 15598 15599 if (this.animX) { 15600 this.animateLine(_line, { 15601 x1: 0, 15602 x2: 0 15603 }, { 15604 x1: x1, 15605 x2: x2 15606 }); 15607 } 15608 } 15609 15610 var _xAxis = new XAxis(this.ctx); 15611 15612 _xAxis.drawXaxisTicks(x1, elg); 15613 } 15614 } 15615 } // draw horizontal lines 15616 15617 15618 if (w.config.grid.yaxis.lines.show) { 15619 var _x = 0; 15620 var _y = 0; 15621 var _y2 = 0; 15622 var _x2 = w.globals.gridWidth; 15623 15624 for (var _i3 = 0; _i3 < tickAmount + 1; _i3++) { 15625 var _line2 = graphics.drawLine(_x, _y, _x2, _y2, w.config.grid.borderColor, strokeDashArray);
15626 15627 elgridLinesH.add(_line2); 15628 15629 _line2.node.classList.add('apexcharts-gridline'); 15630 15631 if (this.animY) { 15632 this.animateLine(_line2, { 15633 y1: _y + 20, 15634 y2: _y2 + 20 15635 }, { 15636 y1: _y, 15637 y2: _y2 15638 }); 15639 } 15640 15641 _y = _y + w.globals.gridHeight / tickAmount; 15642 _y2 = _y; 15643 } 15644 } 15645 } else { 15646 xCount = tickAmount; // draw vertical lines 15647 15648 if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) { 15649 var _x3 = w.globals.padHorizontal; 15650 var _y3 = 0; 15651 15652 var _x4; 15653 15654 var _y4 = w.globals.gridHeight; 15655 15656 for (var _i4 = 0; _i4 < xCount + 1; _i4++) { 15657 _x3 = _x3 + w.globals.gridWidth / xCount + 0.3; 15658 _x4 = _x3; // skip the last vertical line 15659 15660 if (_i4 === xCount - 1) break; 15661 15662 if (w.config.grid.xaxis.lines.show) { 15663 var _line3 = graphics.drawLine(_x3, _y3, _x4, _y4, w.config.grid.borderColor, strokeDashArray);
15664 15665 _line3.node.classList.add('apexcharts-gridline'); 15666 15667 elgridLinesV.add(_line3); 15668 15669 if (this.animX) { 15670 this.animateLine(_line3, { 15671 x1: 0, 15672 x2: 0 15673 }, { 15674 x1: _x3, 15675 x2: _x4 15676 }); 15677 } 15678 } // skip the first vertical line 15679 15680 15681 var _xAxis2 = new XAxis(this.ctx); 15682 15683 _xAxis2.drawXaxisTicks(_x3, elg); 15684 } 15685 } // draw horizontal lines 15686 15687 15688 if (w.config.grid.yaxis.lines.show) { 15689 var _x5 = 0; 15690 var _y5 = 0; 15691 var _y6 = 0; 15692 var _x6 = w.globals.gridWidth; 15693 15694 for (var _i5 = 0; _i5 < w.globals.dataPoints + 1; _i5++) { 15695 var _line4 = graphics.drawLine(_x5, _y5, _x6, _y6, w.config.grid.borderColor, strokeDashArray); 15696 15697 elgridLinesH.add(_line4); 15698 15699 _line4.node.classList.add('apexcharts-gridline'); 15700 15701 if (this.animY) { 15702 this.animateLine(_line4, { 15703 y1: _y5 + 20, 15704 y2: _y6 + 20 15705 }, { 15706 y1: _y5, 15707 y2: _y6 15708 }); 15709 } 15710 15711 _y5 = _y5 + w.globals.gridHeight / w.globals.dataPoints; 15712 _y6 = _y5; 15713 } 15714 } 15715 } 15716 15717 this.drawGridBands(elg, xCount, tickAmount); 15718 return { 15719 el: elg, 15720 xAxisTickWidth: w.globals.gridWidth / xCount 15721 }; 15722 } 15723 }, { 15724 key: "drawGridBands", 15725 value: function drawGridBands(elg, xCount, tickAmount) { 15726 var w = this.w; 15727 var graphics = new Graphics(this.ctx); // rows background bands 15728 15729 if (w.config.grid.row.colors !== undefined && w.config.grid.row.colors.length > 0) { 15730 var x1 = 0; 15731 var y1 = 0; 15732 var y2 = w.globals.gridHeight / tickAmount; 15733 var x2 = w.globals.gridWidth; 15734 15735 for (var i = 0, c = 0; i < tickAmount; i++, c++) { 15736 if (c >= w.config.grid.row.colors.length) { 15737 c = 0; 15738 } 15739 15740 var color = w.config.grid.row.colors[c]; 15741 var rect = graphics.drawRect(x1, y1, x2, y2, 0, color, w.config.grid.row.opacity); 15742 elg.add(rect); 15743 rect.node.classList.add('apexcharts-gridRow'); 15744 y1 = y1 + w.globals.gridHeight / tickAmount; 15745 } 15746 } // columns background bands 15747 15748 15749 if (w.config.grid.column.colors !== undefined && w.config.grid.column.colors.length > 0) { 15750 var _x7 = w.globals.padHorizontal; 15751 var _y7 = 0; 15752 15753 var _x8 = w.globals.padHorizontal + w.globals.gridWidth / xCount; 15754 15755 var _y8 = w.globals.gridHeight; 15756 15757 for (var _i6 = 0, _c = 0; _i6 < xCount; _i6++, _c++) { 15758 if (_c >= w.config.grid.column.colors.length) { 15759 _c = 0; 15760 } 15761 15762 var _color = w.config.grid.column.colors[_c]; 15763 15764 var _rect = graphics.drawRect(_x7, _y7, _x8, _y8, 0, _color, w.config.grid.column.opacity); 15765 15766 _rect.node.classList.add('apexcharts-gridColumn'); 15767 15768 elg.add(_rect); 15769 _x7 = _x7 + w.globals.gridWidth / xCount; 15770 } 15771 } 15772 } 15773 }, { 15774 key: "animateLine", 15775 value: function animateLine(line, from, to) { 15776 var w = this.w; 15777 var initialAnim = w.config.chart.animations; 15778 15779 if (initialAnim && !w.globals.resized && !w.globals.dataChanged) { 15780 var speed = initialAnim.speed; 15781 this.anim.animateLine(line, from, to, speed); 15782 } 15783 } 15784 }]); 15785 15786 return Grid; 15787 }(); 15788 15789 /** 15790 * ApexCharts Legend Class to draw legend. 15791 * 15792 * @module Legend 15793 **/ 15794 15795 var Legend = 15796 /*#__PURE__*/ 15797 function () { 15798 function Legend(ctx, opts) { 15799 _classCallCheck(this, Legend); 15800 15801 this.ctx = ctx; 15802 this.w = ctx.w; 15803 this.onLegendClick = this.onLegendClick.bind(this); 15804 this.onLegendHovered = this.onLegendHovered.bind(this); 15805 } 15806 15807 _createClass(Legend, [{ 15808 key: "init",
15809 value: function init() { 15810 var w = this.w; 15811 var gl = w.globals; 15812 var cnf = w.config; 15813 var showLegendAlways = cnf.legend.showForSingleSeries && gl.series.length === 1 || gl.series.length > 1; 15814 15815 if ((showLegendAlways || !gl.axisCharts) && cnf.legend.show) { 15816 while (gl.dom.elLegendWrap.firstChild) { 15817 gl.dom.elLegendWrap.removeChild(gl.dom.elLegendWrap.firstChild); 15818 } 15819 15820 this.drawLegends(); 15821 15822 if (!Utils.isIE11()) { 15823 this.appendToForeignObject(); 15824 } else { 15825 // IE11 doesn't supports foreignObject, hence append it to <head> 15826 document.getElementsByTagName('head')[0].appendChild(this.getLegendStyles()); 15827 } 15828 15829 if (cnf.legend.position === 'bottom' || cnf.legend.position === 'top') { 15830 this.legendAlignHorizontal(); 15831 } else if (cnf.legend.position === 'right' || cnf.legend.position === 'left') { 15832 this.legendAlignVertical(); 15833 } 15834 } 15835 } 15836 }, { 15837 key: "appendToForeignObject", 15838 value: function appendToForeignObject() { 15839 var gl = this.w.globals; 15840 var elForeign = document.createElementNS(gl.SVGNS, 'foreignObject'); 15841 elForeign.setAttribute('x', 0); 15842 elForeign.setAttribute('y', 0); 15843 elForeign.setAttribute('width', gl.svgWidth); 15844 elForeign.setAttribute('height', gl.svgHeight); 15845 gl.dom.elLegendWrap.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); 15846 elForeign.appendChild(gl.dom.elLegendWrap); 15847 elForeign.appendChild(this.getLegendStyles()); 15848 gl.dom.Paper.node.insertBefore(elForeign, gl.dom.elGraphical.node); 15849 } 15850 }, { 15851 key: "drawLegends", 15852 value: function drawLegends() { 15853 var self = this; 15854 var w = this.w; 15855 var fontFamily = w.config.legend.fontFamily; 15856 var legendNames = w.globals.seriesNames; 15857 var fillcolor = w.globals.colors.slice(); 15858 15859 if (w.config.chart.type === 'heatmap') { 15860 var ranges = w.config.plotOptions.heatmap.colorScale.ranges; 15861 legendNames = ranges.map(function (colorScale) { 15862 return colorScale.name ? colorScale.name : colorScale.from + ' - ' + colorScale.to; 15863 }); 15864 fillcolor = ranges.map(function (color) { 15865 return color.color; 15866 }); 15867 } 15868 15869 var legendFormatter = w.globals.legendFormatter; 15870 15871 for (var i = 0; i <= legendNames.length - 1; i++) { 15872 var text = legendFormatter(legendNames[i], { 15873 seriesIndex: i, 15874 w: w 15875 }); 15876 var collapsedSeries = false; 15877 var ancillaryCollapsedSeries = false; 15878 15879 if (w.globals.collapsedSeries.length > 0) { 15880 for (var c = 0; c < w.globals.collapsedSeries.length; c++) { 15881 if (w.globals.collapsedSeries[c].index === i) { 15882 collapsedSeries = true; 15883 } 15884 } 15885 } 15886 15887 if (w.globals.ancillaryCollapsedSeriesIndices.length > 0) { 15888 for (var _c = 0; _c < w.globals.ancillaryCollapsedSeriesIndices.length; _c++) { 15889 if (w.globals.ancillaryCollapsedSeriesIndices[_c] === i) { 15890 ancillaryCollapsedSeries = true; 15891 } 15892 } 15893 } 15894 15895 var elMarker = document.createElement('span'); 15896 elMarker.classList.add('apexcharts-legend-marker'); 15897 var mOffsetX = w.config.legend.markers.offsetX; 15898 var mOffsetY = w.config.legend.markers.offsetY; 15899 var mHeight = w.config.legend.markers.height; 15900 var mWidth = w.config.legend.markers.width; 15901 var mBorderWidth = w.config.legend.markers.strokeWidth; 15902 var mBorderColor = w.config.legend.markers.strokeColor; 15903 var mBorderRadius = w.config.legend.markers.radius; 15904 var mStyle = elMarker.style; 15905 mStyle.background = fillcolor[i]; 15906 mStyle.color = fillcolor[i]; 15907 mStyle.height = Array.isArray(mHeight) ? parseFloat(mHeight[i]) + 'px' : parseFloat(mHeight) + 'px'; 15908 mStyle.width = Array.isArray(mWidth) ? parseFloat(mWidth[i]) + 'px' : parseFloat(mWidth) + 'px'; 15909 mStyle.left = Array.isArray(mOffsetX) ? mOffsetX[i] : mOffsetX; 15910 mStyle.top = Array.isArray(mOffsetY) ? mOffsetY[i] : mOffsetY; 15911 mStyle.borderWidth = Array.isArray(mBorderWidth) ? mBorderWidth[i] : mBorderWidth; 15912 mStyle.borderColor = Array.isArray(mBorderColor) ? mBorderColor[i] : mBorderColor; 15913 mStyle.borderRadius = Array.isArray(mBorderRadius) ? parseFloat(mBorderRadius[i]) + 'px' : parseFloat(mBorderRadius) + 'px'; 15914 15915 if (w.config.legend.markers.customHTML) { 15916 if (Array.isArray(w.config.legend.markers.customHTML)) { 15917 elMarker.innerHTML = w.config.legend.markers.customHTML[i]();
15918 } else { 15919 elMarker.innerHTML = w.config.legend.markers.customHTML(); 15920 } 15921 } 15922 15923 Graphics.setAttrs(elMarker, { 15924 rel: i + 1, 15925 'data:collapsed': collapsedSeries || ancillaryCollapsedSeries 15926 }); 15927 15928 if (collapsedSeries || ancillaryCollapsedSeries) { 15929 elMarker.classList.add('inactive-legend'); 15930 } 15931 15932 var elLegend = document.createElement('div'); 15933 var elLegendText = document.createElement('span'); 15934 elLegendText.classList.add('apexcharts-legend-text'); 15935 elLegendText.innerHTML = text; 15936 var textColor = w.config.legend.labels.useSeriesColors ? w.globals.colors[i] : w.config.legend.labels.colors; 15937 15938 if (!textColor) { 15939 textColor = w.config.chart.foreColor; 15940 } 15941 15942 elLegendText.style.color = textColor; 15943 elLegendText.style.fontSize = parseFloat(w.config.legend.fontSize) + 'px'; 15944 elLegendText.style.fontFamily = fontFamily || w.config.chart.fontFamily; 15945 Graphics.setAttrs(elLegendText, { 15946 rel: i + 1, 15947 'data:collapsed': collapsedSeries || ancillaryCollapsedSeries 15948 }); 15949 elLegend.appendChild(elMarker); 15950 elLegend.appendChild(elLegendText); 15951 var coreUtils = new CoreUtils(this.ctx); 15952 15953 if (!w.config.legend.showForZeroSeries) { 15954 var total = coreUtils.getSeriesTotalByIndex(i); 15955 15956 if (total === 0 && coreUtils.seriesHaveSameValues(i) && !coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) { 15957 elLegend.classList.add('apexcharts-hidden-zero-series'); 15958 } 15959 } 15960 15961 if (!w.config.legend.showForNullSeries) { 15962 if (coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) { 15963 elLegend.classList.add('apexcharts-hidden-null-series'); 15964 } 15965 } 15966 15967 w.globals.dom.elLegendWrap.appendChild(elLegend); 15968 w.globals.dom.elLegendWrap.classList.add(w.config.legend.horizontalAlign); // w.globals.dom.elLegendWrap.classList.add(w.config.legend.verticalAlign) 15969 15970 w.globals.dom.elLegendWrap.classList.add('position-' + w.config.legend.position); 15971 elLegend.classList.add('apexcharts-legend-series'); 15972 elLegend.style.margin = "".concat(w.config.legend.itemMargin.horizontal, "px ").concat(w.config.legend.itemMargin.vertical, "px"); 15973 w.globals.dom.elLegendWrap.style.width = w.config.legend.width ? w.config.legend.width + 'px' : ''; 15974 w.globals.dom.elLegendWrap.style.height = w.config.legend.height ? w.config.legend.height + 'px' : ''; 15975 Graphics.setAttrs(elLegend, { 15976 rel: i + 1, 15977 'data:collapsed': collapsedSeries || ancillaryCollapsedSeries 15978 }); 15979 15980 if (collapsedSeries || ancillaryCollapsedSeries) { 15981 elLegend.classList.add('inactive-legend'); 15982 } 15983 15984 if (!w.config.legend.onItemClick.toggleDataSeries) { 15985 elLegend.classList.add('no-click'); 15986 } 15987 } // for now - just prevent click on heatmap legend - and allow hover only 15988 15989 15990 var clickAllowed = w.config.chart.type !== 'heatmap'; 15991 15992 if (clickAllowed && w.config.legend.onItemClick.toggleDataSeries) { 15993 w.globals.dom.elWrap.addEventListener('click', self.onLegendClick, true); 15994 } 15995 15996 if (w.config.legend.onItemHover.highlightDataSeries) { 15997 w.globals.dom.elWrap.addEventListener('mousemove', self.onLegendHovered, true); 15998 w.globals.dom.elWrap.addEventListener('mouseout', self.onLegendHovered, true); 15999 } 16000 } 16001 }, { 16002 key: "getLegendBBox", 16003 value: function getLegendBBox() { 16004 var w = this.w; 16005 var currLegendsWrap = w.globals.dom.baseEl.querySelector('.apexcharts-legend'); 16006 var currLegendsWrapRect = currLegendsWrap.getBoundingClientRect(); 16007 var currLegendsWrapWidth = currLegendsWrapRect.width; 16008 var currLegendsWrapHeight = currLegendsWrapRect.height; 16009 return { 16010 clwh: currLegendsWrapHeight, 16011 clww: currLegendsWrapWidth 16012 }; 16013 } 16014 }, { 16015 key: "setLegendWrapXY", 16016 value: function setLegendWrapXY(offsetX, offsetY) { 16017 var w = this.w; 16018 var elLegendWrap = w.globals.dom.baseEl.querySelector('.apexcharts-legend'); 16019 var legendRect = elLegendWrap.getBoundingClientRect(); 16020 var x = 0; 16021 var y = 0; 16022 16023 if (w.config.legend.position === 'bottom') { 16024 y = y + (w.globals.svgHeight - legendRect.height / 2); 16025 } else if (w.config.legend.position === 'top') { 16026 var dim = new Dimensions(this.ctx); 16027 var titleH = dim.getTitleSubtitleCoords('title').height; 16028 var subtitleH = dim.getTitleSubtitleCoords('subtitle').height; 16029 y = y + (titleH > 0 ? titleH - 10 : 0) + (subtitleH > 0 ? subtitleH - 10 : 0); 16030 } 16031 16032 elLegendWrap.style.position = 'absolute'; 16033 x = x + offsetX + w.config.legend.offsetX; 16034 y = y + offsetY + w.config.legend.offsetY; 16035 elLegendWrap.style.left = x + 'px'; 16036 elLegendWrap.style.top = y + 'px'; 16037 16038 if (w.config.legend.position === 'bottom') { 16039 elLegendWrap.style.top = 'auto'; 16040 elLegendWrap.style.bottom = 10 + w.config.legend.offsetY + 'px'; 16041 } else if (w.config.legend.position === 'right') { 16042 elLegendWrap.style.left = 'auto'; 16043 elLegendWrap.style.right = 25 + w.config.legend.offsetX + 'px'; 16044 } 16045 16046 if (elLegendWrap.style.width) { 16047 elLegendWrap.style.width = parseInt(w.config.legend.width) + 'px'; 16048 } 16049 16050 if (elLegendWrap.style.height) { 16051 elLegendWrap.style.height = parseInt(w.config.legend.height) + 'px'; 16052 } 16053 } 16054 }, { 16055 key: "legendAlignHorizontal", 16056 value: function legendAlignHorizontal() { 16057 var w = this.w; 16058 var elLegendWrap = w.globals.dom.baseEl.querySelector('.apexcharts-legend'); 16059 elLegendWrap.style.right = 0; 16060 var lRect = this.getLegendBBox(); 16061 var dimensions = new Dimensions(this.ctx); 16062 var titleRect = dimensions.getTitleSubtitleCoords('title'); 16063 var subtitleRect = dimensions.getTitleSubtitleCoords('subtitle'); 16064 var offsetX = 20; 16065 var offsetY = 0; // the whole legend box is set to bottom 16066 16067 if (w.config.legend.position === 'bottom') { 16068 offsetY = -lRect.clwh / 1.8; 16069 } else if (w.config.legend.position === 'top') { 16070 offsetY = titleRect.height + subtitleRect.height + w.config.title.margin + w.config.subtitle.margin - 15; 16071 } 16072 16073 this.setLegendWrapXY(offsetX, offsetY); 16074 } 16075 }, { 16076 key: "legendAlignVertical", 16077 value: function legendAlignVertical() { 16078 var w = this.w; 16079 var lRect = this.getLegendBBox(); 16080 var offsetY = 20; 16081 var offsetX = 0; 16082 16083 if (w.config.legend.position === 'left') { 16084 offsetX = 20; 16085 } 16086 16087 if (w.config.legend.position === 'right') { 16088 offsetX = w.globals.svgWidth - lRect.clww - 10; 16089 } 16090 16091 this.setLegendWrapXY(offsetX, offsetY); 16092 } 16093 }, { 16094 key: "onLegendHovered", 16095 value: function onLegendHovered(e) { 16096 var w = this.w; 16097 var hoverOverLegend = e.target.classList.contains('apexcharts-legend-text') || e.target.classList.contains('apexcharts-legend-marker'); 16098 16099 if (w.config.chart.type !== 'heatmap') { 16100 if (!e.target.classList.contains('inactive-legend') && hoverOverLegend) { 16101 var series = new Series(this.ctx); 16102 series.toggleSeriesOnHover(e, e.target); 16103 } 16104 } else { 16105 // for heatmap handling 16106 if (hoverOverLegend) { 16107 var seriesCnt = parseInt(e.target.getAttribute('rel')) - 1; 16108 this.ctx.fireEvent('legendHover', [this.ctx, seriesCnt, this.w]); 16109 16110 var _series = new Series(this.ctx); 16111 16112 _series.highlightRangeInSeries(e, e.target); 16113 } 16114 } 16115 } 16116 }, { 16117 key: "onLegendClick", 16118 value: function onLegendClick(e) { 16119 if (e.target.classList.contains('apexcharts-legend-text') || e.target.classList.contains('apexcharts-legend-marker')) { 16120 var seriesCnt = parseInt(e.target.getAttribute('rel')) - 1; 16121 var isHidden = e.target.getAttribute('data:collapsed') === 'true'; 16122 var legendClick = this.w.config.chart.events.legendClick; 16123 16124 if (typeof legendClick === 'function') { 16125 legendClick(this.ctx, seriesCnt, this.w); 16126 } 16127 16128 this.ctx.fireEvent('legendClick', [this.ctx, seriesCnt, this.w]); 16129 var markerClick = this.w.config.legend.markers.onClick; 16130 16131 if (typeof markerClick === 'function' && e.target.classList.contains('apexcharts-legend-marker')) { 16132 markerClick(this.ctx, seriesCnt, this.w); 16133 this.ctx.fireEvent('legendMarkerClick', [this.ctx, seriesCnt, this.w]); 16134 } 16135 16136 this.toggleDataSeries(seriesCnt, isHidden); 16137 } 16138 } 16139 }, { 16140 key: "getLegendStyles", 16141 value: function getLegendStyles() { 16142 var stylesheet = document.createElement('style'); 16143 stylesheet.setAttribute('type', 'text/css'); 16144 var text = "\n \n .apexcharts-legend {\n display: flex;\n overflow: auto;\n padding: 0 10px;\n }\n\n .apexcharts-legend.position-bottom, .apexcharts-legend.position-top {\n flex-wrap: wrap\n }\n .apexcharts-legend.position-right, .apexcharts-legend.position-left {\n flex-direction: column;\n bottom: 0;\n }\n\n .apexcharts-legend.position-bottom.left, .apexcharts-legend.position-top.left, .apexcharts-legend.position-right, .apexcharts-legend.position-left {\n justify-content: flex-start;\n }\n\n .apexcharts-legend.position-bottom.center, .apexcharts-legend.position-top.center {\n justify-content: center; \n }\n\n .apexcharts-legend.position-bottom.right, .apexcharts-legend.position-top.right {\n justify-content: flex-end;\n }\n\n .apexcharts-legend-series {\n cursor: pointer;\n line-height: normal;\n }\n\n .apexcharts-legend.position-bottom .apexcharts-legend-series, .apexcharts-legend.position-top .apexcharts-legend-series{\n display: flex;\n align-items: center;\n }\n\n .apexcharts-legend-text {\n position: relative;\n font-size: 14px;\n }\n\n .apexcharts-legend-text *, .apexcharts-legend-marker * {\n pointer-events: none;\n }\n\n .apexcharts-legend-marker {\n position: relative;\n display: inline-block;\n cursor: pointer;\n margin-right: 3px;\n }\n \n .apexcharts-legend.right .apexcharts-legend-series, .apexcharts-legend.left .apexcharts-legend-series{\n display: inline-block;\n }\n\n .apexcharts-legend-series.no-click {\n cursor: auto;\n }\n\n .apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {\n display: none !important;\n }\n\n .inactive-legend {\n opacity: 0.45;\n }"; 16145 var rules = document.createTextNode(text); 16146 stylesheet.appendChild(rules); 16147 return stylesheet; 16148 } 16149 }, { 16150 key: "resetToggleDataSeries", 16151 value: function resetToggleDataSeries() { 16152 var w = this.w; 16153 var seriesEls = null;
16154 var realIndexes = []; 16155 16156 if (w.globals.axisCharts) { 16157 seriesEls = w.globals.dom.baseEl.querySelectorAll(".apexcharts-series[data\\:realIndex]"); 16158 seriesEls = Utils.listToArray(seriesEls); 16159 seriesEls.forEach(function (v) { 16160 realIndexes.push(parseInt(v.getAttribute('data:realIndex'))); 16161 }); 16162 } else { 16163 seriesEls = w.globals.dom.baseEl.querySelectorAll(".apexcharts-series[rel]"); 16164 seriesEls = Utils.listToArray(seriesEls); 16165 seriesEls.forEach(function (v) { 16166 realIndexes.push(parseInt(v.getAttribute('rel')) - 1); 16167 }); 16168 } 16169 16170 realIndexes.sort(); 16171 16172 if (w.globals.collapsedSeries.length > 0) { 16173 var risingSeries = w.globals.risingSeries.slice(); 16174 var series = w.config.series.slice(); 16175 16176 for (var c = 0; c < w.globals.collapsedSeries.length; c++) { 16177 var index = realIndexes.indexOf(w.globals.collapsedSeries[c].index); 16178 16179 if (index !== -1) { 16180 if (w.globals.axisCharts) { 16181 series[index].data = w.globals.collapsedSeries.slice()[c].data.slice(); 16182 } else { 16183 series[index] = w.globals.collapsedSeries.slice()[c].data; 16184 } 16185 16186 risingSeries.push(index); 16187 } 16188 } 16189 16190 w.globals.collapsedSeries = []; 16191 w.globals.ancillaryCollapsedSeries = []; 16192 w.globals.collapsedSeriesIndices = []; 16193 w.globals.ancillaryCollapsedSeriesIndices = []; 16194 w.globals.risingSeries = risingSeries; 16195 w.config.series = series; 16196 16197 this.ctx._updateSeries(w.config.series, w.config.chart.animations.dynamicAnimation.enabled); 16198 } 16199 } 16200 }, { 16201 key: "toggleDataSeries", 16202 value: function toggleDataSeries(seriesCnt, isHidden) { 16203 var w = this.w; 16204 16205 if (w.globals.axisCharts || w.config.chart.type === 'radialBar') { 16206 w.globals.resized = true; // we don't want initial animations again 16207 16208 var seriesEl = null; 16209 var realIndex = null; // yes, make it null. 1 series will rise at a time 16210 16211 w.globals.risingSeries = []; 16212 16213 if (w.globals.axisCharts) { 16214 seriesEl = w.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(seriesCnt, "']")); 16215 realIndex = parseInt(seriesEl.getAttribute('data:realIndex')); 16216 } else { 16217 seriesEl = w.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(seriesCnt + 1, "']")); 16218 realIndex = parseInt(seriesEl.getAttribute('rel')) - 1; 16219 } 16220 16221 if (isHidden) { 16222 this.riseCollapsedSeries(w.globals.collapsedSeries, w.globals.collapsedSeriesIndices, realIndex); 16223 this.riseCollapsedSeries(w.globals.ancillaryCollapsedSeries, w.globals.ancillaryCollapsedSeriesIndices, realIndex); 16224 } else { 16225 if (w.globals.axisCharts) { 16226 var shouldNotHideYAxis = false; 16227 16228 if (w.config.yaxis[realIndex] && w.config.yaxis[realIndex].show && w.config.yaxis[realIndex].showAlways) { 16229 shouldNotHideYAxis = true; 16230 16231 if (w.globals.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) { 16232 w.globals.ancillaryCollapsedSeries.push({ 16233 index: realIndex, 16234 data: w.config.series[realIndex].data.slice(), 16235 type: seriesEl.parentNode.className.baseVal.split('-')[1] 16236 }); 16237 w.globals.ancillaryCollapsedSeriesIndices.push(realIndex); 16238 } 16239 } 16240 16241 if (!shouldNotHideYAxis) { 16242 w.globals.collapsedSeries.push({ 16243 index: realIndex, 16244 data: w.config.series[realIndex].data.slice(), 16245 type: seriesEl.parentNode.className.baseVal.split('-')[1] 16246 }); 16247 w.globals.collapsedSeriesIndices.push(realIndex); 16248 var removeIndexOfRising = w.globals.risingSeries.indexOf(realIndex); 16249 w.globals.risingSeries.splice(removeIndexOfRising, 1); 16250 } // TODO: AVOID mutating the user's config object below 16251 16252 16253 w.config.series[realIndex].data = []; 16254 } else { 16255 w.globals.collapsedSeries.push({ 16256 index: realIndex, 16257 data: w.config.series[realIndex] 16258 }); 16259 w.globals.collapsedSeriesIndices.push(realIndex); 16260 w.config.series[realIndex] = 0; 16261 } 16262 16263 var seriesChildren = seriesEl.childNodes; 16264 16265 for (var sc = 0; sc < seriesChildren.length; sc++) { 16266 if (seriesChildren[sc].classList.contains('apexcharts-series-markers-wrap')) { 16267 if (seriesChildren[sc].classList.contains('apexcharts-hide')) { 16268 seriesChildren[sc].classList.remove('apexcharts-hide'); 16269 } else { 16270 seriesChildren[sc].classList.add('apexcharts-hide'); 16271 } 16272 } 16273 } 16274 16275 w.globals.allSeriesCollapsed = w.globals.collapsedSeries.length === w.globals.series.length; 16276 16277 this.ctx._updateSeries(w.config.series, w.config.chart.animations.dynamicAnimation.enabled); 16278 } 16279 } else { 16280 // for non-axis charts i.e pie / donuts 16281 var _seriesEl = w.globals.dom.Paper.select(" .apexcharts-series[rel='".concat(seriesCnt + 1, "'] path")); 16282 16283 var type = w.config.chart.type; 16284 16285 if (type === 'pie' || type === 'donut') { 16286 var dataLabels = w.config.plotOptions.pie.donut.labels; 16287 var graphics = new Graphics(this.ctx); 16288 var pie = new Pie(this.ctx); 16289 graphics.pathMouseDown(_seriesEl.members[0], null); 16290 pie.printDataLabelsInner(_seriesEl.members[0].node, dataLabels); 16291 } 16292
16293 _seriesEl.fire('click'); 16294 } 16295 } 16296 }, { 16297 key: "riseCollapsedSeries", 16298 value: function riseCollapsedSeries(series, seriesIndices, realIndex) { 16299 var w = this.w; 16300 16301 if (series.length > 0) { 16302 for (var c = 0; c < series.length; c++) { 16303 if (series[c].index === realIndex) { 16304 if (w.globals.axisCharts) { 16305 w.config.series[realIndex].data = series[c].data.slice(); 16306 series.splice(c, 1); 16307 seriesIndices.splice(c, 1); 16308 w.globals.risingSeries.push(realIndex); 16309 } else { 16310 w.config.series[realIndex] = series[c].data; 16311 series.splice(c, 1); 16312 seriesIndices.splice(c, 1); 16313 w.globals.risingSeries.push(realIndex); 16314 } 16315 16316 this.ctx._updateSeries(w.config.series, w.config.chart.animations.dynamicAnimation.enabled); 16317 } 16318 } 16319 } 16320 } 16321 }]); 16322 16323 return Legend; 16324 }(); 16325 16326 /** 16327 * ApexCharts Responsive Class to override options for different screen sizes. 16328 * 16329 * @module Responsive 16330 **/ 16331 16332 var Responsive = 16333 /*#__PURE__*/ 16334 function () { 16335 function Responsive(ctx) { 16336 _classCallCheck(this, Responsive); 16337 16338 this.ctx = ctx; 16339 this.w = ctx.w; 16340 } // the opts parameter if not null has to be set overriding everything 16341 // as the opts is set by user externally 16342 16343 16344 _createClass(Responsive, [{ 16345 key: "checkResponsiveConfig", 16346 value: function checkResponsiveConfig(opts) { 16347 var _this = this; 16348 16349 var w = this.w; 16350 var cnf = w.config; // check if responsive config exists 16351 16352 if (cnf.responsive.length === 0) return; 16353 var res = cnf.responsive.slice(); 16354 res.sort(function (a, b) { 16355 return a.breakpoint > b.breakpoint ? 1 : b.breakpoint > a.breakpoint ? -1 : 0; 16356 }).reverse(); 16357 var config = new Config({}); 16358 16359 var iterateResponsiveOptions = function iterateResponsiveOptions() { 16360 var newOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 16361 var largestBreakpoint = res[0].breakpoint; 16362 var width = window.innerWidth > 0 ? window.innerWidth : screen.width; 16363 16364 if (width > largestBreakpoint) { 16365 var options = CoreUtils.extendArrayProps(config, w.globals.initialConfig); 16366 newOptions = Utils.extend(options, newOptions); 16367 newOptions = Utils.extend(w.config, newOptions); 16368 16369 _this.overrideResponsiveOptions(newOptions); 16370 } else { 16371 for (var i = 0; i < res.length; i++) { 16372 if (width < res[i].breakpoint) { 16373 newOptions = CoreUtils.extendArrayProps(config, res[i].options); 16374 newOptions = Utils.extend(w.config, newOptions); 16375 16376 _this.overrideResponsiveOptions(newOptions); 16377 } 16378 } 16379 } 16380 }; 16381 16382 if (opts) { 16383 var options = CoreUtils.extendArrayProps(config, opts); 16384 options = Utils.extend(w.config, options); 16385 options = Utils.extend(options, opts); 16386 iterateResponsiveOptions(options); 16387 } else { 16388 iterateResponsiveOptions({}); 16389 } 16390 } 16391 }, { 16392 key: "overrideResponsiveOptions", 16393 value: function overrideResponsiveOptions(newOptions) { 16394 var newConfig = new Config(newOptions).init(); 16395 this.w.config = newConfig; 16396 } 16397 }]); 16398 16399 return Responsive; 16400 }(); 16401 16402 /** 16403 * ApexCharts Theme Class for setting the colors and palettes. 16404 * 16405 * @module Theme 16406 **/ 16407 16408 var Theme = 16409 /*#__PURE__*/ 16410 function () { 16411 function Theme(ctx) { 16412 _classCallCheck(this, Theme); 16413 16414 this.ctx = ctx; 16415 this.w = ctx.w; 16416 this.colors = []; 16417 } 16418 16419 _createClass(Theme, [{ 16420 key: "init", 16421 value: function init() { 16422 this.setDefaultColors(); 16423 } 16424 }, { 16425 key: "setDefaultColors", 16426 value: function setDefaultColors() { 16427 var w = this.w; 16428 var utils = new Utils(); 16429 w.globals.dom.elWrap.classList.add(w.config.theme.mode); 16430 16431 if (w.config.colors === undefined) { 16432 w.globals.colors = this.predefined(); 16433 } else { 16434 w.globals.colors = w.config.colors; 16435 } 16436 16437 if (w.config.theme.monochrome.enabled) { 16438 var monoArr = []; 16439 var glsCnt = w.globals.series.length; 16440 16441 if (w.config.plotOptions.bar.distributed && w.config.chart.type === 'bar') { 16442 glsCnt = w.globals.series[0].length * w.globals.series.length; 16443 } 16444 16445 var mainColor = w.config.theme.monochrome.color; 16446 var part = 1 / (glsCnt / w.config.theme.monochrome.shadeIntensity); 16447 var shade = w.config.theme.monochrome.shadeTo; 16448 var percent = 0; 16449 16450 for (var gsl = 0; gsl < glsCnt; gsl++) { 16451 var newColor = void 0; 16452 16453 if (shade === 'dark') { 16454 newColor = utils.shadeColor(percent * -1, mainColor); 16455 percent = percent + part; 16456 } else { 16457 newColor = utils.shadeColor(percent, mainColor); 16458 percent = percent + part; 16459 } 16460 16461 monoArr.push(newColor); 16462 } 16463 16464 w.globals.colors = monoArr.slice(); 16465 } 16466 16467 var defaultColors = w.globals.colors.slice(); // if user specfied less colors than no. of series, push the same colors again 16468 16469 this.pushExtraColors(w.globals.colors); // The Border colors 16470 16471 if (w.config.stroke.colors === undefined) { 16472 w.globals.stroke.colors = defaultColors; 16473 } else { 16474 w.globals.stroke.colors = w.config.stroke.colors; 16475 } 16476 16477 this.pushExtraColors(w.globals.stroke.colors); // The FILL colors 16478 16479 if (w.config.fill.colors === undefined) { 16480 w.globals.fill.colors = defaultColors; 16481 } else { 16482 w.globals.fill.colors = w.config.fill.colors; 16483 } 16484 16485 this.pushExtraColors(w.globals.fill.colors); 16486 16487 if (w.config.dataLabels.style.colors === undefined) { 16488 w.globals.dataLabels.style.colors = defaultColors; 16489 } else { 16490 w.globals.dataLabels.style.colors = w.config.dataLabels.style.colors; 16491 } 16492 16493 this.pushExtraColors(w.globals.dataLabels.style.colors, 50); 16494 16495 if (w.config.plotOptions.radar.polygons.fill.colors === undefined) { 16496 w.globals.radarPolygons.fill.colors = [w.config.theme.mode === 'dark' ? '#202D48' : '#fff']; 16497 } else { 16498 w.globals.radarPolygons.fill.colors = w.config.plotOptions.radar.polygons.fill.colors; 16499 } 16500 16501 this.pushExtraColors(w.globals.radarPolygons.fill.colors, 20); // The point colors 16502 16503 if (w.config.markers.colors === undefined) { 16504 w.globals.markers.colors = defaultColors; 16505 } else { 16506 w.globals.markers.colors = w.config.markers.colors; 16507 } 16508 16509 this.pushExtraColors(w.globals.markers.colors); 16510 } // When the number of colors provided is less than the number of series, this method 16511 // will push same colors to the list 16512 // params: 16513 // distributed is only valid for distributed column/bar charts 16514 16515 }, { 16516 key: "pushExtraColors", 16517 value: function pushExtraColors(colorSeries, length) { 16518 var distributed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 16519 var w = this.w; 16520 var len = length || w.globals.series.length; 16521 16522 if (distributed === null) { 16523 distributed = w.config.chart.type === 'bar' && w.config.plotOptions.bar.distributed || w.config.chart.type === 'heatmap' && w.config.plotOptions.heatmap.colorScale.inverse; 16524 } 16525 16526 if (distributed) { 16527 len = w.globals.series[0].length * w.globals.series.length; 16528 } 16529 16530 if (colorSeries.length < len) { 16531 var diff = len - colorSeries.length; 16532 16533 for (var i = 0; i < diff; i++) { 16534 colorSeries.push(colorSeries[i]); 16535 } 16536 } 16537 } 16538 }, { 16539 key: "updateThemeOptions", 16540 value: function updateThemeOptions(options) { 16541 options.chart = options.chart || {}; 16542 options.tooltip = options.tooltip || {}; 16543 var mode = options.theme.mode || 'light'; 16544 var palette = options.theme.palette ? options.theme.palette : mode === 'dark' ? 'palette4' : 'palette1'; 16545 var foreColor = options.chart.foreColor ? options.chart.foreColor : mode === 'dark' ? '#f6f7f8' : '#373d3f'; 16546 options.tooltip.theme = mode; 16547 options.chart.foreColor = foreColor; 16548 options.theme.palette = palette; 16549 return options; 16550 } 16551 }, { 16552 key: "predefined", 16553 value: function predefined() { 16554 var palette = this.w.config.theme.palette; // D6E3F8, FCEFEF, DCE0D9, A5978B, EDDDD4, D6E3F8, FEF5EF 16555 16556 switch (palette) { 16557 case 'palette1': 16558 this.colors = ['#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0']; 16559 break; 16560 16561 case 'palette2': 16562 this.colors = ['#3f51b5', '#03a9f4', '#4caf50', '#f9ce1d', '#FF9800']; 16563 break; 16564 16565 case 'palette3': 16566 this.colors = ['#33b2df', '#546E7A', '#d4526e', '#13d8aa', '#A5978B']; 16567 break; 16568 16569 case 'palette4': 16570 this.colors = ['#4ecdc4', '#c7f464', '#81D4FA', '#fd6a6a', '#546E7A']; 16571 break; 16572 16573 case 'palette5': 16574 this.colors = ['#2b908f', '#f9a3a4', '#90ee7e', '#fa4443', '#69d2e7']; 16575 break; 16576 16577 case 'palette6': 16578 this.colors = ['#449DD1', '#F86624', '#EA3546', '#662E9B', '#C5D86D']; 16579 break; 16580 16581 case 'palette7': 16582 this.colors = ['#D7263D', '#1B998B', '#2E294E', '#F46036', '#E2C044']; 16583 break; 16584 16585 case 'palette8': 16586 this.colors = ['#662E9B', '#F86624', '#F9C80E', '#EA3546', '#43BCCD']; 16587 break; 16588 16589 case 'palette9': 16590 this.colors = ['#5C4742', '#A5978B', '#8D5B4C', '#5A2A27', '#C4BBAF']; 16591 break; 16592 16593 case 'palette10': 16594 this.colors = ['#A300D6', '#7D02EB', '#5653FE', '#2983FF', '#00B1F2']; 16595 break; 16596 16597 default: 16598 this.colors = ['#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0']; 16599 break; 16600 } 16601 16602 return this.colors; 16603 } 16604 }]); 16605 16606 return Theme; 16607 }(); 16608 16609 var Utils$1 = 16610 /*#__PURE__*/ 16611 function () { 16612 function Utils(tooltipContext) { 16613 _classCallCheck(this, Utils); 16614 16615 this.w = tooltipContext.w; 16616 this.ttCtx = tooltipContext; 16617 this.ctx = tooltipContext.ctx; 16618 } 16619 /** 16620 ** When hovering over series, you need to capture which series is being hovered on. 16621 ** This function will return both capturedseries index as well as inner index of that series 16622 * @memberof Utils 16623 * @param {object} 16624 * - hoverArea = the rect on which user hovers 16625 * - elGrid = dimensions of the hover rect (it can be different than hoverarea) 16626 */ 16627 16628 16629 _createClass(Utils, [{ 16630 key: "getNearestValues", 16631 value: function getNearestValues(_ref) { 16632 var hoverArea = _ref.hoverArea, 16633 elGrid = _ref.elGrid, 16634 clientX = _ref.clientX, 16635 clientY = _ref.clientY, 16636 hasBars = _ref.hasBars; 16637 var w = this.w; 16638 var hoverWidth = w.globals.gridWidth; 16639 var xDivisor = hoverWidth / (w.globals.dataPoints - 1); 16640 var seriesBound = elGrid.getBoundingClientRect(); 16641 16642 if (hasBars && w.globals.comboCharts || hasBars) { 16643 xDivisor = hoverWidth / w.globals.dataPoints; 16644 } 16645 16646 var hoverX = clientX - seriesBound.left; 16647 var hoverY = clientY - seriesBound.top; 16648 var inRect = hoverX < 0 || hoverY < 0 || hoverX > w.globals.gridWidth || hoverY > w.globals.gridHeight; 16649 16650 if (inRect) { 16651 hoverArea.classList.remove('hovering-zoom'); 16652 hoverArea.classList.remove('hovering-pan'); 16653 } else { 16654 if (w.globals.zoomEnabled) { 16655 hoverArea.classList.remove('hovering-pan'); 16656 hoverArea.classList.add('hovering-zoom'); 16657 } else if (w.globals.panEnabled) { 16658 hoverArea.classList.remove('hovering-zoom'); 16659 hoverArea.classList.add('hovering-pan'); 16660 } 16661 } 16662 16663 var j = Math.round(hoverX / xDivisor); 16664 16665 if (hasBars) { 16666 j = Math.ceil(hoverX / xDivisor); 16667 j = j - 1; 16668 } 16669 16670 var capturedSeries = null; 16671 var closest = null; 16672 var seriesXValArr = []; 16673 var seriesYValArr = []; 16674 16675 for (var s = 0; s < w.globals.seriesXvalues.length; s++) { 16676 seriesXValArr.push([w.globals.seriesXvalues[s][0] - 0.000001].concat(w.globals.seriesXvalues[s])
16676); 16677 } 16678 16679 seriesXValArr = seriesXValArr.map(function (seriesXVal) { 16680 return seriesXVal.filter(function (s) { 16681 return s; 16682 }); 16683 }); 16684 seriesYValArr = w.globals.seriesYvalues.map(function (seriesYVal) { 16685 return seriesYVal.filter(function (s) { 16686 return s; 16687 }); 16688 }); // if X axis type is not category and tooltip is not shared, then we need to find the cursor position and get the nearest value 16689 16690 if (w.globals.isXNumeric) { 16691 closest = this.closestInMultiArray(hoverX, hoverY, seriesXValArr, seriesYValArr); 16692 capturedSeries = closest.index; 16693 j = closest.j; 16694 16695 if (capturedSeries !== null) { 16696 // initial push, it should be a little smaller than the 1st val 16697 seriesXValArr = w.globals.seriesXvalues[capturedSeries]; 16698 closest = this.closestInArray(hoverX, seriesXValArr); 16699 j = closest.index; 16700 } 16701 } 16702 16703 if (!j || j < 1) j = 0; 16704 return { 16705 capturedSeries: capturedSeries, 16706 j: j, 16707 hoverX: hoverX, 16708 hoverY: hoverY 16709 }; 16710 } 16711 }, { 16712 key: "closestInMultiArray", 16713 value: function closestInMultiArray(hoverX, hoverY, Xarrays, Yarrays) { 16714 var w = this.w; 16715 var activeIndex = 0; 16716 var currIndex = null; 16717 var j = -1; 16718 16719 if (w.globals.series.length > 1) { 16720 activeIndex = this.getFirstActiveXArray(Xarrays); 16721 } else { 16722 currIndex = 0; 16723 } 16724 16725 var currY = Yarrays[activeIndex][0]; 16726 var currX = Xarrays[activeIndex][0]; 16727 var diffX = Math.abs(hoverX - currX); 16728 var diffY = Math.abs(hoverY - currY); 16729 var diff = diffY + diffX; 16730 Yarrays.map(function (arrY, arrIndex) { 16731 arrY.map(function (y, innerKey) { 16732 var newdiffY = Math.abs(hoverY - Yarrays[arrIndex][innerKey]); 16733 var newdiffX = Math.abs(hoverX - Xarrays[arrIndex][innerKey]); 16734 var newdiff = newdiffX + newdiffY; 16735 16736 if (newdiff < diff) { 16737 diff = newdiff; 16738 diffX = newdiffX; 16739 diffY = newdiffY; 16740 currIndex = arrIndex; 16741 j = innerKey; 16742 } 16743 }); 16744 }); 16745 return { 16746 index: currIndex, 16747 j: j 16748 }; 16749 } 16750 }, { 16751 key: "getFirstActiveXArray", 16752 value: function getFirstActiveXArray(Xarrays) { 16753 var activeIndex = 0; 16754 var coreUtils = new CoreUtils(this.ctx); 16755 var firstActiveSeriesIndex = Xarrays.map(function (xarr, index) { 16756 if (xarr.length > 0) { 16757 return index; 16758 } else { 16759 return -1; 16760 } 16761 }); 16762 16763 for (var a = 0; a < firstActiveSeriesIndex.length; a++) { 16764 var total = coreUtils.getSeriesTotalByIndex(a); 16765 16766 if (firstActiveSeriesIndex[a] !== -1 && total !== 0 && !coreUtils.seriesHaveSameValues(a)) { 16767 activeIndex = firstActiveSeriesIndex[a]; 16768 break; 16769 } 16770 } 16771 16772 return activeIndex; 16773 } 16774 }, { 16775 key: "closestInArray", 16776 value: function closestInArray(val, arr) { 16777 var curr = arr[0]; 16778 var currIndex = null; 16779 var diff = Math.abs(val - curr); 16780 16781 for (var i = 0; i < arr.length; i++) { 16782 var newdiff = Math.abs(val - arr[i]); 16783 16784 if (newdiff < diff) { 16785 diff = newdiff; 16786 curr = arr[i]; 16787 currIndex = i; 16788 } 16789 } 16790 16791 return { 16792 index: currIndex 16793 }; 16794 } 16795 /** 16796 * When there are multiple series, it is possible to have different x values for each series. 16797 * But it may be possible in those multiple series, that there is same x value for 2 or more 16798 * series. 16799 * @memberof Utils 16800 * @param {int} 16801 * - j = is the inner index of series -> (series[i][j]) 16802 * @return {bool} 16803 */ 16804 16805 }, { 16806 key: "isXoverlap", 16807 value: function isXoverlap(j) { 16808 var w = this.w; 16809 var xSameForAllSeriesJArr = []; 16810 var seriesX = w.globals.seriesX.filter(function (s) { 16811 return typeof s[0] !== 'undefined'; 16812 }); 16813 16814 if (seriesX.length > 0) { 16815 for (var i = 0; i < seriesX.length - 1; i++) { 16816 if (typeof seriesX[i][j] !== 'undefined' && typeof seriesX[i + 1][j] !== 'undefined') { 16817 if (seriesX[i][j] !== seriesX[i + 1][j]) { 16818 xSameForAllSeriesJArr.push('unEqual'); 16819 } 16820 } 16821 } 16822 } 16823 16824 if (xSameForAllSeriesJArr.length === 0) { 16825 return true; 16826 } 16827 16828 return false; 16829 } 16830 }, { 16831 key: "isinitialSeriesSameLen", 16832 value: function isinitialSeriesSameLen() { 16833 var sameLen = true; 16834 var initialSeries = this.w.globals.initialSeries; 16835 16836 for (var i = 0; i < initialSeries.length - 1; i++) { 16837 if (initialSeries[i].data.length !== initialSeries[i + 1].data.length) { 16838 sameLen = false; 16839 break; 16840 } 16841 } 16842 16843 return sameLen; 16844 } 16845 }, { 16846 key: "getBarsHeight", 16847 value: function getBarsHeight(allbars) { 16848 var bars = _toConsumableArray(allbars); 16849 16850 var totalHeight = bars.reduce(function (acc, bar) { 16851 return acc + bar.getBBox().height; 16852 }, 0); 16853 return totalHeight; 16854 } 16855 }, { 16856 key: "toggleAllTooltipSeriesGroups", 16857 value: function toggleAllTooltipSeriesGroups(state) { 16858 var w = this.w; 16859 var ttCtx = this.ttCtx; 16860 16861 if (ttCtx.allTooltipSeriesGroups.length === 0) { 16862 ttCtx.allTooltipSeriesGroups = w.globals.dom.baseEl.querySelectorAll('.apexcharts-tooltip-series-group'); 16863 } 16864 16865 var allTooltipSeriesGroups = ttCtx.allTooltipSeriesGroups; 16866 16867 for (var i = 0; i < allTooltipSeriesGroups.length; i++) { 16868 if (state === 'enable') { 16869 allTooltipSeriesGroups[i].classList.add('active'); 16870 allTooltipSeriesGroups[i].style.display = w.config.tooltip.items.display; 16871 } else { 16872 allTooltipSeriesGroups[i].classList.remove('active'); 16873 allTooltipSeriesGroups[i].style.display = 'none'; 16874 } 16875 } 16876 } 16877 }]); 16878 16879 return Utils; 16880 }(); 16881 16882 /** 16883 * ApexCharts Tooltip.Labels Class to draw texts on the tooltip. 16884 * 16885 * @module Tooltip.Labels 16886 **/ 16887 16888 var Labels = 16889 /*#__PURE__*/ 16890 function () { 16891 function Labels(tooltipContext) { 16892 _classCallCheck(this, Labels); 16893 16894 this.w = tooltipContext.w; 16895 this.ctx = tooltipContext.ctx; 16896 this.ttCtx = tooltipContext; 16897 this.tooltipUtil = new Utils$1(tooltipContext); 16898 } 16899 16900 _createClass(Labels, [{ 16901 key: "drawSeriesTexts", 16902 value: function drawSeriesTexts(_ref) { 16903 var _ref$shared = _ref.shared, 16904 shared = _ref$shared === void 0 ? true : _ref$shared, 16905 ttItems = _ref.ttItems, 16906 _ref$i = _ref.i, 16907 i = _ref$i === void 0 ? 0 : _ref$i, 16908 _ref$j = _ref.j, 16909 j = _ref$j === void 0 ? null : _ref$j; 16910 var w = this.w; 16911 16912 if (w.config.tooltip.custom !== undefined) { 16913 this.handleCustomTooltip({ 16914 i: i, 16915 j: j 16916 }); 16917 } else { 16918 this.toggleActiveInactiveSeries(shared); 16919 } 16920 16921 var values = this.getValuesToPrint({ 16922 i: i, 16923 j: j 16924 }); 16925 this.printLabels({ 16926 i: i, 16927 j: j, 16928 values: values, 16929 ttItems: ttItems, 16930 shared: shared 16931 }); // Re-calculate tooltip dimensions now that we have drawn the text 16932 16933 var tooltipEl = this.ttCtx.getElTooltip(); 16934 this.ttCtx.tooltipRect.ttWidth = tooltipEl.getBoundingClientRect().width; 16935 this.ttCtx.tooltipRect.ttHeight = tooltipEl.getBoundingClientRect().height; 16936 } 16937 }, { 16938 key: "printLabels", 16939 value: function printLabels(_ref2) { 16940 var i = _ref2.i, 16941 j = _ref2.j, 16942 values = _ref2.values, 16943 ttItems = _ref2.ttItems, 16944 shared = _ref2.shared; 16945 var w = this.w; 16946 var val; 16947 var xVal = values.xVal, 16948 zVal = values.zVal, 16949 xAxisTTVal = values.xAxisTTVal; 16950 var seriesName = ''; 16951 var pColor = w.globals.colors[i]; 16952 16953 if (j !== null && w.config.plotOptions.bar.distributed) { 16954 pColor = w.globals.colors[j]; 16955 } 16956 16957 for (var t = 0, inverset = w.globals.series.length - 1; t < w.globals.series.length; t++, inverset--) { 16958 var f = this.getFormatters(i);
16959 seriesName = this.getSeriesName({ 16960 fn: f.yLbTitleFormatter, 16961 index: i, 16962 seriesIndex: i, 16963 j: j 16964 }); 16965 16966 if (shared) { 16967 var tIndex = w.config.tooltip.inverseOrder ? inverset : t; 16968 f = this.getFormatters(tIndex); 16969 seriesName = this.getSeriesName({ 16970 fn: f.yLbTitleFormatter, 16971 index: tIndex, 16972 seriesIndex: i, 16973 j: j 16974 }); 16975 pColor = w.globals.colors[tIndex]; // for plot charts, not for pie/donuts 16976 16977 val = f.yLbFormatter(w.globals.series[tIndex][j], { 16978 series: w.globals.series, 16979 seriesIndex: tIndex, 16980 dataPointIndex: j, 16981 w: w 16982 }); // discard 0 values in BARS 16983 16984 if (this.ttCtx.hasBars() && w.config.chart.stacked && w.globals.series[tIndex][j] === 0 || typeof w.globals.series[tIndex][j] === 'undefined') { 16985 val = undefined; 16986 } 16987 } else { 16988 val = f.yLbFormatter(w.globals.series[i][j], { 16989 series: w.globals.series, 16990 seriesIndex: i, 16991 dataPointIndex: j, 16992 w: w 16993 }); 16994 } // for pie / donuts 16995 16996 16997 if (j === null) { 16998 val = f.yLbFormatter(w.globals.series[i], w); 16999 } 17000 17001 this.DOMHandling({ 17002 t: t, 17003 ttItems: ttItems, 17004 values: { 17005 val: val, 17006 xVal: xVal, 17007 xAxisTTVal: xAxisTTVal, 17008 zVal: zVal 17009 }, 17010 seriesName: seriesName, 17011 shared: shared, 17012 pColor: pColor 17013 }); 17014 } 17015 } 17016 }, { 17017 key: "getFormatters", 17018 value: function getFormatters(i) { 17019 var w = this.w; 17020 var yLbFormatter = w.globals.yLabelFormatters[i]; 17021 var yLbTitleFormatter; 17022 17023 if (w.globals.ttVal !== undefined) { 17024 if (Array.isArray(w.globals.ttVal)) { 17025 yLbFormatter = w.globals.ttVal[i] && w.globals.ttVal[i].formatter; 17026 yLbTitleFormatter = w.globals.ttVal[i] && w.globals.ttVal[i].title && w.globals.ttVal[i].title.formatter; 17027 } else { 17028 yLbFormatter = w.globals.ttVal.formatter; 17029 17030 if (typeof w.globals.ttVal.title.formatter === 'function') { 17031 yLbTitleFormatter = w.globals.ttVal.title.formatter; 17032 } 17033 } 17034 } else { 17035 yLbTitleFormatter = w.config.tooltip.y.title.formatter; 17036 } 17037 17038 if (typeof yLbFormatter !== 'function') { 17039 if (w.globals.yLabelFormatters[0]) { 17040 yLbFormatter = w.globals.yLabelFormatters[0]; 17041 } else { 17042 yLbFormatter = function yLbFormatter(label) { 17043 return label; 17044 }; 17045 } 17046 } 17047 17048 if (typeof yLbTitleFormatter !== 'function') { 17049 yLbTitleFormatter = function yLbTitleFormatter(label) { 17050 return label; 17051 }; 17052 } 17053 17054 return { 17055 yLbFormatter: yLbFormatter, 17056 yLbTitleFormatter: yLbTitleFormatter 17057 }; 17058 } 17059 }, { 17060 key: "getSeriesName", 17061 value: function getSeriesName(_ref3) { 17062 var fn = _ref3.fn, 17063 index = _ref3.index, 17064 seriesIndex = _ref3.seriesIndex, 17065 j = _ref3.j; 17066 var w = this.w; 17067 return fn(String(w.globals.seriesNames[index]), { 17068 series: w.globals.series, 17069 seriesIndex: seriesIndex, 17070 dataPointIndex: j, 17071 w: w 17072 }); 17073 } 17074 }, { 17075 key: "DOMHandling", 17076 value: function DOMHandling(_ref4) { 17077 var t = _ref4.t, 17078 ttItems = _ref4.ttItems, 17079 values = _ref4.values, 17080 seriesName = _ref4.seriesName, 17081 shared = _ref4.shared, 17082 pColor = _ref4.pColor; 17083 var w = this.w; 17084 var ttCtx = this.ttCtx; 17085 var val = values.val, 17086 xVal = values.xVal, 17087 xAxisTTVal = values.xAxisTTVal, 17088 zVal = values.zVal; 17089 var ttItemsChildren = null; 17090 ttItemsChildren = ttItems[t].children; 17091 17092 if (w.config.tooltip.fillSeriesColor) { 17093 // elTooltip.style.backgroundColor = pColor 17094 ttItems[t].style.backgroundColor = pColor; 17095 ttItemsChildren[0].style.display = 'none'; 17096 } 17097 17098 if (ttCtx.showTooltipTitle) { 17099 if (ttCtx.tooltipTitle === null) { 17100 // get it once if null, and store it in class property 17101 ttCtx.tooltipTitle = w.globals.dom.baseEl.querySelector('.apexcharts-tooltip-title'); 17102 } 17103 17104 ttCtx.tooltipTitle.innerHTML = xVal; 17105 } // if xaxis tooltip is constructed, we need to replace the innerHTML 17106 17107 17108 if (ttCtx.blxaxisTooltip) { 17109 ttCtx.xaxisTooltipText.innerHTML = xAxisTTVal !== '' ? xAxisTTVal : xVal; 17110 } 17111 17112 var ttYLabel = ttItems[t].querySelector('.apexcharts-tooltip-text-label'); 17113 17114 if (ttYLabel) { 17115 ttYLabel.innerHTML = seriesName ? seriesName + ': ' : ''; 17116 } 17117 17118 var ttYVal = ttItems[t].querySelector('.apexcharts-tooltip-text-value'); 17119 17120 if (ttYVal) { 17121 ttYVal.innerHTML = val; 17122 } 17123 17124 if (ttItemsChildren[0] && ttItemsChildren[0].classList.contains('apexcharts-tooltip-marker')) { 17125 ttItemsChildren[0].style.backgroundColor = pColor; 17126 } 17127 17128 if (!w.config.tooltip.marker.show) { 17129 ttItemsChildren[0].style.display = 'none'; 17130 } 17131 17132 if (zVal !== null) { 17133 var ttZLabel = ttItems[t].querySelector('.apexcharts-tooltip-text-z-label');
17134 ttZLabel.innerHTML = w.config.tooltip.z.title; 17135 var ttZVal = ttItems[t].querySelector('.apexcharts-tooltip-text-z-value'); 17136 ttZVal.innerHTML = zVal; 17137 } 17138 17139 if (shared && ttItemsChildren[0]) { 17140 // hide when no Val or series collapsed 17141 if (typeof val === 'undefined' || val === null || w.globals.collapsedSeriesIndices.indexOf(t) > -1) { 17142 ttItemsChildren[0].parentNode.style.display = 'none'; 17143 } else { 17144 ttItemsChildren[0].parentNode.style.display = w.config.tooltip.items.display; 17145 } 17146 } 17147 } 17148 }, { 17149 key: "toggleActiveInactiveSeries", 17150 value: function toggleActiveInactiveSeries(shared) { 17151 var w = this.w; 17152 17153 if (shared) { 17154 // make all tooltips active 17155 this.tooltipUtil.toggleAllTooltipSeriesGroups('enable'); 17156 } else { 17157 // disable all tooltip text groups 17158 this.tooltipUtil.toggleAllTooltipSeriesGroups('disable'); // enable the first tooltip text group 17159 17160 var firstTooltipSeriesGroup = w.globals.dom.baseEl.querySelector('.apexcharts-tooltip-series-group'); 17161 17162 if (firstTooltipSeriesGroup) { 17163 firstTooltipSeriesGroup.classList.add('active'); 17164 firstTooltipSeriesGroup.style.display = w.config.tooltip.items.display; 17165 } 17166 } 17167 } 17168 }, { 17169 key: "getValuesToPrint", 17170 value: function getValuesToPrint(_ref5) { 17171 var i = _ref5.i, 17172 j = _ref5.j; 17173 var w = this.w; 17174 var filteredSeriesX = this.ctx.series.filteredSeriesX(); 17175 var xVal = ''; 17176 var xAxisTTVal = ''; 17177 var zVal = null; 17178 var val = null; 17179 var customFormatterOpts = { 17180 series: w.globals.series, 17181 seriesIndex: i, 17182 dataPointIndex: j, 17183 w: w 17184 }; 17185 var zFormatter = w.globals.ttZFormatter; 17186 17187 if (j === null) { 17188 val = w.globals.series[i]; 17189 } else { 17190 if (w.globals.isXNumeric) { 17191 xVal = filteredSeriesX[i][j]; 17192 17193 if (filteredSeriesX[i].length === 0) { 17194 // a series (possibly the first one) might be collapsed, so get the next active index 17195 var firstActiveSeriesIndex = this.tooltipUtil.getFirstActiveXArray(filteredSeriesX); 17196 xVal = filteredSeriesX[firstActiveSeriesIndex][j]; 17197 } 17198 } else { 17199 xVal = typeof w.globals.labels[j] !== 'undefined' ? w.globals.labels[j] : ''; 17200 } 17201 } 17202 17203 var bufferXVal = xVal; 17204 17205 if (w.globals.isXNumeric && w.config.xaxis.type === 'datetime') { 17206 var xFormat = new Formatters(this.ctx); 17207 xVal = xFormat.xLabelFormat(w.globals.ttKeyFormatter, bufferXVal); 17208 } else { 17209 xVal = w.globals.xLabelFormatter(bufferXVal, customFormatterOpts); 17210 } // override default x-axis formatter with tooltip formatter 17211 17212 17213 if (w.config.tooltip.x.formatter !== undefined) { 17214 xVal = w.globals.ttKeyFormatter(bufferXVal, customFormatterOpts); 17215 } 17216 17217 if (w.globals.seriesZ.length > 0 && w.globals.seriesZ[0].length > 0) { 17218 zVal = zFormatter(w.globals.seriesZ[i][j], w); 17219 } 17220 17221 if (typeof w.config.xaxis.tooltip.formatter === 'function') { 17222 xAxisTTVal = w.globals.xaxisTooltipFormatter(bufferXVal, customFormatterOpts); 17223 } else { 17224 xAxisTTVal = xVal; 17225 } 17226 17227 return { 17228 val: val, 17229 xVal: xVal, 17230 xAxisTTVal: xAxisTTVal, 17231 zVal: zVal 17232 }; 17233 } 17234 }, { 17235 key: "handleCustomTooltip", 17236 value: function handleCustomTooltip(_ref6) { 17237 var i = _ref6.i, 17238 j = _ref6.j; 17239 var w = this.w; 17240 var tooltipEl = this.ttCtx.getElTooltip(); // override everything with a custom html tooltip and replace it 17241 17242 tooltipEl.innerHTML = w.config.tooltip.custom({ 17243 ctx: this.ctx, 17244 series: w.globals.series, 17245 seriesIndex: i, 17246 dataPointIndex: j, 17247 w: w 17248 }); 17249 } 17250 }]); 17251 17252 return Labels;
17253 }(); 17254 17255 /** 17256 * ApexCharts Tooltip.Position Class to move the tooltip based on x and y position. 17257 * 17258 * @module Tooltip.Position 17259 **/ 17260 17261 var Position = 17262 /*#__PURE__*/ 17263 function () { 17264 function Position(tooltipContext) { 17265 _classCallCheck(this, Position); 17266 17267 this.ttCtx = tooltipContext; 17268 this.ctx = tooltipContext.ctx; 17269 this.w = tooltipContext.w; 17270 } 17271 /** 17272 * This will move the crosshair (the vertical/horz line that moves along with mouse) 17273 * Along with this, this function also calls the xaxisMove function 17274 * @memberof Position 17275 * @param {int} - cx = point's x position, wherever point's x is, you need to move crosshair 17276 */ 17277 17278 17279 _createClass(Position, [{ 17280 key: "moveXCrosshairs", 17281 value: function moveXCrosshairs(cx) { 17282 var j = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 17283 var ttCtx = this.ttCtx; 17284 var w = this.w; 17285 var xcrosshairs = ttCtx.getElXCrosshairs(); 17286 var x = cx - ttCtx.xcrosshairsWidth / 2; 17287 var tickAmount = w.globals.labels.slice().length; 17288 17289 if (j !== null) { 17290 x = w.globals.gridWidth / tickAmount * j; 17291 } 17292 17293 if (w.config.xaxis.crosshairs.width === 'tickWidth' || w.config.xaxis.crosshairs.width === 'barWidth') { 17294 if (x + ttCtx.xcrosshairsWidth > w.globals.gridWidth) { 17295 x = w.globals.gridWidth - ttCtx.xcrosshairsWidth; 17296 } 17297 } else { 17298 if (j !== null) { 17299 x = x + w.globals.gridWidth / tickAmount / 2; 17300 } 17301 } 17302 17303 if (x < 0) { 17304 x = 0; 17305 } 17306 17307 if (x > w.globals.gridWidth) { 17308 x = w.globals.gridWidth; 17309 } 17310 17311 if (xcrosshairs !== null) { 17312 xcrosshairs.setAttribute('x', x); 17313 xcrosshairs.setAttribute('x1', x); 17314 xcrosshairs.setAttribute('x2', x); 17315 xcrosshairs.setAttribute('y2', w.globals.gridHeight); 17316 xcrosshairs.classList.add('active'); 17317 } 17318 17319 if (ttCtx.blxaxisTooltip) { 17320 var tx = x; 17321 17322 if (w.config.xaxis.crosshairs.width === 'tickWidth' || w.config.xaxis.crosshairs.width === 'barWidth') { 17323 tx = x + ttCtx.xcrosshairsWidth / 2; 17324 } 17325 17326 this.moveXAxisTooltip(tx); 17327 } 17328 } 17329 /** 17330 * This will move the crosshair (the vertical/horz line that moves along with mouse) 17331 * Along with this, this function also calls the xaxisMove function 17332 * @memberof Position 17333 * @param {int} - cx = point's x position, wherever point's x is, you need to move crosshair 17334 */ 17335 17336 }, { 17337 key: "moveYCrosshairs", 17338 value: function moveYCrosshairs(cy) { 17339 var ttCtx = this.ttCtx; 17340 17341 if (ttCtx.ycrosshairs !== null) { 17342 Graphics.setAttrs(ttCtx.ycrosshairs, { 17343 y1: cy, 17344 y2: cy 17345 }); 17346 Graphics.setAttrs(ttCtx.ycrosshairsHidden, { 17347 y1: cy, 17348 y2: cy 17349 }); 17350 } 17351 } 17352 /** 17353 ** AxisTooltip is the small rectangle which appears on x axis with x value, when user moves 17354 * @memberof Position 17355 * @param {int} - cx = point's x position, wherever point's x is, you need to move 17356 */ 17357 17358 }, { 17359 key: "moveXAxisTooltip", 17360 value: function moveXAxisTooltip(cx) { 17361 var w = this.w; 17362 var ttCtx = this.ttCtx; 17363 17364 if (ttCtx.xaxisTooltip !== null) { 17365 ttCtx.xaxisTooltip.classList.add('active'); 17366 var cy = ttCtx.xaxisOffY + w.config.xaxis.tooltip.offsetY + w.globals.translateY + 1 + w.config.xaxis.offsetY; 17367 var xaxisTTText = ttCtx.xaxisTooltip.getBoundingClientRect(); 17368 var xaxisTTTextWidth = xaxisTTText.width; 17369 cx = cx - xaxisTTTextWidth / 2; 17370 17371 if (!isNaN(cx)) { 17372 cx = cx + w.globals.translateX; 17373 var textRect = 0; 17374 var graphics = new Graphics(this.ctx); 17375 textRect = graphics.getTextRects(ttCtx.xaxisTooltipText.innerHTML); 17376 ttCtx.xaxisTooltipText.style.minWidth = textRect.width + 'px'; 17377 ttCtx.xaxisTooltip.style.left = cx + 'px'; 17378 ttCtx.xaxisTooltip.style.top = cy + 'px'; 17379 } 17380 } 17381 } 17382 }, { 17383 key: "moveYAxisTooltip", 17384 value: function moveYAxisTooltip(index) { 17385 var w = this.w; 17386 var ttCtx = this.ttCtx; 17387 17388 if (ttCtx.yaxisTTEls === null) { 17389 ttCtx.yaxisTTEls = w.globals.dom.baseEl.querySelectorAll('.apexcharts-yaxistooltip'); 17390 } 17391 17392 var ycrosshairsHiddenRectY1 = parseInt(ttCtx.ycrosshairsHidden.getAttribute('y1')); 17393 var cy = w.globals.translateY + ycrosshairsHiddenRectY1; 17394 var yAxisTTRect = ttCtx.yaxisTTEls[index].getBoundingClientRect(); 17395 var yAxisTTHeight = yAxisTTRect.height; 17396 var cx = w.globals.translateYAxisX[index] - 2; 17397 17398 if (w.config.yaxis[index].opposite) { 17399 cx = cx - 26; 17400 } 17401 17402 cy = cy - yAxisTTHeight / 2; 17403 17404 if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1) { 17405 ttCtx.yaxisTTEls[index].classList.add('active'); 17406 ttCtx.yaxisTTEls[index].style.top = cy + 'px'; 17407 ttCtx.yaxisTTEls[index].style.left = cx + w.config.yaxis[index].tooltip.offsetX + 'px'; 17408 } else { 17409 ttCtx.yaxisTTEls[index].classList.remove('active'); 17410 } 17411 } 17412 /** 17413 ** moves the whole tooltip by changing x, y attrs 17414 * @memberof Position 17415 * @param {int} - cx = point's x position, wherever point's x is, you need to move tooltip 17416 * @param {int} - cy = point's y position, wherever point's y is, you need to move tooltip 17417 * @param {int}
17417 - r = point's radius 17418 */ 17419 17420 }, { 17421 key: "moveTooltip", 17422 value: function moveTooltip(cx, cy) { 17423 var r = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 17424 var w = this.w; 17425 var ttCtx = this.ttCtx; 17426 var tooltipEl = ttCtx.getElTooltip(); 17427 var tooltipRect = ttCtx.tooltipRect; 17428 var pointR = r !== null ? parseInt(r) : 1; 17429 var x = parseInt(cx) + pointR + 5; 17430 var y = parseInt(cy) + pointR / 2; // - tooltipRect.ttHeight / 2 17431 17432 if (x > w.globals.gridWidth / 2) { 17433 x = x - tooltipRect.ttWidth - pointR - 15; 17434 } 17435 17436 if (x > w.globals.gridWidth - tooltipRect.ttWidth - 10) { 17437 x = w.globals.gridWidth - tooltipRect.ttWidth; 17438 } 17439 17440 if (x < -20) { 17441 x = -20; 17442 } 17443 17444 if (w.config.tooltip.followCursor) { 17445 var elGrid = ttCtx.getElGrid(); 17446 var seriesBound = elGrid.getBoundingClientRect(); 17447 y = ttCtx.e.clientY + w.globals.translateY - seriesBound.top - tooltipRect.ttHeight / 2; 17448 } 17449 17450 var newPositions = this.positionChecks(tooltipRect, x, y); 17451 x = newPositions.x; 17452 y = newPositions.y; 17453 17454 if (!isNaN(x)) { 17455 x = x + w.globals.translateX; 17456 tooltipEl.style.left = x + 'px'; 17457 tooltipEl.style.top = y + 'px'; 17458 } 17459 } 17460 }, { 17461 key: "positionChecks", 17462 value: function positionChecks(tooltipRect, x, y) { 17463 var w = this.w; 17464 17465 if (tooltipRect.ttHeight + y > w.globals.gridHeight) { 17466 y = w.globals.gridHeight - tooltipRect.ttHeight + w.globals.translateY; 17467 } 17468 17469 if (y < 0) { 17470 y = 0; 17471 } 17472 17473 return { 17474 x: x, 17475 y: y 17476 }; 17477 } 17478 }, { 17479 key: "moveMarkers", 17480 value: function moveMarkers(i, j) { 17481 var w = this.w; 17482 var ttCtx = this.ttCtx; 17483 17484 if (w.globals.markers.size[i] > 0) { 17485 var allPoints = w.globals.dom.baseEl.querySelectorAll(" .apexcharts-series[data\\:realIndex='".concat(i, "'] .apexcharts-marker")); 17486 17487 for (var p = 0; p < allPoints.length; p++) { 17488 if (parseInt(allPoints[p].getAttribute('rel')) === j) { 17489 ttCtx.marker.resetPointsSize(); 17490 ttCtx.marker.enlargeCurrentPoint(j, allPoints[p]); 17491 } 17492 } 17493 } else { 17494 ttCtx.marker.resetPointsSize(); 17495 this.moveDynamicPointOnHover(j, i); 17496 } 17497 } // This function is used when you need to show markers/points only on hover - 17498 // DIFFERENT X VALUES in multiple series 17499 17500 }, { 17501 key: "moveDynamicPointOnHover",
17502 value: function moveDynamicPointOnHover(j, capturedSeries) { 17503 var w = this.w; 17504 var ttCtx = this.ttCtx; 17505 var cx = 0; 17506 var cy = 0; 17507 var pointsArr = w.globals.pointsArray; 17508 var hoverSize = w.config.markers.hover.size; 17509 17510 if (hoverSize === undefined) { 17511 hoverSize = w.globals.markers.size[capturedSeries] + w.config.markers.hover.sizeOffset; 17512 } 17513 17514 cx = pointsArr[capturedSeries][j][0]; 17515 cy = pointsArr[capturedSeries][j][1] ? pointsArr[capturedSeries][j][1] : 0; 17516 var point = w.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(capturedSeries, "'] .apexcharts-series-markers circle")); 17517 17518 if (point) { 17519 point.setAttribute('r', hoverSize); 17520 point.setAttribute('cx', cx); 17521 point.setAttribute('cy', cy); 17522 } // point.style.opacity = w.config.markers.hover.opacity 17523 17524 17525 this.moveXCrosshairs(cx); 17526 17527 if (!ttCtx.fixedTooltip) { 17528 this.moveTooltip(cx, cy, hoverSize); 17529 } 17530 } // This function is used when you need to show markers/points only on hover - 17531 // SAME X VALUES in multiple series 17532 17533 }, { 17534 key: "moveDynamicPointsOnHover", 17535 value: function moveDynamicPointsOnHover(j) { 17536 var ttCtx = this.ttCtx; 17537 var w = ttCtx.w; 17538 var cx = 0; 17539 var cy = 0; 17540 var activeSeries = 0; 17541 var pointsArr = w.globals.pointsArray; 17542 var series = new Series(this.ctx); 17543 activeSeries = series.getActiveSeriesIndex(); 17544 var hoverSize = w.config.markers.hover.size; 17545 17546 if (hoverSize === undefined) { 17547 hoverSize = w.globals.markers.size[activeSeries] + w.config.markers.hover.sizeOffset; 17548 } 17549 17550 if (pointsArr[activeSeries]) { 17551 cx = pointsArr[activeSeries][j][0]; 17552 cy = pointsArr[activeSeries][j][1]; 17553 } 17554 17555 var points = null; 17556 var allPoints = ttCtx.getAllMarkers(); 17557 17558 if (allPoints !== null) { 17559 points = allPoints; 17560 } else { 17561 points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series-markers circle'); 17562 } 17563 17564 if (points !== null) { 17565 for (var p = 0; p < points.length; p++) { 17566 var pointArr = pointsArr[p]; 17567 17568 if (pointArr && pointArr.length) { 17569 var pcy = pointsArr[p][j][1]; 17570 points[p].setAttribute('cx', cx); 17571 var realIndex = parseInt(points[p].parentNode.parentNode.parentNode.getAttribute('data:realIndex')); 17572 17573 if (pcy !== null) { 17574 points[realIndex] && points[realIndex].setAttribute('r', hoverSize); 17575 points[realIndex] && points[realIndex].setAttribute('cy', pcy); 17576 } else { 17577 points[realIndex] && points[realIndex].setAttribute('r', 0); 17578 } 17579 } 17580 } 17581 } 17582 17583 this.moveXCrosshairs(cx); 17584 17585 if (!ttCtx.fixedTooltip) { 17586 var tcy = cy || w.globals.gridHeight; 17587 this.moveTooltip(cx, tcy, hoverSize); 17588 } 17589 } 17590 }, { 17591 key: "moveStickyTooltipOverBars", 17592 value: function moveStickyTooltipOverBars(j) { 17593 var w = this.w; 17594 var ttCtx = this.ttCtx; 17595 var jBar = w.globals.dom.baseEl.querySelector(".apexcharts-bar-series .apexcharts-series[rel='1'] path[j='".concat(j, "'], .apexcharts-candlestick-series .apexcharts-series[rel='1'] path[j='").concat(j, "'], .apexcharts-rangebar-series .apexcharts-series[rel='1'] path[j='").concat(j, "']")); 17596 var bcx = jBar ? parseFloat(jBar.getAttribute('cx')) : 0; 17597 var bcy = 0; 17598 var bw = jBar ? parseFloat(jBar.getAttribute('barWidth')) : 0; 17599 17600 if (w.globals.isXNumeric) { 17601 bcx = bcx - bw / 2; 17602 } else { 17603 bcx = ttCtx.xAxisTicksPositions[j - 1] + ttCtx.dataPointsDividedWidth / 2; 17604 17605 if (isNaN(bcx)) { 17606 bcx = ttCtx.xAxisTicksPositions[j] - ttCtx.dataPointsDividedWidth / 2; 17607 } 17608 } // tooltip will move vertically along with mouse as it is a shared tooltip 17609 17610 17611 var elGrid = ttCtx.getElGrid(); 17612 var seriesBound = elGrid.getBoundingClientRect(); 17613 bcy = ttCtx.e.clientY - seriesBound.top - ttCtx.tooltipRect.ttHeight / 2; 17614 this.moveXCrosshairs(bcx); 17615 17616 if (!ttCtx.fixedTooltip) { 17617 var tcy = bcy || w.globals.gridHeight; 17618 this.moveTooltip(bcx, tcy); 17619 } 17620 } 17621 }]); 17622 17623 return Position; 17624 }(); 17625 17626 /** 17627 * ApexCharts Tooltip.Marker Class to draw texts on the tooltip. 17628 * 17629 * @module Tooltip.Marker 17630 **/ 17631 17632 var Marker = 17633 /*#__PURE__*/ 17634 function () { 17635 function Marker(tooltipContext) { 17636 _classCallCheck(this, Marker); 17637 17638 this.w = tooltipContext.w; 17639 this.ttCtx = tooltipContext; 17640 this.ctx = tooltipContext.ctx; 17641 this.tooltipPosition = new Position(tooltipContext); 17642 } 17643 17644 _createClass(Marker, [{ 17645 key: "drawDynamicPoints", 17646 value: function drawDynamicPoints() { 17647 var w = this.w; 17648 var graphics = new Graphics(this.ctx); 17649 var marker = new Markers(this.ctx); 17650 var elsSeries = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series'); 17651 17652 for (var i = 0; i < elsSeries.length; i++) { 17653 var seriesIndex = parseInt(elsSeries[i].getAttribute('data:realIndex')); 17654 var pointsMain = w.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(seriesIndex, "'] .apexcharts-series-markers-wrap")); 17655 17656 if (pointsMain !== null) { 17657 // it can be null as we have tooltips in donut/bar charts 17658 var point = void 0; 17659 var PointClasses = "apexcharts-marker w".concat((Math.random() + 1).toString(36).substring(4)); 17660 17661 if ((w.config.chart.type === 'line' || w.config.chart.type === 'area') && !w.globals.comboCharts && !w.config.tooltip.intersect) { 17662 PointClasses += ' no-pointer-events'; 17663 } 17664 17665 var elPointOptions = marker.getMarkerConfig(PointClasses, seriesIndex); 17666 point = graphics.drawMarker(0, 0, elPointOptions); 17667 point.node.setAttribute('default-marker-size', 0); 17668 var elPointsG = document.createElementNS(w.globals.SVGNS, 'g'); 17669 elPointsG.classList.add('apexcharts-series-markers');
17670 elPointsG.appendChild(point.node); 17671 pointsMain.appendChild(elPointsG); 17672 } 17673 } 17674 } 17675 }, { 17676 key: "enlargeCurrentPoint", 17677 value: function enlargeCurrentPoint(rel, point) { 17678 var x = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 17679 var y = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 17680 var w = this.w; 17681 17682 if (w.config.chart.type !== 'bubble') { 17683 this.newPointSize(rel, point); 17684 } 17685 17686 var cx = point.getAttribute('cx'); 17687 var cy = point.getAttribute('cy'); 17688 17689 if (x !== null && y !== null) { 17690 cx = x; 17691 cy = y; 17692 } 17693 17694 this.tooltipPosition.moveXCrosshairs(cx); 17695 17696 if (!this.fixedTooltip) { 17697 if (w.config.chart.type === 'radar') { 17698 var elGrid = this.ttCtx.getElGrid(); 17699 var seriesBound = elGrid.getBoundingClientRect(); 17700 cx = this.ttCtx.e.clientX - seriesBound.left; 17701 } 17702 17703 this.tooltipPosition.moveTooltip(cx, cy, w.config.markers.hover.size); 17704 } 17705 } 17706 }, { 17707 key: "enlargePoints", 17708 value: function enlargePoints(j) { 17709 var w = this.w; 17710 var me = this; 17711 var ttCtx = this.ttCtx; 17712 var col = j; 17713 var points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker'); 17714 var newSize = w.config.markers.hover.size; 17715 17716 for (var p = 0; p < points.length; p++) { 17717 var rel = points[p].getAttribute('rel'); 17718 var index = points[p].getAttribute('index'); 17719 17720 if (newSize === undefined) { 17721 newSize = w.globals.markers.size[index] + w.config.markers.hover.sizeOffset; 17722 } 17723 17724 if (col === parseInt(rel)) { 17725 me.newPointSize(col, points[p]); 17726 var cx = points[p].getAttribute('cx'); 17727 var cy = points[p].getAttribute('cy'); 17728 me.tooltipPosition.moveXCrosshairs(cx); 17729 17730 if (!ttCtx.fixedTooltip) { 17731 me.tooltipPosition.moveTooltip(cx, cy, newSize); 17732 } 17733 } else { 17734 me.oldPointSize(points[p]); 17735 } 17736 } 17737 } 17738 }, { 17739 key: "newPointSize", 17740 value: function newPointSize(rel, point) { 17741 var w = this.w; 17742 var newSize = w.config.markers.hover.size; 17743 var elPoint = null; 17744 17745 if (rel === 0) { 17746 elPoint = point.parentNode.firstChild; 17747 } else { 17748 elPoint = point.parentNode.lastChild; 17749 } 17750 17751 var index = parseInt(elPoint.getAttribute('index')); 17752 17753 if (newSize === undefined) { 17754 newSize = w.globals.markers.size[index] + w.config.markers.hover.sizeOffset; 17755 } 17756 17757 elPoint.setAttribute('r', newSize); 17758 } 17759 }, { 17760 key: "oldPointSize", 17761 value: function oldPointSize(point) { 17762 var size = parseInt(point.getAttribute('default-marker-size')); 17763 point.setAttribute('r', size); 17764 } 17765 }, { 17766 key: "resetPointsSize", 17767 value: function resetPointsSize() { 17768 var w = this.w; 17769 var points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker'); 17770 17771 for (var p = 0; p < points.length; p++) { 17772 var size = parseInt(points[p].getAttribute('default-marker-size')); 17773 17774 if (Utils.isNumber(size)) { 17775 points[p].setAttribute('r', size); 17776 } else { 17777 points[p].setAttribute('r', 0); 17778 } 17779 } 17780 } 17781 }]); 17782 17783 return Marker; 17784 }(); 17785 17786 /** 17787 * ApexCharts Tooltip.Intersect Class. 17788 * 17789 * @module Tooltip.Intersect 17790 **/ 17791 17792 var Intersect = 17793 /*#__PURE__*/ 17794 function () { 17795 function Intersect(tooltipContext) { 17796 _classCallCheck(this, Intersect); 17797 17798 this.w = tooltipContext.w; 17799 this.ttCtx = tooltipContext; 17800 } 17801 17802 _createClass(Intersect, [{ 17803 key: "getAttr", 17804 value: function getAttr(e, attr) { 17805 return parseFloat(e.target.getAttribute(attr)); 17806 } 17807 }, { 17808 key: "handleHeatTooltip", 17809 value: function handleHeatTooltip(_ref) { 17810 var e = _ref.e, 17811 opt = _ref.opt, 17812 x = _ref.x, 17813 y = _ref.y; 17814 var ttCtx = this.ttCtx; 17815 var w = this.w; 17816 17817 if (e.target.classList.contains('apexcharts-heatmap-rect')) { 17818 var i = this.getAttr(e, 'i'); 17819 var j = this.getAttr(e, 'j'); 17820 var cx = this.getAttr(e, 'cx'); 17821 var cy = this.getAttr(e, 'cy'); 17822 var width = this.getAttr(e, 'width');
17823 var height = this.getAttr(e, 'height'); 17824 ttCtx.tooltipLabels.drawSeriesTexts({ 17825 ttItems: opt.ttItems, 17826 i: i, 17827 j: j, 17828 shared: false 17829 }); 17830 x = cx + ttCtx.tooltipRect.ttWidth / 2 + width; 17831 y = cy + ttCtx.tooltipRect.ttHeight / 2 - height / 2; 17832 ttCtx.tooltipPosition.moveXCrosshairs(cx + width / 2); 17833 17834 if (x > w.globals.gridWidth / 2) { 17835 x = cx - ttCtx.tooltipRect.ttWidth / 2 + width; 17836 } 17837 17838 if (ttCtx.w.config.tooltip.followCursor) { 17839 var elGrid = ttCtx.getElGrid(); 17840 var seriesBound = elGrid.getBoundingClientRect(); // x = ttCtx.e.clientX - seriesBound.left 17841 17842 y = ttCtx.e.clientY - seriesBound.top + w.globals.translateY / 2 - 10; 17843 } 17844 } 17845 17846 return { 17847 x: x, 17848 y: y 17849 }; 17850 } 17851 }, { 17852 key: "handleMarkerTooltip", 17853 value: function handleMarkerTooltip(_ref2) { 17854 var e = _ref2.e, 17855 opt = _ref2.opt, 17856 x = _ref2.x, 17857 y = _ref2.y; 17858 var w = this.w; 17859 var ttCtx = this.ttCtx; 17860 var i; 17861 var j; 17862 17863 if (e.target.classList.contains('apexcharts-marker')) { 17864 var cx = parseInt(opt.paths.getAttribute('cx')); 17865 var cy = parseInt(opt.paths.getAttribute('cy')); 17866 var val = parseFloat(opt.paths.getAttribute('val')); 17867 j = parseInt(opt.paths.getAttribute('rel')); 17868 i = parseInt(opt.paths.parentNode.parentNode.parentNode.getAttribute('rel')) - 1; 17869 17870 if (ttCtx.intersect) { 17871 var el = Utils.findAncestor(opt.paths, 'apexcharts-series'); 17872 17873 if (el) { 17874 i = parseInt(el.getAttribute('data:realIndex')); 17875 } 17876 } 17877 17878 ttCtx.tooltipLabels.drawSeriesTexts({ 17879 ttItems: opt.ttItems, 17880 i: i, 17881 j: j, 17882 shared: ttCtx.showOnIntersect ? false : w.config.tooltip.shared 17883 }); 17884 17885 if (e.type === 'mouseup') { 17886 ttCtx.markerClick(e, i, j); 17887 } 17888 17889 x = cx; 17890 y = cy + w.globals.translateY - ttCtx.tooltipRect.ttHeight * 1.4; 17891 17892 if (ttCtx.w.config.tooltip.followCursor) { 17893 var elGrid = ttCtx.getElGrid(); 17894 var seriesBound = elGrid.getBoundingClientRect(); 17895 y = ttCtx.e.clientY + w.globals.translateY - seriesBound.top; 17896 } 17897 17898 if (val < 0) { 17899 y = cy; 17900 } 17901 17902 ttCtx.marker.enlargeCurrentPoint(j, opt.paths, x, y); 17903 } 17904 17905 return { 17906 x: x, 17907 y: y 17908 }; 17909 } 17910 }, { 17911 key: "handleBarTooltip", 17912 value: function handleBarTooltip(_ref3) { 17913 var e = _ref3.e, 17914 opt = _ref3.opt; 17915 var w = this.w; 17916 var ttCtx = this.ttCtx; 17917 var tooltipEl = ttCtx.getElTooltip(); 17918 var bx = 0; 17919 var x = 0; 17920 var y = 0; // let bW = 0 17921 17922 var i = 0; 17923 var strokeWidth; 17924 var barXY = this.getBarTooltipXY({ 17925 e: e, 17926 opt: opt 17927 }); 17928 i = barXY.i; 17929 var barHeight = barXY.barHeight; 17930 var j = barXY.j; 17931 17932 if (w.globals.isBarHorizontal && ttCtx.hasBars() || !w.config.tooltip.shared) { 17933 x = barXY.x; 17934 y = barXY.y; 17935 strokeWidth = Array.isArray(w.config.stroke.width) ? w.config.stroke.width[i] : w.config.stroke.width; // bW = barXY.barWidth 17936 17937 bx = x; 17938 } else { 17939 if (!w.globals.comboCharts && !w.config.tooltip.shared) { 17940 bx = bx / 2; 17941 } 17942 } // y is NaN, make it touch the bottom of grid area 17943 17944 17945 if (isNaN(y)) { 17946 y = w.globals.svgHeight - ttCtx.tooltipRect.ttHeight; 17947 } // x exceeds gridWidth 17948 17949 17950 if (x + ttCtx.tooltipRect.ttWidth > w.globals.gridWidth) { 17951 x = x - ttCtx.tooltipRect.ttWidth; 17952 } else if (x < 0) { 17953 x = x + ttCtx.tooltipRect.ttWidth; 17954 } 17955 17956 if (ttCtx.w.config.tooltip.followCursor) { 17957 var elGrid = ttCtx.getElGrid(); 17958 var seriesBound = elGrid.getBoundingClientRect(); 17959 y = ttCtx.e.clientY - seriesBound.top; 17960 } // if tooltip is still null, querySelector 17961 17962 17963 if (ttCtx.tooltip === null) { 17964 ttCtx.tooltip = w.globals.dom.baseEl.querySelector('.apexcharts-tooltip'); 17965 } 17966 17967 if (!w.config.tooltip.shared) { 17968 if (w.globals.comboChartsHasBars) { 17969 ttCtx.tooltipPosition.moveXCrosshairs(bx + strokeWidth / 2); 17970 } else { 17971 ttCtx.tooltipPosition.moveXCrosshairs(bx); 17972 } 17973 } // move tooltip here 17974 17975 17976 if (!ttCtx.fixedTooltip && (!w.config.tooltip.shared || w.globals.isBarHorizontal && ttCtx.hasBars())) { 17977 if (isReversed) { 17978 x = w.globals.gridWidth - x; 17979 } 17980 17981 tooltipEl.style.left = x + w.globals.translateX + 'px'; 17982 var seriesIndex = parseInt(opt.paths.parentNode.getAttribute('data:realIndex')); 17983 var isReversed = w.globals.isMultipleYAxis ? w.config.yaxis[seriesIndex] && w.config.yaxis[seriesIndex].reversed : w.config.yaxis[0].reversed; 17984 17985 if (isReversed && !(w.globals.isBarHorizontal && ttCtx.hasBars())) { 17986 y = y + barHeight - (w.globals.series[i][j] < 0 ? barHeight : 0) * 2; 17987 } 17988 17989 if (ttCtx.tooltipRect.ttHeight + y > w.globals.gridHeight) { 17990 y = w.globals.gridHeight - ttCtx.tooltipRect.ttHeight + w.globals.translateY; 17991 tooltipEl.style.top = y + 'px'; 17992 } else { 17993 tooltipEl.style.top = y + w.globals.translateY - ttCtx.tooltipRect.ttHeight / 2 + 'px'; 17994 } 17995 } 17996 } 17997 }, { 17998 key: "getBarTooltipXY", 17999 value: function getBarTooltipXY(_ref4) { 18000 var e = _ref4.e, 18001 opt = _ref4.opt; 18002 var w = this.w; 18003 var j = null; 18004 var ttCtx = this.ttCtx; 18005 var i = 0; 18006 var x = 0; 18007 var y = 0; 18008 var barWidth = 0; 18009 var barHeight = 0; 18010 var cl = e.target.classList; 18011 18012 if (cl.contains('apexcharts-bar-area') || cl.contains('apexcharts-candlestick-area') || cl.contains('apexcharts-rangebar-area')) { 18013 var bar = e.target; 18014 var barRect = bar.getBoundingClientRect(); 18015 var seriesBound = opt.elGrid.getBoundingClientRect(); 18016 var bh = barRect.height; 18017 barHeight = barRect.height; 18018 var bw = barRect.width; 18019 var cx = parseInt(bar.getAttribute('cx')); 18020 var cy = parseInt(bar.getAttribute('cy')); 18021 barWidth = parseFloat(bar.getAttribute('barWidth')); 18022 var clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX; 18023 j = parseInt(bar.getAttribute('j')); 18024 i = parseInt(bar.parentNode.getAttribute('rel')) - 1; 18025 18026 if (w.globals.comboCharts) { 18027 i = parseInt(bar.parentNode.getAttribute('data:realIndex')); 18028 } // if (w.config.tooltip.shared) { 18029 // this check not needed at the moment 18030 // const yDivisor = w.globals.gridHeight / (w.globals.series.length) 18031 // const hoverY = ttCtx.clientY - ttCtx.seriesBound.top 18032 // j = Math.ceil(hoverY / yDivisor) 18033 // } 18034 18035 18036 ttCtx.tooltipLabels.drawSeriesTexts({ 18037 ttItems: opt.ttItems, 18038 i: i, 18039 j: j, 18040 shared: ttCtx.showOnIntersect ? false : w.config.tooltip.shared 18041 }); 18042 18043 if (w.config.tooltip.followCursor) { 18044 if (w.globals.isBarHorizontal) { 18045 x = clientX - seriesBound.left + 15; 18046 y = cy - ttCtx.dataPointsDividedHeight + bh / 2 - ttCtx.tooltipRect.ttHeight / 2; 18047 } else { 18048 if (w.globals.isXNumeric) { 18049 x = cx - bw / 2; 18050 } else { 18051 x = cx - ttCtx.dataPointsDividedWidth + bw / 2; 18052 } 18053 18054 y = e.clientY - seriesBound.top - ttCtx.tooltipRect.ttHeight / 2 - 15; 18055 } 18056 } else { 18057 if (w.globals.isBarHorizontal) { 18058 x = cx; 18059 18060 if (x < ttCtx.xyRatios.baseLineInvertedY) { 18061 x = cx - ttCtx.tooltipRect.ttWidth; 18062 } 18063 18064 y = cy - ttCtx.dataPointsDividedHeight + bh / 2 - ttCtx.tooltipRect.ttHeight / 2; 18065 } else { 18066 // if columns 18067 if (w.globals.isXNumeric) { 18068 x = cx - bw / 2; 18069 } else { 18070 x = cx - ttCtx.dataPointsDividedWidth + bw / 2; 18071 } 18072 18073 y = cy; // - ttCtx.tooltipRect.ttHeight / 2 + 10 18074 } 18075 } 18076 } 18077 18078 return { 18079 x: x, 18080 y: y, 18081 barHeight: barHeight, 18082 barWidth: barWidth, 18083 i: i, 18084 j: j 18085 }; 18086 } 18087 }]); 18088 18089 return Intersect; 18090 }(); 18091 18092 /** 18093 * ApexCharts Tooltip.AxesTooltip Class. 18094 * 18095 * @module Tooltip.AxesTooltip 18096 **/ 18097 var AxesTooltip = 18098 /*#__PURE__*/ 18099 function () { 18100 function AxesTooltip(tooltipContext) { 18101 _classCallCheck(this, AxesTooltip); 18102 18103 this.w = tooltipContext.w; 18104 this.ttCtx = tooltipContext; 18105 } 18106 /** 18107 * This method adds the secondary tooltip which appears below x axis 18108 * @memberof Tooltip 18109 **/ 18110 18111 18112 _createClass(AxesTooltip, [{ 18113 key: "drawXaxisTooltip", 18114 value: function drawXaxisTooltip() { 18115 var w = this.w; 18116 var ttCtx = this.ttCtx; 18117 var isBottom = w.config.xaxis.position === 'bottom'; 18118 ttCtx.xaxisOffY = isBottom ? w.globals.gridHeight + 1 : 1; 18119 var tooltipCssClass = isBottom ? 'apexcharts-xaxistooltip apexcharts-xaxistooltip-bottom' : 'apexcharts-xaxistooltip apexcharts-xaxistooltip-top'; 18120 var renderTo = w.globals.dom.elWrap; 18121 18122 if (ttCtx.blxaxisTooltip) { 18123 var xaxisTooltip = w.globals.dom.baseEl.querySelector('.apexcharts-xaxistooltip'); 18124 18125 if (xaxisTooltip === null) { 18126 ttCtx.xaxisTooltip = document.createElement('div'); 18127 ttCtx.xaxisTooltip.setAttribute('class', tooltipCssClass + ' ' + w.config.tooltip.theme); 18128 renderTo.appendChild(ttCtx.xaxisTooltip); 18129 ttCtx.xaxisTooltipText = document.createElement('div'); 18130 ttCtx.xaxisTooltipText.classList.add('apexcharts-xaxistooltip-text'); 18131 ttCtx.xaxisTooltipText.style.fontFamily = w.config.xaxis.tooltip.style.fontFamily || w.config.chart.fontFamily; 18132 ttCtx.xaxisTooltipText.style.fontSize = w.config.xaxis.tooltip.style.fontSize; 18133 ttCtx.xaxisTooltip.appendChild(ttCtx.xaxisTooltipText); 18134 } 18135 } 18136 } 18137 /** 18138 * This method adds the secondary tooltip which appears below x axis 18139 * @memberof Tooltip 18140 **/ 18141 18142 }, { 18143 key: "drawYaxisTooltip", 18144 value: function drawYaxisTooltip() { 18145 var w = this.w; 18146 var ttCtx = this.ttCtx; 18147 18148 for (var i = 0; i < w.config.yaxis.length; i++) { 18149 var isRight = w.config.yaxis[i].opposite || w.config.yaxis[i].crosshairs.opposite; 18150 ttCtx.yaxisOffX = isRight ? w.globals.gridWidth + 1 : 1; 18151 var tooltipCssClass = isRight ? "apexcharts-yaxistooltip apexcharts-yaxistooltip-".concat(i, " apexcharts-yaxistooltip-right") : "apexcharts-yaxistooltip apexcharts-yaxistooltip-".concat(i, " apexcharts-yaxistooltip-left"); 18152 var renderTo = w.globals.dom.elWrap; 18153 18154 if (ttCtx.blyaxisTooltip) { 18155 var yaxisTooltip = w.globals.dom.baseEl.querySelector(".apexcharts-yaxistooltip apexcharts-yaxistooltip-".concat(i)); 18156 18157 if (yaxisTooltip === null) { 18158 ttCtx.yaxisTooltip = document.createElement('div'); 18159 ttCtx.yaxisTooltip.setAttribute('class', tooltipCssClass + ' ' + w.config.tooltip.theme); 18160 renderTo.appendChild(ttCtx.yaxisTooltip); 18161 if (i === 0) ttCtx.yaxisTooltipText = []; 18162 ttCtx.yaxisTooltipText.push(document.createElement('div')); 18163 ttCtx.yaxisTooltipText[i].classList.add('apexcharts-yaxistooltip-text'); 18164 ttCtx.yaxisTooltip.appendChild(ttCtx.yaxisTooltipText[i]); 18165 } 18166 } 18167 } 18168 } 18169 /** 18170 * @memberof Tooltip 18171 **/ 18172 18173 }, { 18174 key: "setXCrosshairWidth", 18175 value: function setXCrosshairWidth() { 18176 var w = this.w; 18177 var ttCtx = this.ttCtx; // set xcrosshairs width 18178 18179 var xcrosshairs = ttCtx.getElXCrosshairs(); 18180 ttCtx.xcrosshairsWidth = parseInt(w.config.xaxis.crosshairs.width); 18181 18182 if (!w.globals.comboCharts) { 18183 if (w.config.xaxis.crosshairs.width === 'tickWidth') { 18184 var count = w.globals.labels.length; 18185 ttCtx.xcrosshairsWidth = w.globals.gridWidth / count; 18186 } else if (w.config.xaxis.crosshairs.width === 'barWidth') { 18187 var bar = w.globals.dom.baseEl.querySelector('.apexcharts-bar-area'); 18188 18189 if (bar !== null) { 18190 var barWidth = parseFloat(bar.getAttribute('barWidth')); 18191 ttCtx.xcrosshairsWidth = barWidth; 18192 } else { 18193 ttCtx.xcrosshairsWidth = 1; 18194 } 18195 } 18196 } else { 18197 var _bar = w.globals.dom.baseEl.querySelector('.apexcharts-bar-area'); 18198 18199 if (_bar !== null && w.config.xaxis.crosshairs.width === 'barWidth') { 18200 var _barWidth = parseFloat(_bar.getAttribute('barWidth')); 18201 18202 ttCtx.xcrosshairsWidth = _barWidth; 18203 } else { 18204 if (w.config.xaxis.crosshairs.width === 'tickWidth') { 18205 var _count = w.globals.labels.length; 18206 ttCtx.xcrosshairsWidth = w.globals.gridWidth / _count; 18207 } 18208 } 18209 } 18210 18211 if (w.globals.isBarHorizontal) { 18212 ttCtx.xcrosshairsWidth = 0; 18213 } 18214 18215 if (xcrosshairs !== null && ttCtx.xcrosshairsWidth > 0) { 18216 xcrosshairs.setAttribute('width', ttCtx.xcrosshairsWidth); 18217 } 18218 } 18219 }, { 18220 key: "handleYCrosshair",
18221 value: function handleYCrosshair() { 18222 var w = this.w; 18223 var ttCtx = this.ttCtx; // set ycrosshairs height 18224 18225 ttCtx.ycrosshairs = w.globals.dom.baseEl.querySelector('.apexcharts-ycrosshairs'); 18226 ttCtx.ycrosshairsHidden = w.globals.dom.baseEl.querySelector('.apexcharts-ycrosshairs-hidden'); 18227 } 18228 }, { 18229 key: "drawYaxisTooltipText", 18230 value: function drawYaxisTooltipText(index, clientY, xyRatios) { 18231 var ttCtx = this.ttCtx; 18232 var w = this.w; 18233 var lbFormatter = w.globals.yLabelFormatters[index]; 18234 18235 if (ttCtx.blyaxisTooltip) { 18236 var elGrid = ttCtx.getElGrid(); 18237 var seriesBound = elGrid.getBoundingClientRect(); 18238 var hoverY = (clientY - seriesBound.top) * xyRatios.yRatio[index]; 18239 var height = w.globals.maxYArr[index] - w.globals.minYArr[index]; 18240 var val = w.globals.minYArr[index] + (height - hoverY); 18241 ttCtx.tooltipPosition.moveYCrosshairs(clientY - seriesBound.top); 18242 ttCtx.yaxisTooltipText[index].innerHTML = lbFormatter(val); 18243 ttCtx.tooltipPosition.moveYAxisTooltip(index); 18244 } 18245 } 18246 }]); 18247 18248 return AxesTooltip; 18249 }(); 18250 18251 /** 18252 * ApexCharts Core Tooltip Class to handle the tooltip generation. 18253 * 18254 * @module Tooltip 18255 **/ 18256 18257 var Tooltip = 18258 /*#__PURE__*/ 18259 function () { 18260 function Tooltip(ctx) { 18261 _classCallCheck(this, Tooltip); 18262 18263 this.ctx = ctx; 18264 this.w = ctx.w; 18265 var w = this.w; 18266 this.tConfig = w.config.tooltip; 18267 this.tooltipUtil = new Utils$1(this); 18268 this.tooltipLabels = new Labels(this); 18269 this.tooltipPosition = new Position(this); 18270 this.marker = new Marker(this); 18271 this.intersect = new Intersect(this); 18272 this.axesTooltip = new AxesTooltip(this); 18273 this.showOnIntersect = this.tConfig.intersect; 18274 this.showTooltipTitle = this.tConfig.x.show; 18275 this.fixedTooltip = this.tConfig.fixed.enabled; 18276 this.xaxisTooltip = null; 18277 this.yaxisTTEls = null; 18278 this.isBarShared = !w.globals.isBarHorizontal && this.tConfig.shared; 18279 } 18280 18281 _createClass(Tooltip, [{ 18282 key: "getElTooltip", 18283 value: function getElTooltip(ctx) { 18284 if (!ctx) ctx = this; 18285 return ctx.w.globals.dom.baseEl.querySelector('.apexcharts-tooltip'); 18286 } 18287 }, { 18288 key: "getElXCrosshairs", 18289 value: function getElXCrosshairs() { 18290 return this.w.globals.dom.baseEl.querySelector('.apexcharts-xcrosshairs'); 18291 } 18292 }, { 18293 key: "getElGrid", 18294 value: function getElGrid() { 18295 return this.w.globals.dom.baseEl.querySelector('.apexcharts-grid'); 18296 } 18297 }, { 18298 key: "drawTooltip", 18299 value: function drawTooltip(xyRatios) { 18300 var w = this.w; 18301 this.xyRatios = xyRatios; 18302 this.blxaxisTooltip = w.config.xaxis.tooltip.enabled && w.globals.axisCharts; 18303 this.blyaxisTooltip = w.config.yaxis[0].tooltip.enabled && w.globals.axisCharts; 18304 this.allTooltipSeriesGroups = []; 18305 18306 if (!w.globals.axisCharts) { 18307 this.showTooltipTitle = false; 18308 } 18309 18310 var tooltipEl = document.createElement('div'); 18311 tooltipEl.classList.add('apexcharts-tooltip'); 18312 tooltipEl.classList.add(this.tConfig.theme); 18313 w.globals.dom.elWrap.appendChild(tooltipEl); 18314 18315 if (w.globals.axisCharts) { 18316 this.axesTooltip.drawXaxisTooltip(); 18317 this.axesTooltip.drawYaxisTooltip(); 18318 this.axesTooltip.setXCrosshairWidth(); 18319 this.axesTooltip.handleYCrosshair(); 18320 var xAxis = new XAxis(this.ctx); 18321 this.xAxisTicksPositions = xAxis.getXAxisTicksPositions(); 18322 } // we forcefully set intersect true for these conditions 18323 18324 18325 if (w.globals.comboCharts && !this.tConfig.shared || this.tConfig.intersect && !this.tConfig.shared || (w.config.chart.type === 'bar' || w.config.chart.type === 'rangeBar') && !this.tConfig.shared) { 18326 this.showOnIntersect = true; 18327 } 18328 18329 if (w.config.markers.size === 0 || w.globals.markers.largestSize === 0) { 18330 // when user don't want to show points all the time, but only on when hovering on series 18331 this.marker.drawDynamicPoints(this); 18332 } // no visible series, exit 18333 18334 18335 if (w.globals.collapsedSeries.length === w.globals.series.length) return; 18336 this.dataPointsDividedHeight = w.globals.gridHeight / w.globals.dataPoints; 18337 this.dataPointsDividedWidth = w.globals.gridWidth / w.globals.dataPoints; 18338 18339 if (this.showTooltipTitle) { 18340 this.tooltipTitle = document.createElement('div'); 18341 this.tooltipTitle.classList.add('apexcharts-tooltip-title'); 18342 this.tooltipTitle.style.fontFamily = this.tConfig.style.fontFamily || w.config.chart.fontFamily; 18343 this.tooltipTitle.style.fontSize = this.tConfig.style.fontSize; 18344 tooltipEl.appendChild(this.tooltipTitle); 18345 } 18346 18347 var ttItemsCnt = w.globals.series.length; // whether shared or not, default is shared 18348
18349 if ((w.globals.xyCharts || w.globals.comboCharts) && this.tConfig.shared) { 18350 if (!this.showOnIntersect) { 18351 ttItemsCnt = w.globals.series.length; 18352 } else { 18353 ttItemsCnt = 1; 18354 } 18355 } 18356 18357 this.ttItems = this.createTTElements(ttItemsCnt); 18358 this.addSVGEvents(); 18359 } 18360 }, { 18361 key: "createTTElements", 18362 value: function createTTElements(ttItemsCnt) { 18363 var w = this.w; 18364 var ttItems = []; 18365 var tooltipEl = this.getElTooltip(); 18366 18367 for (var i = 0; i < ttItemsCnt; i++) { 18368 var gTxt = document.createElement('div'); 18369 gTxt.classList.add('apexcharts-tooltip-series-group'); 18370 18371 if (this.tConfig.shared && this.tConfig.enabledOnSeries && Array.isArray(this.tConfig.enabledOnSeries)) { 18372 if (this.tConfig.enabledOnSeries.indexOf(i) < 0) { 18373 gTxt.classList.add('apexcharts-tooltip-series-group-hidden'); 18374 } 18375 } 18376 18377 var point = document.createElement('span'); 18378 point.classList.add('apexcharts-tooltip-marker'); 18379 point.style.backgroundColor = w.globals.colors[i]; 18380 gTxt.appendChild(point); 18381 var gYZ = document.createElement('div'); 18382 gYZ.classList.add('apexcharts-tooltip-text'); 18383 gYZ.style.fontFamily = this.tConfig.style.fontFamily || w.config.chart.fontFamily; 18384 gYZ.style.fontSize = this.tConfig.style.fontSize; // y values group 18385 18386 var gYValText = document.createElement('div'); 18387 gYValText.classList.add('apexcharts-tooltip-y-group'); 18388 var txtLabel = document.createElement('span'); 18389 txtLabel.classList.add('apexcharts-tooltip-text-label'); 18390 gYValText.appendChild(txtLabel); 18391 var txtValue = document.createElement('span'); 18392 txtValue.classList.add('apexcharts-tooltip-text-value'); 18393 gYValText.appendChild(txtValue); // z values group 18394 18395 var gZValText = document.createElement('div'); 18396 gZValText.classList.add('apexcharts-tooltip-z-group'); 18397 var txtZLabel = document.createElement('span'); 18398 txtZLabel.classList.add('apexcharts-tooltip-text-z-label'); 18399 gZValText.appendChild(txtZLabel); 18400 var txtZValue = document.createElement('span'); 18401 txtZValue.classList.add('apexcharts-tooltip-text-z-value'); 18402 gZValText.appendChild(txtZValue); 18403 gYZ.appendChild(gYValText); 18404 gYZ.appendChild(gZValText); 18405 gTxt.appendChild(gYZ); 18406 tooltipEl.appendChild(gTxt); 18407 ttItems.push(gTxt); 18408 } 18409 18410 return ttItems; 18411 } 18412 }, { 18413 key: "addSVGEvents", 18414 value: function addSVGEvents() { 18415 var w = this.w; 18416 var type = w.config.chart.type; 18417 var tooltipEl = this.getElTooltip(); 18418 var commonBar = !!(type === 'bar' || type === 'candlestick' || type === 'rangeBar'); 18419 var hoverArea = w.globals.dom.Paper.node; 18420 var elGrid = this.getElGrid(); 18421 18422 if (elGrid) { 18423 this.seriesBound = elGrid.getBoundingClientRect(); 18424 } 18425 18426 var tooltipY = []; 18427 var tooltipX = []; 18428 var seriesHoverParams = { 18429 hoverArea: hoverArea, 18430 elGrid: elGrid, 18431 tooltipEl: tooltipEl, 18432 tooltipY: tooltipY, 18433 tooltipX: tooltipX, 18434 ttItems: this.ttItems 18435 }; 18436 var points; 18437 18438 if (w.globals.axisCharts) { 18439 if (type === 'area' || type === 'line' || type === 'scatter' || type === 'bubble') { 18440 points = w.globals.dom.baseEl.querySelectorAll(".apexcharts-series[data\\:longestSeries='true'] .apexcharts-marker"); 18441 } else if (commonBar) { 18442 points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series .apexcharts-bar-area, .apexcharts-series .apexcharts-candlestick-area, .apexcharts-series .apexcharts-rangebar-area'); 18443 } else if (type === 'heatmap') { 18444 points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series .apexcharts-heatmap'); 18445 } else if (type === 'radar') { 18446 points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series .apexcharts-marker'); 18447 } 18448 18449 if (points && points.length) { 18450 for (var p = 0; p < points.length; p++) { 18451 tooltipY.push(points[p].getAttribute('cy')); 18452 tooltipX.push(points[p].getAttribute('cx')); 18453 } 18454 } 18455 } 18456
18457 var validSharedChartTypes = w.globals.xyCharts && !this.showOnIntersect || w.globals.comboCharts && !this.showOnIntersect || commonBar && this.hasBars() && this.tConfig.shared; 18458 18459 if (validSharedChartTypes) { 18460 this.addPathsEventListeners([hoverArea], seriesHoverParams); 18461 } else if (commonBar && !w.globals.comboCharts) { 18462 this.addBarsEventListeners(seriesHoverParams); 18463 } else if (type === 'bubble' || type === 'scatter' || type === 'radar' || this.showOnIntersect && (type === 'area' || type === 'line')) { 18464 this.addPointsEventsListeners(seriesHoverParams); 18465 } else if (!w.globals.axisCharts || type === 'heatmap') { 18466 var seriesAll = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series'); 18467 this.addPathsEventListeners(seriesAll, seriesHoverParams); 18468 } 18469 18470 if (this.showOnIntersect) { 18471 var linePoints = w.globals.dom.baseEl.querySelectorAll('.apexcharts-line-series .apexcharts-marker'); 18472 18473 if (linePoints.length > 0) { 18474 // if we find any lineSeries, addEventListeners for them 18475 this.addPathsEventListeners(linePoints, seriesHoverParams); 18476 } 18477 18478 var areaPoints = w.globals.dom.baseEl.querySelectorAll('.apexcharts-area-series .apexcharts-marker'); 18479 18480 if (areaPoints.length > 0) { 18481 // if we find any areaSeries, addEventListeners for them 18482 this.addPathsEventListeners(areaPoints, seriesHoverParams); 18483 } // combo charts may have bars, so add event listeners here too 18484 18485 18486 if (this.hasBars() && !this.tConfig.shared) { 18487 this.addBarsEventListeners(seriesHoverParams); 18488 } 18489 } 18490 } 18491 }, { 18492 key: "drawFixedTooltipRect", 18493 value: function drawFixedTooltipRect() { 18494 var w = this.w; 18495 var tooltipEl = this.getElTooltip(); 18496 var tooltipRect = tooltipEl.getBoundingClientRect(); 18497 var ttWidth = tooltipRect.width + 10; 18498 var ttHeight = tooltipRect.height + 10; 18499 var x = this.tConfig.fixed.offsetX; 18500 var y = this.tConfig.fixed.offsetY; 18501 18502 if (this.tConfig.fixed.position.toLowerCase().indexOf('right') > -1) { 18503 x = x + w.globals.svgWidth - ttWidth + 10; 18504 } 18505 18506 if (this.tConfig.fixed.position.toLowerCase().indexOf('bottom') > -1) { 18507 y = y + w.globals.svgHeight - ttHeight - 10; 18508 } 18509 18510 tooltipEl.style.left = x + 'px'; 18511 tooltipEl.style.top = y + 'px'; 18512 return { 18513 x: x, 18514 y: y, 18515 ttWidth: ttWidth, 18516 ttHeight: ttHeight 18517 }; 18518 } 18519 }, { 18520 key: "addPointsEventsListeners", 18521 value: function addPointsEventsListeners(seriesHoverParams) { 18522 var w = this.w; 18523 var points = w.globals.dom.baseEl.querySelectorAll('.apexcharts-series-markers .apexcharts-marker'); 18524 this.addPathsEventListeners(points, seriesHoverParams); 18525 } 18526 }, { 18527 key: "addBarsEventListeners", 18528 value: function addBarsEventListeners(seriesHoverParams) { 18529 var w = this.w; 18530 var bars = w.globals.dom.baseEl.querySelectorAll('.apexcharts-bar-area, .apexcharts-candlestick-area, .apexcharts-rangebar-area'); 18531 this.addPathsEventListeners(bars, seriesHoverParams); 18532 } 18533 }, { 18534 key: "addPathsEventListeners", 18535 value: function addPathsEventListeners(paths, opts) { 18536 var _this = this; 18537 18538 var self = this; 18539 18540 var _loop = function _loop(p) { 18541 var extendedOpts = { 18542 paths: paths[p], 18543 tooltipEl: opts.tooltipEl, 18544 tooltipY: opts.tooltipY, 18545 tooltipX: opts.tooltipX, 18546 elGrid: opts.elGrid, 18547 hoverArea: opts.hoverArea, 18548 ttItems: opts.ttItems 18549 }; 18550 _this.w.globals.tooltipOpts = extendedOpts; 18551 var events = ['mousemove', 'mouseup', 'touchmove', 'mouseout', 'touchend']; 18552 events.map(function (ev) { 18553 return paths[p].addEventListener(ev, self.seriesHover.bind(self, extendedOpts), { 18554 capture: false, 18555 passive: true 18556 }); 18557 }); 18558 }; 18559 18560 for (var p = 0; p < paths.length; p++) { 18561 _loop(p); 18562 } 18563 } 18564 /* 18565 ** The actual series hover function 18566 */ 18567 18568 }, { 18569 key: "seriesHover", 18570 value: function seriesHover(opt, e) { 18571 var _this2 = this; 18572 18573 var chartGroups = []; 18574 var w = this.w; // if user has more than one charts in group, we need to sync 18575 18576 if (w.config.chart.group) { 18577 chartGroups = this.ctx.getGroupedCharts(); 18578 } 18579 18580 if (w.globals.axisCharts && (w.globals.minX === -Infinity && w.globals.maxX === Infinity || w.globals.dataPoints === 0)) { 18581 return; 18582 } 18583 18584 if (chartGroups.length) { 18585 chartGroups.forEach(function (ch) { 18586 var tooltipEl = _this2.getElTooltip(ch); 18587 18588 var newOpts = { 18589 paths: opt.paths, 18590 tooltipEl: tooltipEl, 18591 tooltipY: opt.tooltipY, 18592 tooltipX: opt.tooltipX, 18593 elGrid: opt.elGrid, 18594 hoverArea: opt.hoverArea, 18595 ttItems: ch.w.globals.tooltip.ttItems // all the charts should have the same minX and maxX (same xaxis) for multiple tooltips to work correctly 18596 18597 }; 18598 18599 if (ch.w.globals.minX === _this2.w.globals.minX && ch.w.globals.maxX === _this2.w.globals.maxX) { 18600 ch.w.globals.tooltip.seriesHoverByContext({ 18601 chartCtx: ch, 18602 ttCtx: ch.w.globals.tooltip, 18603 opt: newOpts, 18604 e: e 18605 }); 18606 } 18607 }); 18608 } else { 18609 this.seriesHoverByContext({ 18610 chartCtx: this.ctx, 18611 ttCtx: this.w.globals.tooltip, 18612 opt: opt, 18613 e: e 18614 }); 18615 } 18616 } 18617 }, { 18618 key: "seriesHoverByContext", 18619 value: function seriesHoverByContext(_ref) { 18620 var chartCtx = _ref.chartCtx, 18621 ttCtx = _ref.ttCtx, 18622 opt = _ref.opt, 18623 e = _ref.e; 18624 var w = chartCtx.w; 18625 var tooltipEl = this.getElTooltip(); // tooltipRect is calculated on every mousemove, because the text is dynamic 18626 18627 ttCtx.tooltipRect = { 18628 x: 0, 18629 y: 0, 18630 ttWidth: tooltipEl.getBoundingClientRect().width, 18631 ttHeight: tooltipEl.getBoundingClientRect().height 18632 }; 18633 ttCtx.e = e; // highlight the current hovered bars 18634 18635 if (ttCtx.hasBars() && !w.globals.comboCharts && !ttCtx.isBarShared) {
18636 if (this.tConfig.onDatasetHover.highlightDataSeries) { 18637 var series = new Series(chartCtx); 18638 series.toggleSeriesOnHover(e, e.target.parentNode); 18639 } 18640 } 18641 18642 if (ttCtx.fixedTooltip) { 18643 ttCtx.drawFixedTooltipRect(); 18644 } 18645 18646 if (w.globals.axisCharts) { 18647 ttCtx.axisChartsTooltips({ 18648 e: e, 18649 opt: opt, 18650 tooltipRect: ttCtx.tooltipRect 18651 }); 18652 } else { 18653 // non-plot charts i.e pie/donut/circle 18654 ttCtx.nonAxisChartsTooltips({ 18655 e: e, 18656 opt: opt, 18657 tooltipRect: ttCtx.tooltipRect 18658 }); 18659 } 18660 } // tooltip handling for line/area/bar/columns/scatter 18661 18662 }, { 18663 key: "axisChartsTooltips", 18664 value: function axisChartsTooltips(_ref2) { 18665 var e = _ref2.e, 18666 opt = _ref2.opt; 18667 var w = this.w; 18668 var j, x, y; 18669 var self = this; 18670 var capj = null; 18671 var seriesBound = opt.elGrid.getBoundingClientRect(); 18672 var clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX; 18673 var clientY = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY; 18674 this.clientY = clientY; 18675 this.clientX = clientX; 18676 18677 if (clientY < seriesBound.top || clientY > seriesBound.top + seriesBound.height) { 18678 self.handleMouseOut(opt); 18679 return; 18680 } 18681 18682 if (Array.isArray(this.tConfig.enabledOnSeries)) { 18683 var index = parseInt(opt.paths.getAttribute('index')); 18684 18685 if (this.tConfig.enabledOnSeries.indexOf(index) < 0) { 18686 self.handleMouseOut(opt); 18687 return; 18688 } 18689 } 18690 18691 var tooltipEl = this.getElTooltip(); 18692 var xcrosshairs = this.getElXCrosshairs(); 18693 var isStickyTooltip = w.globals.xyCharts || w.config.chart.type === 'bar' && !w.globals.isBarHorizontal && this.hasBars() && this.tConfig.shared || w.globals.comboCharts && this.hasBars; 18694 18695 if (w.globals.isBarHorizontal && this.hasBars()) { 18696 isStickyTooltip = false; 18697 } 18698 18699 if (e.type === 'mousemove' || e.type === 'touchmove' || e.type === 'mouseup') { 18700 if (xcrosshairs !== null) { 18701 xcrosshairs.classList.add('active'); 18702 } 18703 18704 if (self.ycrosshairs !== null && self.blyaxisTooltip) { 18705 self.ycrosshairs.classList.add('active'); 18706 } 18707 18708 if (isStickyTooltip && !self.showOnIntersect) { 18709 capj = self.tooltipUtil.getNearestValues({ 18710 context: self, 18711 hoverArea: opt.hoverArea, 18712 elGrid: opt.elGrid, 18713 clientX: clientX, 18714 clientY: clientY, 18715 hasBars: self.hasBars 18716 }); 18717 j = capj.j; 18718 var capturedSeries = capj.capturedSeries; 18719 18720 if (capj.hoverX < 0 || capj.hoverX > w.globals.gridWidth) { 18721 self.handleMouseOut(opt); 18722 return; 18723 } 18724 18725 if (capturedSeries !== null) { 18726 var ignoreNull = w.globals.series[capturedSeries][j] === null; 18727 18728 if (ignoreNull) { 18729 opt.tooltipEl.classList.remove('active'); 18730 return; 18731 } 18732 18733 if (typeof w.globals.series[capturedSeries][j] !== 'undefined') { 18734 if (this.tConfig.shared && this.tooltipUtil.isXoverlap(j) && this.tooltipUtil.isinitialSeriesSameLen()) { 18735 this.create(e, self, capturedSeries, j, opt.ttItems); 18736 } else { 18737 this.create(e, self, capturedSeries, j, opt.ttItems, false); 18738 } 18739 } else { 18740 if (this.tooltipUtil.isXoverlap(j)) { 18741 self.create(e, self, 0, j, opt.ttItems); 18742 } 18743 } 18744 } else { 18745 // couldn't capture any series. check if shared X is same, 18746 // if yes, draw a grouped tooltip 18747 if (this.tooltipUtil.isXoverlap(j)) {
18748 self.create(e, self, 0, j, opt.ttItems); 18749 } 18750 } 18751 } else { 18752 if (w.config.chart.type === 'heatmap') { 18753 var markerXY = this.intersect.handleHeatTooltip({ 18754 e: e, 18755 opt: opt, 18756 x: x, 18757 y: y 18758 }); 18759 x = markerXY.x; 18760 y = markerXY.y; 18761 tooltipEl.style.left = x + 'px'; 18762 tooltipEl.style.top = y + 'px'; 18763 } else { 18764 if (this.hasBars) { 18765 this.intersect.handleBarTooltip({ 18766 e: e, 18767 opt: opt 18768 }); 18769 } 18770 18771 if (this.hasMarkers) { 18772 // intersect - line/area/scatter/bubble 18773 this.intersect.handleMarkerTooltip({ 18774 e: e, 18775 opt: opt, 18776 x: x, 18777 y: y 18778 }); 18779 } 18780 } 18781 } 18782 18783 if (this.blyaxisTooltip) { 18784 for (var yt = 0; yt < w.config.yaxis.length; yt++) { 18785 self.axesTooltip.drawYaxisTooltipText(yt, clientY, self.xyRatios); 18786 } 18787 } 18788 18789 opt.tooltipEl.classList.add('active'); 18790 } else if (e.type === 'mouseout' || e.type === 'touchend') { 18791 this.handleMouseOut(opt); 18792 } 18793 } // tooltip handling for pie/donuts 18794 18795 }, { 18796 key: "nonAxisChartsTooltips", 18797 value: function nonAxisChartsTooltips(_ref3) { 18798 var e = _ref3.e, 18799 opt = _ref3.opt, 18800 tooltipRect = _ref3.tooltipRect; 18801 var w = this.w; 18802 var rel = opt.paths.getAttribute('rel'); 18803 var tooltipEl = this.getElTooltip(); 18804 var seriesBound = w.globals.dom.elWrap.getBoundingClientRect(); 18805 18806 if (e.type === 'mousemove' || e.type === 'touchmove') { 18807 tooltipEl.classList.add('active'); 18808 this.tooltipLabels.drawSeriesTexts({ 18809 ttItems: opt.ttItems, 18810 i: parseInt(rel) - 1, 18811 shared: false 18812 }); 18813 var x = w.globals.clientX - seriesBound.left - tooltipRect.ttWidth / 2; 18814 var y = w.globals.clientY - seriesBound.top - tooltipRect.ttHeight - 10; 18815 tooltipEl.style.left = x + 'px'; 18816 tooltipEl.style.top = y + 'px'; 18817 } else if (e.type === 'mouseout' || e.type === 'touchend') { 18818 tooltipEl.classList.remove('active'); 18819 } 18820 } 18821 }, { 18822 key: "deactivateHoverFilter", 18823 value: function deactivateHoverFilter() { 18824 var w = this.w; 18825 var graphics = new Graphics(this.ctx); 18826 var allPaths = w.globals.dom.Paper.select(".apexcharts-bar-area"); 18827 18828 for (var b = 0; b < allPaths.length; b++) { 18829 graphics.pathMouseLeave(allPaths[b]); 18830 } 18831 } 18832 }, { 18833 key: "handleMouseOut", 18834 value: function handleMouseOut(opt) { 18835 var w = this.w; 18836 var xcrosshairs = this.getElXCrosshairs(); 18837 opt.tooltipEl.classList.remove('active'); 18838 this.deactivateHoverFilter(); 18839 18840 if (w.config.chart.type !== 'bubble') { 18841 this.marker.resetPointsSize(); 18842 } 18843 18844 if (xcrosshairs !== null) { 18845 xcrosshairs.classList.remove('active'); 18846 } 18847 18848 if (this.ycrosshairs !== null) { 18849 this.ycrosshairs.classList.remove('active'); 18850 } 18851 18852 if (this.blxaxisTooltip) { 18853 this.xaxisTooltip.classList.remove('active'); 18854 } 18855 18856 if (this.blyaxisTooltip) { 18857 if (this.yaxisTTEls === null) { 18858 this.yaxisTTEls = w.globals.dom.baseEl.querySelectorAll('.apexcharts-yaxistooltip'); 18859 } 18860 18861 for (var i = 0; i < this.yaxisTTEls.length; i++) { 18862 this.yaxisTTEls[i].classList.remove('active'); 18863 } 18864 } 18865 } 18866 }, { 18867 key: "getElMarkers", 18868 value: function getElMarkers() { 18869 return this.w.globals.dom.baseEl.querySelectorAll(' .apexcharts-series-markers'); 18870 } 18871 }, { 18872 key: "getAllMarkers", 18873 value: function getAllMarkers() { 18874 return this.w.globals.dom.baseEl.querySelectorAll('.apexcharts-series-markers .apexcharts-marker'); 18875 } 18876 }, { 18877 key: "hasMarkers", 18878 value: function hasMarkers() { 18879 var markers = this.getElMarkers(); 18880 return markers.length > 0;
18881 } 18882 }, { 18883 key: "getElBars", 18884 value: function getElBars() { 18885 return this.w.globals.dom.baseEl.querySelectorAll('.apexcharts-bar-series, .apexcharts-candlestick-series, .apexcharts-rangebar-series'); 18886 } 18887 }, { 18888 key: "hasBars", 18889 value: function hasBars() { 18890 var bars = this.getElBars(); 18891 return bars.length > 0; 18892 } 18893 }, { 18894 key: "markerClick", 18895 value: function markerClick(e, seriesIndex, dataPointIndex) { 18896 var w = this.w; 18897 18898 if (typeof w.config.chart.events.markerClick === 'function') { 18899 w.config.chart.events.markerClick(e, this.ctx, { 18900 seriesIndex: seriesIndex, 18901 dataPointIndex: dataPointIndex, 18902 w: w 18903 }); 18904 } 18905 18906 this.ctx.fireEvent('markerClick', [e, this.ctx, { 18907 seriesIndex: seriesIndex, 18908 dataPointIndex: dataPointIndex, 18909 w: w 18910 }]); 18911 } 18912 }, { 18913 key: "create", 18914 value: function create(e, context, capturedSeries, j, ttItems) { 18915 var shared = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null; 18916 var w = this.w; 18917 var ttCtx = context; 18918 18919 if (e.type === 'mouseup') { 18920 this.markerClick(e, capturedSeries, j); 18921 } 18922 18923 if (shared === null) shared = this.tConfig.shared; 18924 var hasMarkers = this.hasMarkers(); 18925 var bars = this.getElBars(); 18926 18927 if (shared) { 18928 ttCtx.tooltipLabels.drawSeriesTexts({ 18929 ttItems: ttItems, 18930 i: capturedSeries, 18931 j: j, 18932 shared: this.showOnIntersect ? false : this.tConfig.shared 18933 }); 18934 18935 if (hasMarkers) { 18936 if (w.globals.markers.largestSize > 0) { 18937 ttCtx.marker.enlargePoints(j); 18938 } else { 18939 ttCtx.tooltipPosition.moveDynamicPointsOnHover(j); 18940 } 18941 } 18942 18943 if (this.hasBars()) { 18944 this.barSeriesHeight = this.tooltipUtil.getBarsHeight(bars); 18945 18946 if (this.barSeriesHeight > 0) { 18947 // hover state, activate snap filter 18948 var graphics = new Graphics(this.ctx); 18949 var paths = w.globals.dom.Paper.select(".apexcharts-bar-area[j='".concat(j, "']")); // de-activate first 18950 18951 this.deactivateHoverFilter(); 18952 this.tooltipPosition.moveStickyTooltipOverBars(j); 18953 18954 for (var b = 0; b < paths.length; b++) { 18955 graphics.pathMouseEnter(paths[b]); 18956 } 18957 } 18958 } 18959 } else { 18960 ttCtx.tooltipLabels.drawSeriesTexts({ 18961 shared: false, 18962 ttItems: ttItems, 18963 i: capturedSeries, 18964 j: j 18965 }); 18966 18967 if (this.hasBars()) { 18968 ttCtx.tooltipPosition.moveStickyTooltipOverBars(j); 18969 } 18970 18971 if (hasMarkers) { 18972 ttCtx.tooltipPosition.moveMarkers(capturedSeries, j); 18973 } 18974 } 18975 } 18976 }]); 18977 18978 return Tooltip; 18979 }(); 18980 18981 var icoPan = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" fill=\"#000000\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\">\n <defs>\n <path d=\"M0 0h24v24H0z\" id=\"a\"/>\n </defs>\n <clipPath id=\"b\">\n <use overflow=\"visible\" xlink:href=\"#a\"/>\n </clipPath>\n <path clip-path=\"url(#b)\" d=\"M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z\"/>\n</svg>"; 18982 18983 var icoZoom = "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"#000000\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\">\n <path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\"/>\n <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n <path d=\"M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z\"/>\n</svg>"; 18984 18985 var icoReset = "<svg fill=\"#000000\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"/>\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\n</svg>"; 18986 18987 var icoZoomIn = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"/>\n</svg>\n"; 18988 18989 var icoZoomOut = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z\"/>\n</svg>\n"; 18990 18991 var icoSelect = "<svg fill=\"#6E8192\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2z\"/>\n</svg>"; 18992 18993 var icoMenu = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\"/></svg>"; 18994 18995 /** 18996 * ApexCharts Toolbar Class for creating toolbar in axis based charts. 18997 * 18998 * @module Toolbar 18999 **/ 19000 19001 var Toolbar = 19002 /*#__PURE__*/ 19003 function () { 19004 function Toolbar(ctx) { 19005 _classCallCheck(this, Toolbar); 19006 19007 this.ctx = ctx; 19008 this.w = ctx.w; 19009 this.ev = this.w.config.chart.events; 19010 this.localeValues = this.w.globals.locale.toolbar; 19011 } 19012 19013 _createClass(Toolbar, [{ 19014 key: "createToolbar", 19015 value: function createToolbar() { 19016 var w = this.w; 19017 var elToolbarWrap = document.createElement('div'); 19018 elToolbarWrap.setAttribute('class', 'apexcharts-toolbar'); 19019 w.globals.dom.elWrap.appendChild(elToolbarWrap); 19020 this.elZoom = document.createElement('div'); 19021 this.elZoomIn = document.createElement('div'); 19022 this.elZoomOut = document.createElement('div'); 19023 this.elPan = document.createElement('div'); 19024 this.elSelection = document.createElement('div'); 19025 this.elZoomReset = document.createElement('div'); 19026 this.elMenuIcon = document.createElement('div'); 19027 this.elMenu = document.createElement('div'); 19028 this.elCustomIcons = []; 19029 this.t = w.config.chart.toolbar.tools; 19030 19031 if (Array.isArray(this.t.customIcons)) { 19032 for (var i = 0; i < this.t.customIcons.length; i++) { 19033 this.elCustomIcons.push(document.createElement('div')); 19034 } 19035 } 19036 19037 this.elMenuItems = []; 19038 var toolbarControls = []; 19039 19040 if (this.t.zoomin && w.config.chart.zoom.enabled) { 19041 toolbarControls.push({ 19042 el: this.elZoomIn, 19043 icon: typeof this.t.zoomin === 'string' ? this.t.zoomin : icoZoomIn, 19044 title: this.localeValues.zoomIn, 19045 class: 'apexcharts-zoom-in-icon' 19046 }); 19047 } 19048 19049 if (this.t.zoomout && w.config.chart.zoom.enabled) { 19050 toolbarControls.push({ 19051 el: this.elZoomOut, 19052 icon: typeof this.t.zoomout === 'string' ? this.t.zoomout : icoZoomOut, 19053 title: this.localeValues.zoomOut, 19054 class: 'apexcharts-zoom-out-icon' 19055 }); 19056 } 19057 19058 if (this.t.zoom && w.config.chart.zoom.enabled) { 19059 toolbarControls.push({ 19060 el: this.elZoom, 19061 icon: typeof this.t.zoom === 'string' ? this.t.zoom : icoZoom, 19062 title: this.localeValues.selectionZoom, 19063 class: w.globals.isTouchDevice ? 'hidden' : 'apexcharts-zoom-icon' 19064 }); 19065 } 19066 19067 if (this.t.selection && w.config.chart.selection.enabled) { 19068 toolbarControls.push({ 19069 el: this.elSelection, 19070 icon: typeof this.t.selection === 'string' ? this.t.selection : icoSelect, 19071 title: this.localeValues.selection, 19072 class: w.globals.isTouchDevice ? 'hidden' : 'apexcharts-selection-icon' 19073 }); 19074 } 19075 19076 if (this.t.pan && w.config.chart.zoom.enabled) { 19077 toolbarControls.push({ 19078 el: this.elPan, 19079 icon: typeof this.t.pan === 'string' ? this.t.pan : icoPan, 19080 title: this.localeValues.pan, 19081 class: w.globals.isTouchDevice ? 'hidden' : 'apexcharts-pan-icon' 19082 }); 19083 } 19084 19085 if (this.t.reset && w.config.chart.zoom.enabled) { 19086 toolbarControls.push({ 19087 el: this.elZoomReset, 19088 icon: typeof this.t.reset === 'string' ? this.t.reset : icoReset, 19089 title: this.localeValues.reset, 19090 class: 'apexcharts-reset-zoom-icon' 19091 }); 19092 } 19093 19094 if (this.t.download) { 19095 toolbarControls.push({ 19096 el: this.elMenuIcon, 19097 icon: typeof this.t.download === 'string' ? this.t.download : icoMenu, 19098 title: this.localeValues.menu, 19099 class: 'apexcharts-menu-icon' 19100 }); 19101 } 19102 19103 for (var _i = 0; _i < this.elCustomIcons.length; _i++) { 19104 toolbarControls.push({ 19105 el: this.elCustomIcons[_i], 19106 icon: this.t.customIcons[_i].icon, 19107 title: this.t.customIcons[_i].title, 19108 index: this.t.customIcons[_i].index, 19109 class: 'apexcharts-toolbar-custom-icon ' + this.t.customIcons[_i].class 19110 }); 19111 } 19112
19113 toolbarControls.forEach(function (t, index) { 19114 if (t.index) { 19115 Utils.moveIndexInArray(toolbarControls, index, t.index); 19116 } 19117 }); 19118 19119 for (var _i2 = 0; _i2 < toolbarControls.length; _i2++) { 19120 Graphics.setAttrs(toolbarControls[_i2].el, { 19121 class: toolbarControls[_i2].class, 19122 title: toolbarControls[_i2].title 19123 }); 19124 toolbarControls[_i2].el.innerHTML = toolbarControls[_i2].icon; 19125 elToolbarWrap.appendChild(toolbarControls[_i2].el); 19126 } 19127 19128 elToolbarWrap.appendChild(this.elMenu); 19129 Graphics.setAttrs(this.elMenu, { 19130 class: 'apexcharts-menu' 19131 }); 19132 var menuItems = [{ 19133 name: 'exportSVG', 19134 title: this.localeValues.exportToSVG 19135 }, { 19136 name: 'exportPNG', 19137 title: this.localeValues.exportToPNG 19138 }]; 19139 19140 for (var _i3 = 0; _i3 < menuItems.length; _i3++) { 19141 this.elMenuItems.push(document.createElement('div')); 19142 this.elMenuItems[_i3].innerHTML = menuItems[_i3].title; 19143 Graphics.setAttrs(this.elMenuItems[_i3], { 19144 class: "apexcharts-menu-item ".concat(menuItems[_i3].name), 19145 title: menuItems[_i3].title 19146 }); 19147 this.elMenu.appendChild(this.elMenuItems[_i3]); 19148 } 19149 19150 if (w.globals.zoomEnabled) { 19151 this.elZoom.classList.add('selected'); 19152 } else if (w.globals.panEnabled) { 19153 this.elPan.classList.add('selected'); 19154 } else if (w.globals.selectionEnabled) { 19155 this.elSelection.classList.add('selected'); 19156 } 19157 19158 this.addToolbarEventListeners(); 19159 } 19160 }, { 19161 key: "addToolbarEventListeners", 19162 value: function addToolbarEventListeners() { 19163 var _this = this; 19164 19165 this.elZoomReset.addEventListener('click', this.handleZoomReset.bind(this)); 19166 this.elSelection.addEventListener('click', this.toggleSelection.bind(this)); 19167 this.elZoom.addEventListener('click', this.toggleZooming.bind(this)); 19168 this.elZoomIn.addEventListener('click', this.handleZoomIn.bind(this)); 19169 this.elZoomOut.addEventListener('click', this.handleZoomOut.bind(this)); 19170 this.elPan.addEventListener('click', this.togglePanning.bind(this)); 19171 this.elMenuIcon.addEventListener('click', this.toggleMenu.bind(this)); 19172 this.elMenuItems.forEach(function (m) { 19173 if (m.classList.contains('exportSVG')) { 19174 m.addEventListener('click', _this.downloadSVG.bind(_this)); 19175 } else if (m.classList.contains('exportPNG')) { 19176 m.addEventListener('click', _this.downloadPNG.bind(_this)); 19177 } 19178 }); 19179 19180 for (var i = 0; i < this.t.customIcons.length; i++) { 19181 this.elCustomIcons[i].addEventListener('click', this.t.customIcons[i].click); 19182 } 19183 } 19184 }, { 19185 key: "toggleSelection", 19186 value: function toggleSelection() { 19187 this.toggleOtherControls(); 19188 this.w.globals.selectionEnabled = !this.w.globals.selectionEnabled; 19189 19190 if (!this.elSelection.classList.contains('selected')) { 19191 this.elSelection.classList.add('selected'); 19192 } else { 19193 this.elSelection.classList.remove('selected'); 19194 } 19195 } 19196 }, { 19197 key: "toggleZooming", 19198 value: function toggleZooming() { 19199 this.toggleOtherControls(); 19200 this.w.globals.zoomEnabled = !this.w.globals.zoomEnabled; 19201 19202 if (!this.elZoom.classList.contains('selected')) { 19203 this.elZoom.classList.add('selected'); 19204 } else { 19205 this.elZoom.classList.remove('selected'); 19206 } 19207 } 19208 }, { 19209 key: "getToolbarIconsReference", 19210 value: function getToolbarIconsReference() { 19211 var w = this.w; 19212 19213 if (!this.elZoom) { 19214 this.elZoom = w.globals.dom.baseEl.querySelector('.apexcharts-zoom-icon'); 19215 } 19216 19217 if (!this.elPan) { 19218 this.elPan = w.globals.dom.baseEl.querySelector('.apexcharts-pan-icon'); 19219 } 19220 19221 if (!this.elSelection) { 19222 this.elSelection = w.globals.dom.baseEl.querySelector('.apexcharts-selection-icon'); 19223 } 19224 } 19225 }, { 19226 key: "enableZooming", 19227 value: function enableZooming() { 19228 this.toggleOtherControls(); 19229 this.w.globals.zoomEnabled = true; 19230 19231 if (this.elZoom) { 19232 this.elZoom.classList.add('selected'); 19233 } 19234 19235 if (this.elPan) { 19236 this.elPan.classList.remove('selected'); 19237 } 19238 } 19239 }, { 19240 key: "enablePanning", 19241 value: function enablePanning() { 19242 this.toggleOtherControls(); 19243 this.w.globals.panEnabled = true; 19244 19245 if (this.elPan) { 19246 this.elPan.classList.add('selected'); 19247 } 19248 19249 if (this.elZoom) { 19250 this.elZoom.classList.remove('selected'); 19251 } 19252 } 19253 }, { 19254 key: "togglePanning", 19255 value: function togglePanning() { 19256 this.toggleOtherControls(); 19257 this.w.globals.panEnabled = !this.w.globals.panEnabled; 19258 19259 if (!this.elPan.classList.contains('selected')) { 19260 this.elPan.classList.add('selected'); 19261 } else { 19262 this.elPan.classList.remove('selected'); 19263 } 19264 } 19265 }, { 19266 key: "toggleOtherControls", 19267 value: function toggleOtherControls() { 19268 var w = this.w; 19269 w.globals.panEnabled = false; 19270 w.globals.zoomEnabled = false; 19271 w.globals.selectionEnabled = false; 19272 this.getToolbarIconsReference(); 19273 19274 if (this.elPan) { 19275 this.elPan.classList.remove('selected'); 19276 } 19277 19278 if (this.elSelection) { 19279 this.elSelection.classList.remove('selected'); 19280 } 19281 19282 if (this.elZoom) { 19283 this.elZoom.classList.remove('selected'); 19284 } 19285 } 19286 }, { 19287 key: "handleZoomIn", 19288 value: function handleZoomIn() { 19289 var w = this.w; 19290 var centerX = (w.globals.minX + w.globals.maxX) / 2; 19291 var newMinX = (w.globals.minX + centerX) / 2; 19292 var newMaxX = (w.globals.maxX + centerX) / 2; 19293 19294 if (!w.globals.disableZoomIn) { 19295 this.zoomUpdateOptions(newMinX, newMaxX); 19296 } 19297 } 19298 }, { 19299 key: "handleZoomOut", 19300 value: function handleZoomOut() { 19301 var w = this.w; // avoid zooming out beyond 1000 which may result in NaN values being printed on x-a
19301xis 19302 19303 if (w.config.xaxis.type === 'datetime' && new Date(w.globals.minX).getUTCFullYear() < 1000) { 19304 return; 19305 } 19306 19307 var centerX = (w.globals.minX + w.globals.maxX) / 2; 19308 var newMinX = w.globals.minX - (centerX - w.globals.minX); 19309 var newMaxX = w.globals.maxX - (centerX - w.globals.maxX); 19310 19311 if (!w.globals.disableZoomOut) { 19312 this.zoomUpdateOptions(newMinX, newMaxX); 19313 } 19314 } 19315 }, { 19316 key: "zoomUpdateOptions", 19317 value: function zoomUpdateOptions(newMinX, newMaxX) { 19318 var xaxis = { 19319 min: newMinX, 19320 max: newMaxX 19321 }; 19322 var beforeZoomRange = this.getBeforeZoomRange(xaxis); 19323 19324 if (beforeZoomRange) { 19325 xaxis = beforeZoomRange.xaxis; 19326 } 19327 19328 this.w.globals.zoomed = true; 19329 19330 this.ctx._updateOptions({ 19331 xaxis: xaxis 19332 }, false, this.w.config.chart.animations.dynamicAnimation.enabled); 19333 19334 this.zoomCallback(xaxis); 19335 } 19336 }, { 19337 key: "zoomCallback", 19338 value: function zoomCallback(xaxis, yaxis) { 19339 if (typeof this.ev.zoomed === 'function') { 19340 this.ev.zoomed(this.ctx, { 19341 xaxis: xaxis, 19342 yaxis: yaxis 19343 }); 19344 } 19345 } 19346 }, { 19347 key: "getBeforeZoomRange", 19348 value: function getBeforeZoomRange(xaxis, yaxis) { 19349 var newRange = null; 19350 19351 if (typeof this.ev.beforeZoom === 'function') { 19352 newRange = this.ev.beforeZoom(this, { 19353 xaxis: xaxis, 19354 yaxis: yaxis 19355 }); 19356 } 19357 19358 return newRange; 19359 } 19360 }, { 19361 key: "toggleMenu", 19362 value: function toggleMenu() { 19363 if (this.elMenu.classList.contains('open')) { 19364 this.elMenu.classList.remove('open'); 19365 } else { 19366 this.elMenu.classList.add('open'); 19367 } 19368 } 19369 }, { 19370 key: "downloadPNG", 19371 value: function downloadPNG() { 19372 var downloadPNG = new Exports(this.ctx); 19373 downloadPNG.exportToPng(this.ctx); 19374 this.toggleMenu(); 19375 } 19376 }, { 19377 key: "downloadSVG", 19378 value: function downloadSVG() { 19379 var downloadSVG = new Exports(this.ctx); 19380 downloadSVG.exportToSVG(); 19381 this.toggleMenu(); 19382 } 19383 }, { 19384 key: "handleZoomReset", 19385 value: function handleZoomReset(e) { 19386 var _this2 = this; 19387 19388 var charts = this.ctx.getSyncedCharts(); 19389 charts.forEach(function (ch) { 19390 var w = ch.w; 19391 19392 if (w.globals.minX !== w.globals.initialminX && w.globals.maxX !== w.globals.initialmaxX) { 19393 ch.revertDefaultAxisMinMax(); 19394 19395 if (typeof w.config.chart.events.zoomed === 'function') { 19396 _this2.zoomCallback({ 19397 min: w.config.xaxis.min, 19398 max: w.config.xaxis.max 19399 }); 19400 } 19401 19402 w.globals.zoomed = false; 19403 19404 ch._updateSeries(w.globals.initialSeries, w.config.chart.animations.dynamicAnimation.enabled); 19405 } 19406 }); 19407 } 19408 }, { 19409 key: "destroy", 19410 value: function destroy() { 19411 if (this.elZoomReset) { 19412 this.elZoomReset.removeEventListener('click', this.handleZoomReset.bind(this)); 19413 this.elSelection.removeEventListener('click', this.toggleSelection.bind(this)); 19414 this.elZoom.removeEventListener('click', this.toggleZooming.bind(this)); 19415 this.elZoomIn.removeEventListener('click', this.handleZoomIn.bind(this)); 19416 this.elZoomOut.removeEventListener('click', this.handleZoomOut.bind(this)); 19417 this.elPan.removeEventListener('click', this.togglePanning.bind(this)); 19418 this.elMenuIcon.removeEventListener('click', this.toggleMenu.bind(this)); 19419 } 19420 19421 this.elZoom = null; 19422 this.elZoomIn = null; 19423 this.elZoomOut = null; 19424 this.elPan = null; 19425 this.elSelection = null; 19426 this.elZoomReset = null; 19427 this.elMenuIcon = null; 19428 } 19429 }]); 19430 19431 return Toolbar; 19432 }(); 19433 19434 /** 19435 * ApexCharts Zoom Class for handling zooming and panning on axes based charts. 19436 * 19437 * @module ZoomPanSelection 19438 **/ 19439 19440 var ZoomPanSelection = 19441 /*#__PURE__*/ 19442 function (_Toolbar) { 19443 _inherits(ZoomPanSelection, _Toolbar); 19444 19445 function ZoomPanSelection(ctx) { 19446 var _this; 19447 19448 _classCallCheck(this, ZoomPanSelection); 19449 19450 _this = _possibleConstructorReturn(this, _getPrototypeOf(ZoomPanSelection).call(this, ctx)); 19451 _this.ctx = ctx; 19452 _this.w = ctx.w; 19453 _this.dragged = false; 19454 _this.graphics = new Graphics(_this.ctx); 19455 _this.eventList = ['mousedown', 'mousemove', 'touchstart', 'touchmove', 'mouseup', 'touchend']; 19456 _this.clientX = 0; 19457 _this.clientY = 0; 19458 _this.startX = 0; 19459 _this.endX = 0; 19460 _this.dragX = 0; 19461 _this.startY = 0; 19462 _this.endY = 0; 19463 _this.dragY = 0; 19464 return _this; 19465 } 19466 19467 _createClass(ZoomPanSelection, [{ 19468 key: "init", 19469 value: function init(_ref) { 19470 var _this2 = this; 19471 19472 var xyRatios = _ref.xyRatios; 19473 var w = this.w; 19474 var me = this; 19475 this.xyRatios = xyRatios; 19476 this.zoomRect = this.graphics.drawRect(0, 0, 0, 0); 19477 this.selectionRect = this.graphics.drawRect(0, 0, 0, 0); 19478 this.gridRect = w.globals.dom.baseEl.querySelector('.apexcharts-grid'); 19479 this.zoomRect.node.classList.add('apexcharts-zoom-rect'); 19480 this.selectionRect.node.classList.add('apexcharts-selection-rect'); 19481 w.globals.dom.elGraphical.add(this.zoomRect); 19482 w.globals.dom.elGraphical.add(this.selectionRect); 19483 19484 if (w.config.chart.selection.type === 'x') { 19485 this.slDraggableRect = this.selectionRect.draggable({ 19486 minX: 0, 19487 minY: 0, 19488 maxX: w.globals.gridWidth, 19489 maxY: w.globals.gridHeight 19490 }).on('dragmove', this.selectionDragging.bind(this, 'dragging')); 19491 } else if (w.config.chart.selection.type === 'y') { 19492 this.slDraggableRect = this.selectionRect.draggable({ 19493 minX: 0, 19494 maxX: w.globals.gridWidth 19495 }).on('dragmove', this.selectionDragging.bind(this, 'dragging')); 19496 } else { 19497 this.slDraggableRect = this.selectionRect.draggable().on('dragmove', this.selectionDragging.bind(this, 'dragging')); 19498 } 19499 19500 this.preselectedSelection(); 19501 this.hoverArea = w.globals.dom.baseEl.querySelector(w.globals.chartClass); 19502 this.hoverArea.classList.add('zoomable'); 19503 this.eventList.forEach(function (event) { 19504 _this2.hoverArea.addEventListener(event, me.svgMouseEvents.bind(me, xyRatios), { 19505 capture: false, 19506 passive: true 19507 }); 19508 }); 19509 } // remove the event listeners which were previously added on hover area 19510 19511 }, {
19512 key: "destroy", 19513 value: function destroy() { 19514 var _this3 = this; 19515 19516 var me = this; 19517 this.eventList.forEach(function (event) { 19518 if (_this3.hoverArea) { 19519 _this3.hoverArea.removeEventListener(event, me.svgMouseEvents.bind(me, me.xyRatios), { 19520 capture: false, 19521 passive: true 19522 }); 19523 } 19524 }); 19525 19526 if (this.slDraggableRect) { 19527 this.slDraggableRect.draggable(false); 19528 this.slDraggableRect.off(); 19529 this.selectionRect.off(); 19530 } 19531 19532 this.selectionRect = null; 19533 this.zoomRect = null; 19534 this.gridRect = null; 19535 } 19536 }, { 19537 key: "svgMouseEvents", 19538 value: function svgMouseEvents(xyRatios, e) { 19539 var w = this.w; 19540 var me = this; 19541 var toolbar = this.ctx.toolbar; 19542 var zoomtype = w.globals.zoomEnabled ? w.config.chart.zoom.type : w.config.chart.selection.type; 19543 19544 if (e.shiftKey) { 19545 this.shiftWasPressed = true; 19546 toolbar.enablePanning(); 19547 } else { 19548 if (this.shiftWasPressed) { 19549 toolbar.enableZooming(); 19550 this.shiftWasPressed = false; 19551 } 19552 } 19553 19554 var falsePositives = e.target.classList.contains('apexcharts-selection-rect') || e.target.parentNode.classList.contains('apexcharts-toolbar'); 19555 if (falsePositives) return; 19556 me.clientX = e.type === 'touchmove' || e.type === 'touchstart' ? e.touches[0].clientX : e.type === 'touchend' ? e.changedTouches[0].clientX : e.clientX; 19557 me.clientY = e.type === 'touchmove' || e.type === 'touchstart' ? e.touches[0].clientY : e.type === 'touchend' ? e.changedTouches[0].clientY : e.clientY; 19558 19559 if (e.type === 'mousedown' && e.which === 1) { 19560 var gridRectDim = me.gridRect.getBoundingClientRect(); 19561 me.startX = me.clientX - gridRectDim.left; 19562 me.startY = me.clientY - gridRectDim.top; 19563 me.dragged = false; 19564 me.w.globals.mousedown = true; 19565 } 19566 19567 if (e.type === 'mousemove' && e.which === 1 || e.type === 'touchmove') { 19568 me.dragged = true; 19569 19570 if (w.globals.panEnabled) { 19571 w.globals.selection = null; 19572 19573 if (me.w.globals.mousedown) { 19574 me.panDragging({ 19575 context: me, 19576 zoomtype: zoomtype, 19577 xyRatios: xyRatios 19578 }); 19579 } 19580 } else { 19581 if (me.w.globals.mousedown && w.globals.zoomEnabled || me.w.globals.mousedown && w.globals.selectionEnabled) { 19582 me.selection = me.selectionDrawing({ 19583 context: me, 19584 zoomtype: zoomtype 19585 }); 19586 } 19587 } 19588 } 19589 19590 if (e.type === 'mouseup' || e.type === 'touchend') { 19591 // we will be calling getBoundingClientRect on each mousedown/mousemove/mouseup 19592 var _gridRectDim = me.gridRect.getBoundingClientRect(); 19593 19594 if (me.w.globals.mousedown) { 19595 // user released the drag, now do all the calculations 19596 me.endX = me.clientX - _gridRectDim.left; 19597 me.endY = me.clientY - _gridRectDim.top; 19598 me.dragX = Math.abs(me.endX - me.startX); 19599 me.dragY = Math.abs(me.endY - me.startY); 19600 19601 if (w.globals.zoomEnabled || w.globals.selectionEnabled) { 19602 me.selectionDrawn({ 19603 context: me, 19604 zoomtype: zoomtype 19605 }); 19606 } 19607 } 19608 19609 if (w.globals.zoomEnabled) { 19610 me.hideSelectionRect(this.selectionRect); 19611 } 19612 19613 me.dragged = false; 19614 me.w.globals.mousedown = false; 19615 } 19616 19617 this.makeSelectionRectDraggable(); 19618 } 19619 }, { 19620 key: "makeSelectionRectDraggable", 19621 value: function makeSelectionRectDraggable() { 19622 var w = this.w; 19623 if (!this.selectionRect) return; 19624 var rectDim = this.selectionRect.node.getBoundingClientRect(); 19625 19626 if (rectDim.width > 0 && rectDim.height > 0) { 19627 this.slDraggableRect.selectize().resize({ 19628 constraint: { 19629 minX: 0, 19630 minY: 0, 19631 maxX: w.globals.gridWidth, 19632 maxY: w.globals.gridHeight 19633 } 19634 }).on('resizing', this.selectionDragging.bind(this, 'resizing')); 19635 } 19636 } 19637 }, { 19638 key: "preselectedSelection", 19639 value: function preselectedSelection() { 19640 var w = this.w; 19641 var xyRatios = this.xyRatios; 19642 19643 if (!w.globals.zoomEnabled) { 19644 if (typeof w.globals.selection !== 'undefined' && w.globals.selection !== null) { 19645 this.drawSelectionRect(w.globals.selection); 19646 } else { 19647 if (w.config.chart.selection.xaxis.min !== undefined && w.config.chart.selection.xaxis.max !== undefined) { 19648 var x = (w.config.chart.selection.xaxis.min - w.globals.minX) / xyRatios.xRatio; 19649 var width = w.globals.gridWidth - (w.globals.maxX - w.config.chart.selection.xaxis.max) / xyRatios.xRatio - x; 19650 var selectionRect = { 19651 x: x, 19652 y: 0, 19653 width: width, 19654 height: w.globals.gridHeight, 19655 translateX: 0, 19656 translateY: 0, 19657 selectionEnabled: true 19658 }; 19659 this.drawSelectionRect(selectionRect); 19660 this.makeSelectionRectDraggable(); 19661 19662 if (typeof w.config.chart.events.selection === 'function') { 19663 w.config.chart.events.selection(this.ctx, { 19664 xaxis: { 19665 min: w.config.chart.selection.xaxis.min, 19666 max: w.config.chart.selection.xaxis.max 19667 }, 19668 yaxis: {} 19669 }); 19670 } 19671 } 19672 } 19673 } 19674 } 19675 }, { 19676 key: "drawSelectionRect", 19677 value: function drawSelectionRect(_ref2) { 19678 var x = _ref2.x, 19679 y = _ref2.y, 19680 width = _ref2.width, 19681 height = _ref2.height, 19682 translateX = _ref2.translateX, 19683 translateY = _ref2.translateY; 19684 var w = this.w; 19685 var zoomRect = this.zoomRect; 19686 var selectionRect = this.selectionRect; 19687 19688 if (this.dragged || w.globals.selection !== null) { 19689 var scalingAttrs = { 19690 transform: 'translate(' + translateX + ', ' + translateY + ')' // change styles based on zoom or selection 19691 // zoom is Enabled and user has dragged, so draw blue rect 19692 19693 }; 19694 19695 if (w.globals.zoomEnabled && this.dragged) { 19696 zoomRect.attr({ 19697 x: x, 19698 y: y, 19699 width: width, 19700 height: height, 19701 fill: w.config.chart.zoom.zoomedArea.fill.color, 19702 'fill-opacity': w.config.chart.zoom.zoomedArea.fill.opacity, 19703 stroke: w.config.chart.zoom.zoomedArea.stroke.color, 19704 'stroke-width': w.config.chart.zoom.zoomedArea.stroke.width, 19705 'stroke-opacity': w.config.chart.zoom.zoomedArea.stroke.opacity 19706 }); 19707 Graphics.setAttrs(zoomRect.node, scalingAttrs); 19708 } // selection is enabled 19709 19710 19711 if (w.globals.selectionEnabled) { 19712 selectionRect.attr({ 19713 x: x, 19714 y: y, 19715 width: width > 0 ? width : 0, 19716 height: height > 0 ? height : 0, 19717 fill: w.config.chart.selection.fill.color, 19718 'fill-opacity': w.config.chart.selection.fill.opacity, 19719 stroke: w.config.chart.selection.stroke.color, 19720 'stroke-width': w.config.chart.selection.stroke.width, 19721 'stroke-dasharray': w.config.chart.selection.stroke.dashArray, 19722 'stroke-opacity': w.config.chart.selection.stroke.opacity 19723 }); 19724 Graphics.setAttrs(selectionRect.node, scalingAttrs); 19725 } 19726 } 19727 } 19728 }, { 19729 key: "hideSelectionRect", 19730 value: function hideSelectionRect(rect) { 19731 if (rect) { 19732 rect.attr({ 19733 x: 0, 19734 y: 0, 19735 width: 0, 19736 height: 0 19737 }); 19738 } 19739 } 19740 }, { 19741 key: "selectionDrawing", 19742 value: function selectionDrawing(_ref3) { 19743 var context = _ref3.context, 19744 zoomtype = _ref3.zoomtype; 19745 var w = this.w; 19746 var me = context; 19747 var gridRectDim = this.gridRect.getBoundingClientRect(); 19748 var startX = me.startX - 1; 19749 var startY = me.startY; 19750 var selectionWidth = me.clientX - gridRectDim.left - startX;
19751 var selectionHeight = me.clientY - gridRectDim.top - startY; 19752 var translateX = 0; 19753 var translateY = 0; 19754 var selectionRect = {}; 19755 19756 if (Math.abs(selectionWidth + startX) > w.globals.gridWidth || me.clientX - gridRectDim.left < 0) { 19757 // user dragged the mouse outside drawing area 19758 // TODO: test the selectionRect and make sure it doesn't crosses drawing area 19759 me.hideSelectionRect(this.zoomRect); 19760 me.dragged = false; 19761 me.w.globals.mousedown = false; 19762 } // inverse selection X 19763 19764 19765 if (startX > me.clientX - gridRectDim.left) { 19766 selectionWidth = Math.abs(selectionWidth); 19767 translateX = -selectionWidth; 19768 } // inverse selection Y 19769 19770 19771 if (startY > me.clientY - gridRectDim.top) { 19772 selectionHeight = Math.abs(selectionHeight); 19773 translateY = -selectionHeight; 19774 } 19775 19776 if (zoomtype === 'x') { 19777 selectionRect = { 19778 x: startX, 19779 y: 0, 19780 width: selectionWidth, 19781 height: w.globals.gridHeight, 19782 translateX: translateX, 19783 translateY: 0 19784 }; 19785 } else if (zoomtype === 'y') { 19786 selectionRect = { 19787 x: 0, 19788 y: startY, 19789 width: w.globals.gridWidth, 19790 height: selectionHeight, 19791 translateX: 0, 19792 translateY: translateY 19793 }; 19794 } else { 19795 selectionRect = { 19796 x: startX, 19797 y: startY, 19798 width: selectionWidth, 19799 height: selectionHeight, 19800 translateX: translateX, 19801 translateY: translateY 19802 }; 19803 } 19804 19805 me.drawSelectionRect(selectionRect); 19806 me.selectionDragging('resizing'); 19807 return selectionRect; 19808 } 19809 }, { 19810 key: "selectionDragging", 19811 value: function selectionDragging(type, e) { 19812 var _this4 = this; 19813 19814 var w = this.w; 19815 var xyRatios = this.xyRatios; 19816 var selRect = this.selectionRect; 19817 var timerInterval = 0; 19818 19819 if (type === 'resizing') { 19820 timerInterval = 30; 19821 } 19822 19823 if (typeof w.config.chart.events.selection === 'function' && w.globals.selectionEnabled) { 19824 // a small debouncer is required when resizing to avoid freezing the chart 19825 clearTimeout(this.w.globals.selectionResizeTimer); 19826 this.w.globals.selectionResizeTimer = window.setTimeout(function () { 19827 var gridRectDim = _this4.gridRect.getBoundingClientRect(); 19828 19829 var selectionRect = selRect.node.getBoundingClientRect(); 19830 var minX = w.globals.xAxisScale.niceMin + (selectionRect.left - gridRectDim.left) * xyRatios.xRatio; 19831 var maxX = w.globals.xAxisScale.niceMin + (selectionRect.right - gridRectDim.left) * xyRatios.xRatio; 19832 var minY = w.globals.yAxisScale[0].niceMin + (gridRectDim.bottom - selectionRect.bottom) * xyRatios.yRatio[0]; 19833 var maxY = w.globals.yAxisScale[0].niceMax - (selectionRect.top - gridRectDim.top) * xyRatios.yRatio[0]; 19834 w.config.chart.events.selection(_this4.ctx, { 19835 xaxis: { 19836 min: minX, 19837 max: maxX 19838 }, 19839 yaxis: { 19840 min: minY, 19841 max: maxY 19842 } 19843 }); 19844 }, timerInterval); 19845 } 19846 } 19847 }, { 19848 key: "selectionDrawn", 19849 value: function selectionDrawn(_ref4) { 19850 var context = _ref4.context, 19851 zoomtype = _ref4.zoomtype; 19852 var w = this.w; 19853 var me = context; 19854 var xyRatios = this.xyRatios; 19855 var toolbar = this.ctx.toolbar; 19856 19857 if (me.startX > me.endX) { 19858 var tempX = me.startX; 19859 me.startX = me.endX; 19860 me.endX = tempX; 19861 } 19862 19863 if (me.startY > me.endY) { 19864 var tempY = me.startY; 19865 me.startY = me.endY; 19866 me.endY = tempY; 19867 } 19868 19869 var xLowestValue = w.globals.xAxisScale.niceMin + me.startX * xyRatios.xRatio; 19870 var xHighestValue = w.globals.xAxisScale.niceMin + me.endX * xyRatios.xRatio;
19870 // TODO: we will consider the 1st y axis values here for getting highest and lowest y 19871 19872 var yHighestValue = []; 19873 var yLowestValue = []; 19874 w.config.yaxis.forEach(function (yaxe, index) { 19875 yHighestValue.push(Math.floor(w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[index] * me.startY)); 19876 yLowestValue.push(Math.floor(w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[index] * me.endY)); 19877 }); 19878 19879 if (me.dragged && (me.dragX > 10 || me.dragY > 10) && xLowestValue !== xHighestValue) { 19880 if (w.globals.zoomEnabled) { 19881 var yaxis = Utils.clone(w.config.yaxis); // before zooming in/out, store the last yaxis and xaxis range, so that when user hits the RESET button, we get the original range 19882 // also - make sure user is not already zoomed in/out - otherwise we will store zoomed values in lastAxis 19883 19884 if (!w.globals.zoomed) { 19885 w.globals.lastXAxis = Utils.clone(w.config.xaxis); 19886 w.globals.lastYAxis = Utils.clone(w.config.yaxis); 19887 } 19888 19889 var xaxis = { 19890 min: xLowestValue, 19891 max: xHighestValue 19892 }; 19893 19894 if (zoomtype === 'xy' || zoomtype === 'y') { 19895 yaxis.forEach(function (yaxe, index) { 19896 yaxis[index].min = yLowestValue[index]; 19897 yaxis[index].max = yHighestValue[index]; 19898 }); 19899 } 19900 19901 if (w.config.chart.zoom.autoScaleYaxis) { 19902 var scale = new Range(me.ctx); 19903 yaxis = scale.autoScaleY(me.ctx, { 19904 xaxis: xaxis 19905 }); 19906 } 19907 19908 if (toolbar) { 19909 var beforeZoomRange = toolbar.getBeforeZoomRange(xaxis, yaxis); 19910 19911 if (beforeZoomRange) { 19912 xaxis = beforeZoomRange.xaxis ? beforeZoomRange.xaxis : xaxis; 19913 yaxis = beforeZoomRange.yaxis ? beforeZoomRange.yaxe : yaxis; 19914 } 19915 } 19916 19917 me.ctx._updateOptions({ 19918 xaxis: xaxis, 19919 yaxis: yaxis 19920 }, false, me.w.config.chart.animations.dynamicAnimation.enabled); 19921 19922 if (typeof w.config.chart.events.zoomed === 'function') { 19923 toolbar.zoomCallback(xaxis, yaxis); 19924 } 19925 19926 w.globals.zoomed = true; 19927 } else if (w.globals.selectionEnabled) { 19928 var _yaxis = null; 19929 var _xaxis = null; 19930 _xaxis = { 19931 min: xLowestValue, 19932 max: xHighestValue 19933 }; 19934 19935 if (zoomtype === 'xy' || zoomtype === 'y') { 19936 _yaxis = Utils.clone(w.config.yaxis); 19937 19938 _yaxis.forEach(function (yaxe, index) { 19939 _yaxis[index].min = yLowestValue[index]; 19940 _yaxis[index].max = yHighestValue[index]; 19941 }); 19942 } 19943 19944 w.globals.selection = me.selection; 19945 19946 if (typeof w.config.chart.events.selection === 'function') { 19947 w.config.chart.events.selection(me.ctx, { 19948 xaxis: _xaxis, 19949 yaxis: _yaxis 19950 }); 19951 } 19952 } 19953 } 19954 } 19955 }, { 19956 key: "panDragging", 19957 value: function panDragging(_ref5) { 19958 var context = _ref5.context, 19959 zoomtype = _ref5.zoomtype; 19960 var w = this.w; 19961 var me = context; 19962 var moveDirection; // check to make sure there is data to compare against 19963 19964 if (typeof w.globals.lastClientPosition.x !== 'undefined') { 19965 // get the change from last position to this position 19966 var deltaX = w.globals.lastClientPosition.x - me.clientX; 19967 var deltaY = w.globals.lastClientPosition.y - me.clientY; // check which direction had the highest amplitude and then figure out direction by checking if the value is greater or less than zero 19968 19969 if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX > 0) { 19970 moveDirection = 'left'; 19971 } else if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX < 0) { 19972 moveDirection = 'right'; 19973 } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY > 0) { 19974 moveDirection = 'up'; 19975 } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY < 0) { 19976 moveDirection = 'down'; 19977 } 19978 } // set the new last position to the current for next time (to get the position of drag) 19979 19980 19981 w.globals.lastClientPosition = { 19982 x: me.clientX, 19983 y: me.clientY 19984 }; 19985 var xLowestValue = w.globals.minX; 19986 var xHighestValue = w.globals.maxX; 19987 this.panScrolled(moveDirection, xLowestValue, xHighestValue); 19988 } 19989 }, { 19990 key: "panScrolled", 19991 value: function panScrolled(moveDirection, xLowestValue, xHighestValue) { 19992 var w = this.w; 19993 var xyRatios = this.xyRatios; 19994 var yaxis = Utils.clone(w.config.yaxis); 19995 19996 if (moveDirection === 'left') { 19997 xLowestValue = w.globals.minX + w.globals.gridWidth / 15 * xyRatios.xRatio; 19998 xHighestValue = w.globals.maxX + w.globals.gridWidth / 15 * xyRatios.xRatio; 19999 } else if (moveDirection === 'right') { 20000 xLowestValue = w.globals.minX - w.globals.gridWidth / 15 * xyRatios.xRatio; 20001 xHighestValue = w.globals.maxX - w.globals.gridWidth / 15 * xyRatios.xRatio; 20002 } 20003 20004 if (xLowestValue < w.globals.initialminX || xHighestValue > w.globals.initialmaxX) { 20005 xLowestValue = w.globals.minX; 20006 xHighestValue = w.globals.maxX; 20007 } 20008 20009 var xaxis = { 20010 min: xLowestValue, 20011 max: xHighestValue 20012 }; 20013 20014 if (w.config.chart.zoom.autoScaleYaxis) { 20015 var scale = new Range(me.ctx); 20016 yaxis = scale.autoScaleY(me.ctx, { 20017 xaxis: xaxis 20018 }); 20019 } 20020 20021 this.ctx._updateOptions({ 20022 xaxis: { 20023 min: xLowestValue, 20024 max: xHighestValue 20025 }, 20026 yaxis: yaxis 20027 }, false, false); 20028 20029 if (typeof w.config.chart.events.scrolled === 'function') { 20030 w.config.chart.events.scrolled(this.ctx, { 20031 xaxis: { 20032 min: xLowestValue, 20033 max: xHighestValue 20034 } 20035 }); 20036 } 20037 } 20038 }]); 20039 20040 return ZoomPanSelection; 20041 }(Toolbar); 20042 20043 var TitleSubtitle = 20044 /*#__PURE__*/ 20045 function () { 20046 function TitleSubtitle(ctx) { 20047 _classCallCheck(this, TitleSubtitle); 20048 20049 this.ctx = ctx; 20050 this.w = ctx.w; 20051 } 20052 20053 _createClass(TitleSubtitle, [{ 20054 key: "draw", 20055 value: function draw() { 20056 this.drawTitleSubtitle('title'); 20057 this.drawTitleSubtitle('subtitle'); 20058 } 20059 }, { 20060 key: "drawTitleSubtitle", 20061 value: function drawTitleSubtitle(type) { 20062 var w = this.w; 20063 var tsConfig = type === 'title' ? w.config.title : w.config.subtitle; 20064 var x = w.globals.svgWidth / 2; 20065 var y = tsConfig.offsetY; 20066 var textAnchor = 'middle'; 20067 20068 if (tsConfig.align === 'left') { 20069 x = 10; 20070 textAnchor = 'start'; 20071 } else if (tsConfig.align === 'right') { 20072 x = w.globals.svgWidth - 10; 20073 textAnchor = 'end'; 20074 } 20075 20076 x = x + tsConfig.offsetX; 20077 y = y + parseInt(tsConfig.style.fontSize) + 2; 20078 20079 if (tsConfig.text !== undefined) { 20080 var graphics = new Graphics(this.ctx); 20081 var titleText = graphics.drawText({ 20082 x: x, 20083 y: y, 20084 text: tsConfig.text, 20085 textAnchor: textAnchor, 20086 fontSize: tsConfig.style.fontSize, 20087 fontFamily: tsConfig.style.fontFamily, 20088 foreColor: tsConfig.style.color, 20089 opacity: 1 20090 }); 20091 titleText.node.setAttribute('class', "apexcharts-".concat(type, "-text")); 20092 w.globals.dom.Paper.add(titleText); 20093 } 20094 } 20095 }]); 20096 20097 return TitleSubtitle; 20098 }(); 20099 20100 (function (root, factory) { 20101 /* istanbul ignore next */ 20102 if (typeof define === 'function' && define.amd) { 20103 define(function () { 20104 return factory(root, root.document); 20105 }); 20106 /* below check fixes #412 */ 20107 } else if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined') { 20108 module.exports = root.document ? factory(root, root.document) : function (w) { 20109 return factory(w, w.document); 20110 }; 20111 } else { 20112 root.SVG = factory(root, root.document); 20113 } 20114 })(typeof window !== 'undefined' ? window : undefined, function (window, document) { 20115 // Find global reference - uses 'this' by default when available, 20116 // falls back to 'window' otherwise (for bundlers like Webpack) 20117 var globalRef = typeof this !== 'undefined' ? this : window; // The main wrapping element 20118
20119 var SVG = globalRef.SVG = function (element) { 20120 if (SVG.supported) { 20121 element = new SVG.Doc(element); 20122 20123 if (!SVG.parser.draw) { 20124 SVG.prepare(); 20125 } 20126 20127 return element; 20128 } 20129 }; // Default namespaces 20130 20131 20132 SVG.ns = 'http://www.w3.org/2000/svg'; 20133 SVG.xmlns = 'http://www.w3.org/2000/xmlns/'; 20134 SVG.xlink = 'http://www.w3.org/1999/xlink'; 20135 SVG.svgjs = 'http://svgjs.com/svgjs'; // Svg support test 20136 20137 SVG.supported = function () { 20138 return true; // !!document.createElementNS && 20139 // !! document.createElementNS(SVG.ns,'svg').createSVGRect 20140 }(); // Don't bother to continue if SVG is not supported 20141 20142 20143 if (!SVG.supported) return false; // Element id sequence 20144 20145 SVG.did = 1000; // Get next named element id 20146 20147 SVG.eid = function (name) { 20148 return 'Svgjs' + capitalize(name) + SVG.did++; 20149 }; // Method for element creation 20150 20151 20152 SVG.create = function (name) { 20153 // create element 20154 var element = document.createElementNS(this.ns, name); // apply unique id 20155 20156 element.setAttribute('id', this.eid(name)); 20157 return element; 20158 }; // Method for extending objects 20159 20160 20161 SVG.extend = function () { 20162 var modules, methods, key, i; // Get list of modules 20163 20164 modules = [].slice.call(arguments); // Get object with extensions 20165 20166 methods = modules.pop(); 20167 20168 for (i = modules.length - 1; i >= 0; i--) { 20169 if (modules[i]) { 20170 for (key in methods) { 20171 modules[i].prototype[key] = methods[key]; 20172 } 20173 } 20174 } // Make sure SVG.Set inherits any newly added methods 20175 20176 20177 if (SVG.Set && SVG.Set.inherit) { 20178 SVG.Set.inherit(); 20179 } 20180 }; // Invent new element 20181 20182 20183 SVG.invent = function (config) { 20184 // Create element initializer 20185 var initializer = typeof config.create === 'function' ? config.create : function () { 20186 this.constructor.call(this, SVG.create(config.create)); 20187 }; // Inherit prototype 20188 20189 if (config.inherit) { 20190 initializer.prototype = new config.inherit(); 20191 } // Extend with methods 20192 20193 20194 if (config.extend) { 20195 SVG.extend(initializer, config.extend); 20196 } // Attach construct method to parent 20197 20198 20199 if (config.construct) { 20200 SVG.extend(config.parent || SVG.Container, config.construct); 20201 } 20202 20203 return initializer; 20204 }; // Adopt existing svg elements 20205 20206 20207 SVG.adopt = function (node) { 20208 // check for presence of node 20209 if (!node) return null; // make sure a node isn't already adopted 20210 20211 if (node.instance) return node.instance; // initialize variables 20212 20213 var element; // adopt with element-specific settings 20214 20215 if (node.nodeName == 'svg') { 20216 element = node.parentNode instanceof window.SVGElement ? new SVG.Nested() : new SVG.Doc(); 20217 } else if (node.nodeName == 'linearGradient') { 20218 element = new SVG.Gradient('linear'); 20219 } else if (node.nodeName == 'radialGradient') { 20220 element = new SVG.Gradient('radial'); 20221 } else if (SVG[capitalize(node.nodeName)]) { 20222 element = new SVG[capitalize(node.nodeName)](); 20223 } else { 20224 element = new SVG.Element(node); 20225 } // ensure references 20226 20227 20228 element.type = node.nodeName; 20229 element.node = node; 20230 node.instance = element; // SVG.Class specific preparations 20231 20232 if (element instanceof SVG.Doc) { 20233 element.namespace().defs(); 20234 } // pull svgjs data from the dom (getAttributeNS doesn't work in html5) 20235 20236 20237 element.setData(JSON.parse(node.getAttribute('svgjs:data')) || {}); 20238 return element; 20239 }; // Initialize parsing element 20240 20241 20242 SVG.prepare = function () { 20243 // Select document body and create invisible svg element 20244 var body = document.getElementsByTagName('body')[0], 20245 draw = (body ? new SVG.Doc(body) : SVG.adopt(document.documentElement).nested()).size(2, 0); // Create parser object 20246 20247 SVG.parser = { 20248 body: body || document.documentElement, 20249 draw: draw.style('opacity:0;position:absolute;
20249left:-100%;top:-100%;overflow:hidden').node, 20250 poly: draw.polyline().node, 20251 path: draw.path().node, 20252 native: SVG.create('svg') 20253 }; 20254 }; 20255 20256 SVG.parser = { 20257 native: SVG.create('svg') 20258 }; 20259 document.addEventListener('DOMContentLoaded', function () { 20260 if (!SVG.parser.draw) { 20261 SVG.prepare(); 20262 } 20263 }, false); // Storage for regular expressions 20264 20265 SVG.regex = { 20266 // Parse unit value 20267 numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i, 20268 // Parse hex value 20269 hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i, 20270 // Parse rgb value 20271 rgb: /rgb\((\d+),(\d+),(\d+)\)/, 20272 // Parse reference id 20273 reference: /#([a-z0-9\-_]+)/i, 20274 // splits a transformation chain 20275 transforms: /\)\s*,?\s*/, 20276 // Whitespace 20277 whitespace: /\s/g, 20278 // Test hex value 20279 isHex: /^#[a-f0-9]{3,6}$/i, 20280 // Test rgb value 20281 isRgb: /^rgb\(/, 20282 // Test css declaration 20283 isCss: /[^:]+:[^;]+;?/, 20284 // Test for blank string 20285 isBlank: /^(\s+)?$/, 20286 // Test for numeric string 20287 isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, 20288 // Test for percent value 20289 isPercent: /^-?[\d\.]+%$/, 20290 // Test for image url 20291 isImage: /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i, 20292 // split at whitespace and comma 20293 delimiter: /[\s,]+/, 20294 // The following regex are used to parse the d attribute of a path 20295 // Matches all hyphens which are not after an exponent 20296 hyphen: /([^e])\-/gi, 20297 // Replaces and tests for all path letters 20298 pathLetters: /[MLHVCSQTAZ]/gi, 20299 // yes we need this one, too 20300 isPathLetter: /[MLHVCSQTAZ]/i, 20301 // matches 0.154.23.45 20302 numbersWithDots: /((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi, 20303 // matches . 20304 dots: /\./g 20305 }; 20306 SVG.utils = { 20307 // Map function 20308 map: function map(array, block) { 20309 var i, 20310 il = array.length, 20311 result = []; 20312 20313 for (i = 0; i < il; i++) { 20314 result.push(block(array[i])); 20315 } 20316 20317 return result; 20318 }, 20319 // Filter function 20320 filter: function filter(array, block) { 20321 var i, 20322 il = array.length, 20323 result = []; 20324 20325 for (i = 0; i < il; i++) { 20326 if (block(array[i])) { 20327 result.push(array[i]); 20328 } 20329 } 20330 20331 return result; 20332 }, 20333 // Degrees to radians 20334 radians: function radians(d) { 20335 return d % 360 * Math.PI / 180; 20336 }, 20337 // Radians to degrees 20338 degrees: function degrees(r) { 20339 return r * 180 / Math.PI % 360; 20340 }, 20341 filterSVGElements: function filterSVGElements(nodes) { 20342 return this.filter(nodes, function (el) { 20343 return el instanceof window.SVGElement; 20344 }); 20345 } 20346 }; 20347 SVG.defaults = { 20348 // Default attribute values 20349 attrs: { 20350 // fill and stroke 20351 'fill-opacity': 1, 20352 'stroke-opacity': 1, 20353 'stroke-width': 0, 20354 'stroke-linejoin': 'miter', 20355 'stroke-linecap': 'butt', 20356 fill: '#000000', 20357 stroke: '#000000', 20358 opacity: 1, 20359 // position 20360 x: 0, 20361 y: 0, 20362 cx: 0, 20363 cy: 0, 20364 // size 20365 width: 0, 20366 height: 0, 20367 // radius 20368 r: 0, 20369 rx: 0, 20370 ry: 0, 20371 // gradient 20372 offset: 0, 20373 'stop-opacity': 1, 20374 'stop-color': '#000000', 20375 // text 20376 'font-size': 16, 20377 'font-family': 'Helvetica, Arial, sans-serif', 20378 'text-anchor': 'start' 20379 } // Module for color convertions 20380 20381 }; 20382 20383 SVG.Color = function (color) { 20384 var match; // initialize defaults 20385 20386 this.r = 0; 20387 this.g = 0; 20388 this.b = 0; 20389 if (!color) return; // parse color 20390 20391 if (typeof color === 'string') { 20392 if (SVG.regex.isRgb.test(color)) { 20393 // get rgb values 20394 match = SVG.regex.rgb.exec(color.replace(SVG.regex.whitespace, '')); // parse numeric values 20395 20396 this.r = parseInt(match[1]); 20397 this.g = parseInt(match[2]); 20398 this.b = parseInt(match[3]); 20399 } else if (SVG.regex.isHex.test(color)) { 20400 // get hex values 20401 match = SVG.regex.hex.exec(fullHex(color)); // parse numeric values 20402 20403 this.r = parseInt(match[1], 16); 20404 this.g = parseInt(match[2], 16); 20405 this.b = parseInt(match[3], 16); 20406 } 20407 } else if (_typeof(color) === 'object') { 20408 this.r = color.r; 20409 this.g = color.g; 20410 this.b = color.b; 20411 } 20412 }; 20413 20414 SVG.extend(SVG.Color, { 20415 // Default to hex conversion 20416 toString: function toString() { 20417 return this.toHex(); 20418 }, 20419 // Build hex value 20420 toHex: function toHex() { 20421 return '#' + compToHex(this.r) + compToHex(this.g) + compToHex(this.b); 20422 }, 20423 // Build rgb value 20424 toRgb: function toRgb() { 20425 return 'rgb(' + [this.r, this.g, this.b].join() + ')'; 20426 }, 20427 // Calculate true brightness 20428 brightness: function brightness() { 20429 return this.r / 255 * 0.30 + this.g / 255 * 0.59 + this.b / 255 * 0.11; 20430 }, 20431 // Make color morphable 20432 morph: function morph(color) { 20433 this.destination = new SVG.Color(color); 20434 return this; 20435 }, 20436 // Get morphed color at given position 20437 at: function at(pos) { 20438 // make sure a destination is defined 20439 if (!this.destination) return this; // normalise pos 20440 20441 pos = pos < 0 ? 0 : pos > 1 ? 1 : pos; // generate morphed color 20442 20443 return new SVG.Color({ 20444 r: ~~(this.r + (this.destination.r - this.r) * pos), 20445 g: ~~(this.g + (this.destination.g - this.g) * pos), 20446 b: ~~(this.b + (this.destination.b - this.b) * pos) 20447 }); 20448 } 20449 }); // Testers 20450 // Test if given value is a color string 20451 20452 SVG.Color.test = function (color) { 20453 color += ''; 20454 return SVG.regex.isHex.test(color) || SVG.regex.isRgb.test(color); 20455 }; // Test if given value is a rgb object 20456 20457 20458 SVG.Color.isRgb = function (color) { 20459 return color && typeof color.r === 'number' && typeof color.g === 'number' && typeof color.b === 'number'; 20460 }; // Test if given value is a color 20461 20462 20463 SVG.Color.isColor = function (color) { 20464 return SVG.Color.isRgb(color) || SVG.Color.test(color); 20465 }; // Module for array conversion 20466 20467 20468 SVG.Array = function (array, fallback) { 20469 array = (array || []).valueOf(); // if array is empty and fallback is provided, use fallback 20470 20471 if (array.length == 0 && fallback) { 20472 array = fallback.valueOf(); 20473 } // parse array 20474 20475 20476 this.value = this.parse(array); 20477 }; 20478 20479 SVG.extend(SVG.Array, { 20480 // Make array morphable 20481 morph: function morph(array) { 20482 this.destination = this.parse(array); // normalize length of arrays 20483 20484 if (this.value.length != this.destination.length) { 20485 var lastValue = this.value[this.value.length - 1], 20486 lastDestination = this.destination[this.destination.length - 1]; 20487 20488 while (this.value.length > this.destination.length) { 20489 this.destination.push(lastDestination); 20490 } 20491 20492 while (this.value.length < this.destination.length) { 20493 this.value.push(lastValue); 20494 } 20495 } 20496 20497 return this; 20498 }, 20499 // Clean up any duplicate points 20500 settle: function settle() { 20501 // find all unique values 20502 for (var i = 0, il = this.value.length, seen = []; i < il; i++) { 20503 if (seen.indexOf(this.value[i]) == -1) { 20504 seen.push(this.value[i]); 20505 } 20506 } // set new value 20507 20508 20509 return this.value = seen; 20510 }, 20511 // Get morphed array at given position 20512 at: function at(pos) { 20513 // make sure a destination is defined 20514 if (!this.destination) return this; // generate morphed array 20515 20516 for (var i = 0, il = this.value.length, array = []; i < il; i++) { 20517 array.push(this.value[i] + (this.destination[i] - this.value[i]) * pos); 20518 } 20519 20520 return new SVG.Array(array); 20521 }, 20522 // Convert array to string 20523 toString: function toString() { 20524 return this.value.join(' '); 20525 }, 20526 // Real value
20527 valueOf: function valueOf() { 20528 return this.value; 20529 }, 20530 // Parse whitespace separated string 20531 parse: function parse(array) { 20532 array = array.valueOf(); // if already is an array, no need to parse it 20533 20534 if (Array.isArray(array)) return array; 20535 return this.split(array); 20536 }, 20537 // Strip unnecessary whitespace 20538 split: function split(string) { 20539 return string.trim().split(SVG.regex.delimiter).map(parseFloat); 20540 }, 20541 // Reverse array 20542 reverse: function reverse() { 20543 this.value.reverse(); 20544 return this; 20545 }, 20546 clone: function clone() { 20547 var clone = new this.constructor(); 20548 clone.value = array_clone(this.value); 20549 return clone; 20550 } 20551 }); // Poly points array 20552 20553 SVG.PointArray = function (array, fallback) { 20554 SVG.Array.call(this, array, fallback || [[0, 0]]); 20555 }; // Inherit from SVG.Array 20556 20557 20558 SVG.PointArray.prototype = new SVG.Array(); 20559 SVG.PointArray.prototype.constructor = SVG.PointArray; 20560 SVG.extend(SVG.PointArray, { 20561 // Convert array to string 20562 toString: function toString() { 20563 // convert to a poly point string 20564 for (var i = 0, il = this.value.length, array = []; i < il; i++) { 20565 array.push(this.value[i].join(',')); 20566 } 20567 20568 return array.join(' '); 20569 }, 20570 // Convert array to line object 20571 toLine: function toLine() { 20572 return { 20573 x1: this.value[0][0], 20574 y1: this.value[0][1], 20575 x2: this.value[1][0], 20576 y2: this.value[1][1] 20577 }; 20578 }, 20579 // Get morphed array at given position 20580 at: function at(pos) { 20581 // make sure a destination is defined 20582 if (!this.destination) return this; // generate morphed point string 20583 20584 for (var i = 0, il = this.value.length, array = []; i < il; i++) { 20585 array.push([this.value[i][0] + (this.destination[i][0] - this.value[i][0]) * pos, this.value[i][1] + (this.destination[i][1] - this.value[i][1]) * pos]); 20586 } 20587 20588 return new SVG.PointArray(array); 20589 }, 20590 // Parse point string and flat array 20591 parse: function parse(array) { 20592 var points = []; 20593 array = array.valueOf(); // if it is an array 20594 20595 if (Array.isArray(array)) { 20596 // and it is not flat, there is no need to parse it 20597 if (Array.isArray(array[0])) { 20598 // make sure to use a clone 20599 return array.map(function (el) { 20600 return el.slice(); 20601 }); 20602 } else if (array[0].x != null) { 20603 // allow point objects to be passed 20604 return array.map(function (el) { 20605 return [el.x, el.y]; 20606 }); 20607 } 20608 } else { 20609 // Else, it is considered as a string 20610 // parse points 20611 array = array.trim().split(SVG.regex.delimiter).map(parseFloat); 20612 } // validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints 20613 // Odd number of coordinates is an error. In such cases, drop the last odd coordinate. 20614 20615 20616 if (array.length % 2 !== 0) array.pop(); // wrap points in two-tuples and parse points as floats 20617 20618 for (var i = 0, len = array.length; i < len; i = i + 2) { 20619 points.push([array[i], array[i + 1]]); 20620 } 20621 20622 return points; 20623 }, 20624 // Move point string 20625 move: function move(x, y) { 20626 var box = this.bbox(); // get relative offset 20627 20628 x -= box.x; 20629 y -= box.y; // move every point 20630 20631 if (!isNaN(x) && !isNaN(y)) { 20632 for (var i = this.value.length - 1; i >= 0; i--) { 20633 this.value[i] = [this.value[i][0] + x, this.value[i][1] + y]; 20634 } 20635 } 20636 20637 return this; 20638 }, 20639 // Resize poly string 20640 size: function size(width, height) { 20641 var i, 20642 box = this.bbox(); // recalculate position of all points according to new size 20643 20644 for (i = this.value.length - 1; i >= 0; i--) { 20645 if (box.width) this.value[i][0] = (this.value[i][0] - box.x) * width / box.width + box.x; 20646 if (box.height) this.value[i][1] = (this.value[i][1] - box.y) * height / box.height + box.y; 20647 } 20648 20649 return this; 20650 }, 20651 // Get bounding box of points 20652 bbox: function bbox() { 20653 if (!SVG.parser.draw) { 20654 SVG.prepare(); 20655 } 20656 20657 SVG.parser.poly.setAttribute('points', this.toString()); 20658 return SVG.parser.poly.getBBox(); 20659 } 20660 });
20661 var pathHandlers = { 20662 M: function M(c, p, p0) { 20663 p.x = p0.x = c[0]; 20664 p.y = p0.y = c[1]; 20665 return ['M', p.x, p.y]; 20666 }, 20667 L: function L(c, p) { 20668 p.x = c[0]; 20669 p.y = c[1]; 20670 return ['L', c[0], c[1]]; 20671 }, 20672 H: function H(c, p) { 20673 p.x = c[0]; 20674 return ['H', c[0]]; 20675 }, 20676 V: function V(c, p) { 20677 p.y = c[0]; 20678 return ['V', c[0]]; 20679 }, 20680 C: function C(c, p) { 20681 p.x = c[4]; 20682 p.y = c[5]; 20683 return ['C', c[0], c[1], c[2], c[3], c[4], c[5]]; 20684 }, 20685 S: function S(c, p) { 20686 p.x = c[2]; 20687 p.y = c[3]; 20688 return ['S', c[0], c[1], c[2], c[3]]; 20689 }, 20690 Q: function Q(c, p) { 20691 p.x = c[2]; 20692 p.y = c[3]; 20693 return ['Q', c[0], c[1], c[2], c[3]]; 20694 }, 20695 T: function T(c, p) { 20696 p.x = c[0]; 20697 p.y = c[1]; 20698 return ['T', c[0], c[1]]; 20699 }, 20700 Z: function Z(c, p, p0) { 20701 p.x = p0.x; 20702 p.y = p0.y; 20703 return ['Z']; 20704 }, 20705 A: function A(c, p) { 20706 p.x = c[5]; 20707 p.y = c[6]; 20708 return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]]; 20709 } 20710 }; 20711 var mlhvqtcsa = 'mlhvqtcsaz'.split(''); 20712 20713 for (var i = 0, il = mlhvqtcsa.length; i < il; ++i) { 20714 pathHandlers[mlhvqtcsa[i]] = function (i) { 20715 return function (c, p, p0) { 20716 if (i == 'H') c[0] = c[0] + p.x;else if (i == 'V') c[0] = c[0] + p.y;else if (i == 'A') { 20717 c[5] = c[5] + p.x, c[6] = c[6] + p.y; 20718 } else { 20719 for (var j = 0, jl = c.length; j < jl; ++j) { 20720 c[j] = c[j] + (j % 2 ? p.y : p.x); 20721 } 20722 } 20723 return pathHandlers[i](c, p, p0); 20724 }; 20725 }(mlhvqtcsa[i].toUpperCase()); 20726 } // Path points array 20727 20728 20729 SVG.PathArray = function (array, fallback) { 20730 SVG.Array.call(this, array, fallback || [['M', 0, 0]]); 20731 }; // Inherit from SVG.Array 20732 20733 20734 SVG.PathArray.prototype = new SVG.Array(); 20735 SVG.PathArray.prototype.constructor = SVG.PathArray; 20736 SVG.extend(SVG.PathArray, { 20737 // Convert array to string 20738 toString: function toString() { 20739 return arrayToString(this.value); 20740 }, 20741 // Move path string 20742 move: function move(x, y) { 20743 // get bounding box of current situation 20744 var box = this.bbox(); // get relative offset 20745 20746 x -= box.x; 20747 y -= box.y; 20748 20749 if (!isNaN(x) && !isNaN(y)) { 20750 // move every point 20751 for (var l, i = this.value.length - 1; i >= 0; i--) { 20752 l = this.value[i][0]; 20753 20754 if (l == 'M' || l == 'L' || l == 'T') { 20755 this.value[i][1] += x; 20756 this.value[i][2] += y; 20757 } else if (l == 'H') { 20758 this.value[i][1] += x; 20759 } else if (l == 'V') { 20760 this.value[i][1] += y; 20761 } else if (l == 'C' || l == 'S' || l == 'Q') { 20762 this.value[i][1] += x; 20763 this.value[i][2] += y; 20764 this.value[i][3] += x; 20765 this.value[i][4] += y; 20766 20767 if (l == 'C') { 20768 this.value[i][5] += x; 20769 this.value[i][6] += y; 20770 } 20771 } else if (l == 'A') { 20772 this.value[i][6] += x; 20773 this.value[i][7] += y; 20774 } 20775 } 20776 } 20777 20778 return this; 20779 }, 20780 // Resize path string 20781 size: function size(width, height) { 20782 // get bounding box of current situation 20783 var i, 20784 l, 20785 box = this.bbox(); // recalculate position of all points according to new size 20786 20787 for (i = this.value.length - 1; i >= 0; i--) { 20788 l = this.value[i][0]; 20789 20790 if (l == 'M' || l == 'L' || l == 'T') { 20791 this.value[i][1] = (this.value[i][1] - box.x) * width / box.width + box.x; 20792 this.value[i][2] = (this.value[i][2] - box.y) * height / box.height + box.y; 20793 } else if (l == 'H') { 20794 this.value[i][1] = (this.value[i][1] - box.x) * width / box.width + box.x; 20795 } else if (l == 'V') { 20796 this.value[i][1] = (this.value[i][1] - box.y) * height / box.height + box.y; 20797 } else if (l == 'C' || l == 'S' || l == 'Q') { 20798 this.value[i][1] = (this.value[i][1] - box.x) * width / box.width + box.x; 20799 this.value[i][2] = (this.value[i][2] - box.y) * height / box.height + box.y; 20800 this.value[i][3] = (this.value[i][3] - box.x) * width / box.width + box.x; 20801 this.value[i][4] = (this.value[i][4] - box.y) * height / box.height + box.y; 20802 20803 if (l == 'C') { 20804 this.value[i][5] = (this.value[i][5] - box.x) * width / box.width + box.x; 20805 this.value[i][6] = (this.value[i][6] - box.y) * height / box.height + box.y; 20806 } 20807 } else if (l == 'A') { 20808 // resize radii 20809 this.value[i][1] = this.value[i][1] * width / box.width; 20810 this.value[i][2] = this.value[i][2] * height / box.height; // move position values 20811 20812 this.value[i][6] = (this.value[i][6] - box.x) * width / box.width + box.x; 20813 this.value[i][7] = (this.value[i][7] - box.y) * height / box.height + box.y; 20814 } 20815 } 20816 20817 return this; 20818 }, 20819 // Test if the passed path array use the same path data commands as this path array 20820 equalCommands: function equalCommands(pathArray) { 20821 var i, il, equalCommands; 20822 pathArray = new SVG.PathArray(pathArray);
20823 equalCommands = this.value.length === pathArray.value.length; 20824 20825 for (i = 0, il = this.value.length; equalCommands && i < il; i++) { 20826 equalCommands = this.value[i][0] === pathArray.value[i][0]; 20827 } 20828 20829 return equalCommands; 20830 }, 20831 // Make path array morphable 20832 morph: function morph(pathArray) { 20833 pathArray = new SVG.PathArray(pathArray); 20834 20835 if (this.equalCommands(pathArray)) { 20836 this.destination = pathArray; 20837 } else { 20838 this.destination = null; 20839 } 20840 20841 return this; 20842 }, 20843 // Get morphed path array at given position 20844 at: function at(pos) { 20845 // make sure a destination is defined 20846 if (!this.destination) return this; 20847 var sourceArray = this.value, 20848 destinationArray = this.destination.value, 20849 array = [], 20850 pathArray = new SVG.PathArray(), 20851 i, 20852 il, 20853 j, 20854 jl; // Animate has specified in the SVG spec 20855 // See: https://www.w3.org/TR/SVG11/paths.html#PathElement 20856 20857 for (i = 0, il = sourceArray.length; i < il; i++) { 20858 array[i] = [sourceArray[i][0]]; 20859 20860 for (j = 1, jl = sourceArray[i].length; j < jl; j++) { 20861 array[i][j] = sourceArray[i][j] + (destinationArray[i][j] - sourceArray[i][j]) * pos; 20862 } // For the two flags of the elliptical arc command, the SVG spec say: 20863 // Flags and booleans are interpolated as fractions between zero and one, with any non-zero value considered to be a value of one/true 20864 // Elliptical arc command as an array followed by corresponding indexes: 20865 // ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y] 20866 // 0 1 2 3 4 5 6 7 20867 20868 20869 if (array[i][0] === 'A') { 20870 array[i][4] = +(array[i][4] != 0); 20871 array[i][5] = +(array[i][5] != 0); 20872 } 20873 } // Directly modify the value of a path array, this is done this way for performance 20874 20875 20876 pathArray.value = array; 20877 return pathArray; 20878 }, 20879 // Absolutize and parse path to array 20880 parse: function parse(array) { 20881 // if it's already a patharray, no need to parse it 20882 if (array instanceof SVG.PathArray) return array.valueOf(); // prepare for parsing 20883 20884 var s, 20885 arr, 20886 paramCnt = { 20887 'M': 2, 20888 'L': 2, 20889 'H': 1, 20890 'V': 1, 20891 'C': 6, 20892 'S': 4, 20893 'Q': 4, 20894 'T': 2, 20895 'A': 7, 20896 'Z': 0 20897 }; 20898 20899 if (typeof array === 'string') { 20900 array = array.replace(SVG.regex.numbersWithDots, pathRegReplace) // convert 45.123.123 to 45.123 .123 20901 .replace(SVG.regex.pathLetters, ' $& ') // put some room between letters and numbers 20902 .replace(SVG.regex.hyphen, '$1 -') // add space before hyphen 20903 .trim() // trim 20904 .split(SVG.regex.delimiter); // split into array 20905 } else { 20906 array = array.reduce(function (prev, curr) { 20907 return [].concat.call(prev, curr); 20908 }, []); 20909 } // array now is an array containing all parts of a path e.g. ['M', '0', '0', 'L', '30', '30' ...] 20910 20911 20912 var arr = [], 20913 p = new SVG.Point(), 20914 p0 = new SVG.Point(), 20915 index = 0, 20916 len = array.length; 20917 20918 do { 20919 // Test if we have a path letter 20920 if (SVG.regex.isPathLetter.test(array[index])) { 20921 s = array[index]; 20922 ++index; // If last letter was a move command and we got no new, it defaults to [L]ine 20923 } else if (s == 'M') { 20924 s = 'L'; 20925 } else if (s == 'm') { 20926 s = 'l'; 20927 } 20928 20929 arr.push(pathHandlers[s].call(null, array.slice(index, index = index + paramCnt[s.toUpperCase()]).map(parseFloat), p, p0)); 20930 } while (len > index); 20931 20932 return arr; 20933 }, 20934 // Get bounding box of path 20935 bbox: function bbox() { 20936 if (!SVG.parser.draw) { 20937 SVG.prepare(); 20938 } 20939 20940 SVG.parser.path.setAttribute('d', this.toString()); 20941 return SVG.parser.path.getBBox(); 20942 } 20943 }); // Module for unit convertions 20944 20945 SVG.Number = SVG.invent({ 20946 // Initialize 20947 create: function create(value, unit) { 20948 // initialize defaults 20949 this.value = 0; 20950 this.unit = unit || ''; // parse value 20951 20952 if (typeof value === 'number') { 20953 // ensure a valid numeric value 20954 this.value = isNaN(value) ? 0 : !isFinite(value) ? value < 0 ? -3.4e+38 : +3.4e+38 : value; 20955 } else if (typeof value === 'string') { 20956 unit = value.match(SVG.regex.numberAndUnit); 20957 20958 if (unit) { 20959 // make value numeric 20960 this.value = parseFloat(unit[1]); // normalize 20961 20962 if (unit[5] == '%') { 20963 this.value /= 100; 20964 } else if (unit[5] == 's') { 20965 this.value *= 1000; 20966 } // store unit 20967 20968 20969 this.unit = unit[5]; 20970 } 20971 } else { 20972 if (value instanceof SVG.Number) { 20973 this.value = value.valueOf(); 20974 this.unit = value.unit; 20975 } 20976 } 20977 }, 20978 // Add methods 20979 extend: { 20980 // Stringalize 20981 toString: function toString() { 20982 return (this.unit == '%' ? ~~(this.value * 1e8) / 1e6 : this.unit == 's' ? this.value / 1e3 : this.value) + this.unit; 20983 }, 20984 toJSON: function toJSON() { 20985 return this.toString(); 20986 }, 20987 // Convert to primitive
20988 valueOf: function valueOf() { 20989 return this.value; 20990 }, 20991 // Add number 20992 plus: function plus(number) { 20993 number = new SVG.Number(number); 20994 return new SVG.Number(this + number, this.unit || number.unit); 20995 }, 20996 // Subtract number 20997 minus: function minus(number) { 20998 number = new SVG.Number(number); 20999 return new SVG.Number(this - number, this.unit || number.unit); 21000 }, 21001 // Multiply number 21002 times: function times(number) { 21003 number = new SVG.Number(number); 21004 return new SVG.Number(this * number, this.unit || number.unit); 21005 }, 21006 // Divide number 21007 divide: function divide(number) { 21008 number = new SVG.Number(number); 21009 return new SVG.Number(this / number, this.unit || number.unit); 21010 }, 21011 // Convert to different unit 21012 to: function to(unit) { 21013 var number = new SVG.Number(this); 21014 21015 if (typeof unit === 'string') { 21016 number.unit = unit; 21017 } 21018 21019 return number; 21020 }, 21021 // Make number morphable 21022 morph: function morph(number) { 21023 this.destination = new SVG.Number(number); 21024 21025 if (number.relative) { 21026 this.destination.value += this.value; 21027 } 21028 21029 return this; 21030 }, 21031 // Get morphed number at given position 21032 at: function at(pos) { 21033 // Make sure a destination is defined 21034 if (!this.destination) return this; // Generate new morphed number 21035 21036 return new SVG.Number(this.destination).minus(this).times(pos).plus(this); 21037 } 21038 } 21039 }); 21040 SVG.Element = SVG.invent({ 21041 // Initialize node 21042 create: function create(node) { 21043 // make stroke value accessible dynamically 21044 this._stroke = SVG.defaults.attrs.stroke; 21045 this._event = null; // initialize data object 21046 21047 this.dom = {}; // create circular reference 21048 21049 if (this.node = node) { 21050 this.type = node.nodeName; 21051 this.node.instance = this; // store current attribute value 21052 21053 this._stroke = node.getAttribute('stroke') || this._stroke; 21054 } 21055 }, 21056 // Add class methods 21057 extend: { 21058 // Move over x-axis 21059 x: function x(_x) { 21060 return this.attr('x', _x); 21061 }, 21062 // Move over y-axis 21063 y: function y(_y) { 21064 return this.attr('y', _y); 21065 }, 21066 // Move by center over x-axis 21067 cx: function cx(x) { 21068 return x == null ? this.x() + this.width() / 2 : this.x(x - this.width() / 2); 21069 }, 21070 // Move by center over y-axis 21071 cy: function cy(y) { 21072 return y == null ? this.y() + this.height() / 2 : this.y(y - this.height() / 2); 21073 }, 21074 // Move element to given x and y values 21075 move: function move(x, y) { 21076 return this.x(x).y(y); 21077 }, 21078 // Move element by its center 21079 center: function center(x, y) { 21080 return this.cx(x).cy(y); 21081 }, 21082 // Set width of element 21083 width: function width(_width) { 21084 return this.attr('width', _width); 21085 }, 21086 // Set height of element 21087 height: function height(_height) { 21088 return this.attr('height', _height); 21089 }, 21090 // Set element size to given width and height 21091 size: function size(width, height) { 21092 var p = proportionalSize(this, width, height); 21093 return this.width(new SVG.Number(p.width)).height(new SVG.Number(p.height)); 21094 }, 21095 // Clone element 21096 clone: function clone(parent) { 21097 // write dom data to the dom so the clone can pickup the data 21098 this.writeDataToDom(); // clone element and assign new id 21099 21100 var clone = assignNewId(this.node.cloneNode(true)); // insert the clone in the given parent or after myself 21101 21102 if (parent) parent.add(clone);else this.after(clone); 21103 return clone; 21104 }, 21105 // Remove element 21106 remove: function remove() { 21107 if (this.parent()) { 21108 this.parent().removeElement(this); 21109 } 21110 21111 return this; 21112 }, 21113 // Replace element 21114 replace: function replace(element) { 21115 this.after(element).remove(); 21116 return element; 21117 }, 21118 // Add element to given container and return self 21119 addTo: function addTo(parent) { 21120 return parent.put(this); 21121 }, 21122 // Add element to given container and return container 21123 putIn: function putIn(parent) { 21124 return parent.add(this); 21125 }, 21126 // Get / set id 21127 id: function id(_id) { 21128 return this.attr('id', _id); 21129 }, 21130 // Checks whether the given point inside the bounding box of the element 21131 inside: function inside(x, y) { 21132 var box = this.bbox(); 21133 return x > box.x && y > box.y && x < box.x + box.width && y < box.y + box.height; 21134 }, 21135 // Show element 21136 show: function show() { 21137 return this.style('display', ''); 21138 }, 21139 // Hide element 21140 hide: function hide() { 21141 return this.style('display', 'none'); 21142 }, 21143 // Is element visible? 21144 visible: function visible() { 21145 return this.style('display') != 'none'; 21146 }, 21147 // Return id on string conversion 21148 toString: function toString() { 21149 return this.attr('id'); 21150 }, 21151 // Return array of classes on the node 21152 classes: function classes() { 21153 var attr = this.attr('class'); 21154 return attr == null ? [] : attr.trim().split(SVG.regex.delimiter); 21155 }, 21156 // Return true if class exists on the node, false otherwise 21157 hasClass: function hasClass(name) { 21158 return this.classes().indexOf(name) != -1; 21159 }, 21160 // Add class to the node 21161 addClass: function addClass(name) { 21162 if (!this.hasClass(name)) { 21163 var array = this.classes(); 21164 array.push(name); 21165 this.attr('class', array.join(' '));
21166 } 21167 21168 return this; 21169 }, 21170 // Remove class from the node 21171 removeClass: function removeClass(name) { 21172 if (this.hasClass(name)) { 21173 this.attr('class', this.classes().filter(function (c) { 21174 return c != name; 21175 }).join(' ')); 21176 } 21177 21178 return this; 21179 }, 21180 // Toggle the presence of a class on the node 21181 toggleClass: function toggleClass(name) { 21182 return this.hasClass(name) ? this.removeClass(name) : this.addClass(name); 21183 }, 21184 // Get referenced element form attribute value 21185 reference: function reference(attr) { 21186 return SVG.get(this.attr(attr)); 21187 }, 21188 // Returns the parent element instance 21189 parent: function parent(type) { 21190 var parent = this; // check for parent 21191 21192 if (!parent.node.parentNode) return null; // get parent element 21193 21194 parent = SVG.adopt(parent.node.parentNode); 21195 if (!type) return parent; // loop trough ancestors if type is given 21196 21197 while (parent && parent.node instanceof window.SVGElement) { 21198 if (typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent; 21199 if (!parent.node.parentNode || parent.node.parentNode.nodeName == '#document') return null; // #759, #720 21200 21201 parent = SVG.adopt(parent.node.parentNode); 21202 } 21203 }, 21204 // Get parent document 21205 doc: function doc() { 21206 return this instanceof SVG.Doc ? this : this.parent(SVG.Doc); 21207 }, 21208 // return array of all ancestors of given type up to the root svg 21209 parents: function parents(type) { 21210 var parents = [], 21211 parent = this; 21212 21213 do { 21214 parent = parent.parent(type); 21215 if (!parent || !parent.node) break; 21216 parents.push(parent); 21217 } while (parent.parent); 21218 21219 return parents; 21220 }, 21221 // matches the element vs a css selector 21222 matches: function matches(selector) { 21223 return _matches(this.node, selector); 21224 }, 21225 // Returns the svg node to call native svg methods on it 21226 native: function native() { 21227 return this.node; 21228 }, 21229 // Import raw svg 21230 svg: function svg(_svg) { 21231 // create temporary holder 21232 var well = document.createElement('svg'); // act as a setter if svg is given 21233 21234 if (_svg && this instanceof SVG.Parent) { 21235 // dump raw svg 21236 well.innerHTML = '<svg>' + _svg.replace(/\n/, '').replace(/<([\w:-]+)([^<]+?)\/>/g, '<$1$2></$1>') + '</svg>'; // transplant nodes 21237 21238 for (var i = 0, il = well.firstChild.childNodes.length; i < il; i++) { 21239 this.node.appendChild(well.firstChild.firstChild); 21240 } // otherwise act as a getter 21241 21242 } else { 21243 // create a wrapping svg element in case of partial content 21244 well.appendChild(_svg = document.createElement('svg')); // write svgjs data to the dom 21245 21246 this.writeDataToDom(); // insert a copy of this node 21247 21248 _svg.appendChild(this.node.cloneNode(true)); // return target element 21249 21250 21251 return well.innerHTML.replace(/^<svg>/, '').replace(/<\/svg>$/, ''); 21252 } 21253 21254 return this; 21255 }, 21256 // write svgjs data to the dom 21257 writeDataToDom: function writeDataToDom() { 21258 // dump variables recursively 21259 if (this.each || this.lines) { 21260 var fn = this.each ? this : this.lines(); 21261 fn.each(function () { 21262 this.writeDataToDom(); 21263 }); 21264 } // remove previously set data 21265 21266 21267 this.node.removeAttribute('svgjs:data'); 21268 21269 if (Object.keys(this.dom).length) { 21270 this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)); 21271 } // see #428 21272 21273 21274 return this; 21275 }, 21276 // set given data to the elements data property 21277 setData: function setData(o) { 21278 this.dom = o; 21279 return this; 21280 }, 21281 is: function is(obj) { 21282 return _is(this, obj); 21283 } 21284 } 21285 });
21286 SVG.easing = { 21287 '-': function _(pos) { 21288 return pos; 21289 }, 21290 '<>': function _(pos) { 21291 return -Math.cos(pos * Math.PI) / 2 + 0.5; 21292 }, 21293 '>': function _(pos) { 21294 return Math.sin(pos * Math.PI / 2); 21295 }, 21296 '<': function _(pos) { 21297 return -Math.cos(pos * Math.PI / 2) + 1; 21298 } 21299 }; 21300 21301 SVG.morph = function (pos) { 21302 return function (from, to) { 21303 return new SVG.MorphObj(from, to).at(pos); 21304 }; 21305 }; 21306 21307 SVG.Situation = SVG.invent({ 21308 create: function create(o) { 21309 this.init = false; 21310 this.reversed = false; 21311 this.reversing = false; 21312 this.duration = new SVG.Number(o.duration).valueOf(); 21313 this.delay = new SVG.Number(o.delay).valueOf(); 21314 this.start = +new Date() + this.delay; 21315 this.finish = this.start + this.duration; 21316 this.ease = o.ease; // this.loop is incremented from 0 to this.loops 21317 // it is also incremented when in an infinite loop (when this.loops is true) 21318 21319 this.loop = 0; 21320 this.loops = false; 21321 this.animations = {// functionToCall: [list of morphable objects] 21322 // e.g. move: [SVG.Number, SVG.Number] 21323 }; 21324 this.attrs = {// holds all attributes which are not represented from a function svg.js provides 21325 // e.g. someAttr: SVG.Number 21326 }; 21327 this.styles = {// holds all styles which should be animated 21328 // e.g. fill-color: SVG.Color 21329 }; 21330 this.transforms = [// holds all transformations as transformation objects 21331 // e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix] 21332 ]; 21333 this.once = {// functions to fire at a specific position 21334 // e.g. "0.5": function foo(){} 21335 }; 21336 } 21337 }); 21338 SVG.FX = SVG.invent({ 21339 create: function create(element) { 21340 this._target = element; 21341 this.situations = []; 21342 this.active = false; 21343 this.situation = null; 21344 this.paused = false; 21345 this.lastPos = 0; 21346 this.pos = 0; // The absolute position of an animation is its position in the context of its complete duration (including delay and loops) 21347 // When performing a delay, absPos is below 0 and when performing a loop, its value is above 1 21348 21349 this.absPos = 0; 21350 this._speed = 1; 21351 }, 21352 extend: { 21353 /** 21354 * sets or returns the target of this animation 21355 * @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation
21356 * @param ease function || string Function which should be used for easing or easing keyword 21357 * @param delay Number indicating the delay before the animation starts 21358 * @return target || this 21359 */ 21360 animate: function animate(o, ease, delay) { 21361 if (_typeof(o) === 'object') { 21362 ease = o.ease; 21363 delay = o.delay; 21364 o = o.duration; 21365 } 21366 21367 var situation = new SVG.Situation({ 21368 duration: o || 1000, 21369 delay: delay || 0, 21370 ease: SVG.easing[ease || '-'] || ease 21371 }); 21372 this.queue(situation); 21373 return this; 21374 }, 21375 21376 /** 21377 * sets a delay before the next element of the queue is called 21378 * @param delay Duration of delay in milliseconds 21379 * @return this.target() 21380 */ 21381 delay: function delay(_delay) { 21382 // The delay is performed by an empty situation with its duration 21383 // attribute set to the duration of the delay 21384 var situation = new SVG.Situation({ 21385 duration: _delay, 21386 delay: 0, 21387 ease: SVG.easing['-'] 21388 }); 21389 return this.queue(situation); 21390 }, 21391 21392 /** 21393 * sets or returns the target of this animation 21394 * @param null || target SVG.Element which should be set as new target 21395 * @return target || this 21396 */ 21397 target: function target(_target) { 21398 if (_target && _target instanceof SVG.Element) { 21399 this._target = _target; 21400 return this; 21401 } 21402 21403 return this._target; 21404 }, 21405 // returns the absolute position at a given time 21406 timeToAbsPos: function timeToAbsPos(timestamp) { 21407 return (timestamp - this.situation.start) / (this.situation.duration / this._speed); 21408 }, 21409 // returns the timestamp from a given absolute positon 21410 absPosToTime: function absPosToTime(absPos) { 21411 return this.situation.duration / this._speed * absPos + this.situation.start; 21412 }, 21413 // starts the animationloop 21414 startAnimFrame: function startAnimFrame() { 21415 this.stopAnimFrame(); 21416 this.animationFrame = window.requestAnimationFrame(function () { 21417 this.step(); 21418 }.bind(this)); 21419 }, 21420 // cancels the animationframe 21421 stopAnimFrame: function stopAnimFrame() { 21422 window.cancelAnimationFrame(this.animationFrame); 21423 }, 21424 // kicks off the animation - only does something when the queue is currently not active and at least one situation is set 21425 start: function start() { 21426 // dont start if already started 21427 if (!this.active && this.situation) { 21428 this.active = true; 21429 this.startCurrent(); 21430 } 21431 21432 return this; 21433 }, 21434 // start the current situation 21435 startCurrent: function startCurrent() { 21436 this.situation.start = +new Date() + this.situation.delay / this._speed; 21437 this.situation.finish = this.situation.start + this.situation.duration / this._speed; 21438 return this.initAnimations().step(); 21439 }, 21440 21441 /** 21442 * adds a function / Situation to the animation queue 21443 * @param fn function / situation to add 21444 * @return this 21445 */ 21446 queue: function queue(fn) { 21447 if (typeof fn === 'function' || fn instanceof SVG.Situation) { 21448 this.situations.push(fn); 21449 } 21450 21451 if (!this.situation) this.situation = this.situations.shift(); 21452 return this; 21453 }, 21454 21455 /** 21456 * pulls next element from the queue and execute it 21457 * @return this 21458 */ 21459 dequeue: function dequeue() { 21460 // stop current animation 21461 this.stop(); // get next animation from queue 21462 21463 this.situation = this.situations.shift(); 21464 21465 if (this.situation) { 21466 if (this.situation instanceof SVG.Situation) { 21467 this.start(); 21468 } else { 21469 // If it is not a SVG.Situation, then it is a function, we execute it 21470 this.situation.call(this); 21471 } 21472 } 21473 21474 return this; 21475 }, 21476 // updates all animations to the current state of the element 21477 // this is important when one property could be changed from another property 21478 initAnimations: function initAnimations() { 21479 var i, j, source; 21480 var s = this.situation; 21481 if (s.init) return this; 21482 21483 for (i in s.animations) { 21484 source = this.target()[i](); 21485 21486 if (!Array.isArray(source)) { 21487 source = [source]; 21488 } 21489 21490 if (!Array.isArray(s.animations[i])) { 21491 s.animations[i] = [s.animations[i]]; 21492 } // if(s.animations[i].length > source.length) { 21493 // source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length)) 21494 // } 21495 21496 21497 for (j = source.length; j--;) { 21498 // The condition is because some methods return a normal number instead 21499 // of a SVG.Number 21500 if (s.animations[i][j] instanceof SVG.Number) { 21501 source[j] = new SVG.Number(source[j]); 21502 } 21503 21504 s.animations[i][j] = source[j].morph(s.animations[i][j]); 21505 } 21506 } 21507 21508 for (i in s.attrs) {
21509 s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i]); 21510 } 21511 21512 for (i in s.styles) { 21513 s.styles[i] = new SVG.MorphObj(this.target().style(i), s.styles[i]); 21514 } 21515 21516 s.initialTransformation = this.target().matrixify(); 21517 s.init = true; 21518 return this; 21519 }, 21520 clearQueue: function clearQueue() { 21521 this.situations = []; 21522 return this; 21523 }, 21524 clearCurrent: function clearCurrent() { 21525 this.situation = null; 21526 return this; 21527 }, 21528 21529 /** stops the animation immediately 21530 * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. 21531 * @param clearQueue A Boolean indicating whether to remove queued animation as well. 21532 * @return this 21533 */ 21534 stop: function stop(jumpToEnd, clearQueue) { 21535 var active = this.active; 21536 this.active = false; 21537 21538 if (clearQueue) { 21539 this.clearQueue(); 21540 } 21541 21542 if (jumpToEnd && this.situation) { 21543 // initialize the situation if it was not 21544 !active && this.startCurrent(); 21545 this.atEnd(); 21546 } 21547 21548 this.stopAnimFrame(); 21549 return this.clearCurrent(); 21550 }, 21551 21552 /** resets the element to the state where the current element has started 21553 * @return this 21554 */ 21555 reset: function reset() { 21556 if (this.situation) { 21557 var temp = this.situation; 21558 this.stop(); 21559 this.situation = temp; 21560 this.atStart(); 21561 } 21562 21563 return this; 21564 }, 21565 // Stop the currently-running animation, remove all queued animations, and complete all animations for the element. 21566 finish: function finish() { 21567 this.stop(true, false); 21568 21569 while (this.dequeue().situation && this.stop(true, false)) { 21570 } 21571 21572 this.clearQueue().clearCurrent(); 21573 return this; 21574 }, 21575 // set the internal animation pointer at the start position, before any loops, and updates the visualisation 21576 atStart: function atStart() { 21577 return this.at(0, true); 21578 }, 21579 // set the internal animation pointer at the end position, after all the loops, and updates the visualisation 21580 atEnd: function atEnd() { 21581 if (this.situation.loops === true) { 21582 // If in a infinite loop, we end the current iteration 21583 this.situation.loops = this.situation.loop + 1; 21584 } 21585 21586 if (typeof this.situation.loops === 'number') { 21587 // If performing a finite number of loops, we go after all the loops 21588 return this.at(this.situation.loops, true); 21589 } else { 21590 // If no loops, we just go at the end 21591 return this.at(1, true); 21592 } 21593 }, 21594 // set the internal animation pointer to the specified position and updates the visualisation 21595 // if isAbsPos is true, pos is treated as an absolute position 21596 at: function at(pos, isAbsPos) { 21597 var durDivSpd = this.situation.duration / this._speed; 21598 this.absPos = pos; // If pos is not an absolute position, we convert it into one 21599 21600 if (!isAbsPos) { 21601 if (this.situation.reversed) this.absPos = 1 - this.absPos; 21602 this.absPos += this.situation.loop; 21603 } 21604 21605 this.situation.start = +new Date() - this.absPos * durDivSpd; 21606 this.situation.finish = this.situation.start + durDivSpd; 21607 return this.step(true); 21608 }, 21609 21610 /** 21611 * sets or returns the speed of the animations 21612 * @param speed null || Number The new speed of the animations 21613 * @return Number || this 21614 */ 21615 speed: function speed(_speed) { 21616 if (_speed === 0) return this.pause(); 21617 21618 if (_speed) { 21619 this._speed = _speed; // We use an absolute position here so that speed can affect the delay before the animation 21620 21621 return this.at(this.absPos, true); 21622 } else return this._speed; 21623 }, 21624 // Make loopable 21625 loop: function loop(times, reverse) { 21626 var c = this.last(); // store total loops 21627 21628 c.loops = times != null ? times : true; 21629 c.loop = 0; 21630 if (reverse) c.reversing = true; 21631 return this; 21632 }, 21633 // pauses the animation 21634 pause: function pause() { 21635 this.paused = true;
21636 this.stopAnimFrame(); 21637 return this; 21638 }, 21639 // unpause the animation 21640 play: function play() { 21641 if (!this.paused) return this; 21642 this.paused = false; // We use an absolute position here so that the delay before the animation can be paused 21643 21644 return this.at(this.absPos, true); 21645 }, 21646 21647 /** 21648 * toggle or set the direction of the animation 21649 * true sets direction to backwards while false sets it to forwards 21650 * @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status) 21651 * @return this 21652 */ 21653 reverse: function reverse(reversed) { 21654 var c = this.last(); 21655 if (typeof reversed === 'undefined') c.reversed = !c.reversed;else c.reversed = reversed; 21656 return this; 21657 }, 21658 21659 /** 21660 * returns a float from 0-1 indicating the progress of the current animation 21661 * @param eased Boolean indicating whether the returned position should be eased or not 21662 * @return number 21663 */ 21664 progress: function progress(easeIt) { 21665 return easeIt ? this.situation.ease(this.pos) : this.pos; 21666 }, 21667 21668 /** 21669 * adds a callback function which is called when the current animation is finished 21670 * @param fn Function which should be executed as callback 21671 * @return number 21672 */ 21673 after: function after(fn) { 21674 var c = this.last(), 21675 wrapper = function wrapper(e) { 21676 if (e.detail.situation == c) { 21677 fn.call(this, c); 21678 this.off('finished.fx', wrapper); // prevent memory leak 21679 } 21680 }; 21681 21682 this.target().on('finished.fx', wrapper); 21683 return this._callStart(); 21684 }, 21685 // adds a callback which is called whenever one animation step is performed 21686 during: function during(fn) { 21687 var c = this.last(), 21688 wrapper = function wrapper(e) { 21689 if (e.detail.situation == c) { 21690 fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c); 21691 } 21692 }; // see above 21693 21694 21695 this.target().off('during.fx', wrapper).on('during.fx', wrapper); 21696 this.after(function () { 21697 this.off('during.fx', wrapper); 21698 }); 21699 return this._callStart(); 21700 }, 21701 // calls after ALL animations in the queue are finished 21702 afterAll: function afterAll(fn) { 21703 var wrapper = function wrapper(e) { 21704 fn.call(this); 21705 this.off('allfinished.fx', wrapper); 21706 }; // see above 21707 21708 21709 this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper); 21710 return this._callStart(); 21711 }, 21712 // calls on every animation step for all animations 21713 duringAll: function duringAll(fn) { 21714 var wrapper = function wrapper(e) { 21715 fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation); 21716 }; 21717 21718 this.target().off('during.fx', wrapper).on('during.fx', wrapper); 21719 this.afterAll(function () { 21720 this.off('during.fx', wrapper); 21721 }); 21722 return this._callStart(); 21723 }, 21724 last: function last() { 21725 return this.situations.length ? this.situations[this.situations.length - 1] : this.situation; 21726 }, 21727 // adds one property to the animations 21728 add: function add(method, args, type) { 21729 this.last()[type || 'animations'][method] = args; 21730 return this._callStart(); 21731 }, 21732 21733 /** perform one step of the animation 21734 * @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time 21735 * @return this 21736 */ 21737 step: function step(ignoreTime) { 21738 // convert current time to an absolute position 21739 if (!ignoreTime) this.absPos = this.timeToAbsPos(+new Date()); // This part convert an absolute position to a position 21740 21741 if (this.situation.loops !== false) { 21742 var absPos, absPosInt, lastLoop; // If the absolute position is below 0, we just treat it as if it was 0 21743 21744 absPos = Math.max(this.absPos, 0); 21745 absPosInt = Math.floor(absPos); 21746 21747 if (this.situation.loops === true || absPosInt < this.situation.loops) { 21748 this.pos = absPos - absPosInt; 21749 lastLoop = this.situation.loop; 21750 this.situation.loop = absPosInt; 21751 } else { 21752 this.absPos = this.situation.loops; 21753 this.pos = 1; // The -1 here is because we don't want to toggle reversed when all the loops have been completed 21754 21755 lastLoop = this.situation.loop - 1; 21756 this.situation.loop = this.situation.loops; 21757 } 21758 21759 if (this.situation.reversing) { 21760 // Toggle reversed if an odd number of loops as occured since the last call of step 21761 this.situation.reversed = this.situation.reversed != Boolean((this.situation.loop - lastLoop) % 2); 21762 } 21763 } else { 21764 // If there are no loop, the absolute position must not be above 1 21765 this.absPos = Math.min(this.absPos, 1); 21766 this.pos = this.absPos; 21767 } // while the absolute position can be below 0, the position must not be below 0 21768 21769 21770 if (this.pos < 0) this.pos = 0; 21771 if (this.situation.reversed) this.pos = 1 - this.pos; // apply easing 21772 21773 var eased = this.situation.ease(this.pos); // call once-callbacks 21774 21775 for (var i in this.situation.once) { 21776 if (i > this.lastPos && i <= eased) { 21777 this.situation.once[i].call(this.target(), this.pos, eased); 21778 delete this.situation.once[i]; 21779 } 21780 } // fire during callback with position, eased position and current situation as parameter 21781 21782 21783 if (this.active) this.target().fire('during', { 21784 pos: this.pos, 21785 eased: eased, 21786 fx: this, 21787 situation: this.situation 21788 }); // the user may call stop or finish in the during callback 21789 // so make sure that we still have a valid situation 21790 21791 if (!this.situation) { 21792 return this; 21793 } // apply the actual animation to every property 21794 21795 21796 this.eachAt(); // do final code when situation is finished 21797 21798 if (this.pos == 1 && !this.situation.reversed || this.situation.reversed && this.pos == 0) { 21799 // stop animation callback
21800 this.stopAnimFrame(); // fire finished callback with current situation as parameter 21801 21802 this.target().fire('finished', { 21803 fx: this, 21804 situation: this.situation 21805 }); 21806 21807 if (!this.situations.length) { 21808 this.target().fire('allfinished'); // Recheck the length since the user may call animate in the afterAll callback 21809 21810 if (!this.situations.length) { 21811 this.target().off('.fx'); // there shouldnt be any binding left, but to make sure... 21812 21813 this.active = false; 21814 } 21815 } // start next animation 21816 21817 21818 if (this.active) this.dequeue();else this.clearCurrent(); 21819 } else if (!this.paused && this.active) { 21820 // we continue animating when we are not at the end 21821 this.startAnimFrame(); 21822 } // save last eased position for once callback triggering 21823 21824 21825 this.lastPos = eased; 21826 return this; 21827 }, 21828 // calculates the step for every property and calls block with it 21829 eachAt: function eachAt() { 21830 var i, 21831 len, 21832 at, 21833 self = this, 21834 target = this.target(), 21835 s = this.situation; // apply animations which can be called trough a method 21836 21837 for (i in s.animations) { 21838 at = [].concat(s.animations[i]).map(function (el) { 21839 return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el; 21840 }); 21841 target[i].apply(target, at); 21842 } // apply animation which has to be applied with attr() 21843 21844 21845 for (i in s.attrs) { 21846 at = [i].concat(s.attrs[i]).map(function (el) { 21847 return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el; 21848 }); 21849 target.attr.apply(target, at); 21850 } // apply animation which has to be applied with style() 21851 21852 21853 for (i in s.styles) { 21854 at = [i].concat(s.styles[i]).map(function (el) { 21855 return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el; 21856 }); 21857 target.style.apply(target, at); 21858 } // animate initialTransformation which has to be chained 21859 21860 21861 if (s.transforms.length) { 21862 // get initial initialTransformation 21863 at = s.initialTransformation; 21864 21865 for (i = 0, len = s.transforms.length; i < len; i++) { 21866 // get next transformation in chain 21867 var a = s.transforms[i]; // multiply matrix directly 21868 21869 if (a instanceof SVG.Matrix) { 21870 if (a.relative) { 21871 at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos))); 21872 } else { 21873 at = at.morph(a).at(s.ease(this.pos)); 21874 } 21875 21876 continue; 21877 } // when transformation is absolute we have to reset the needed transformation first 21878 21879 21880 if (!a.relative) { 21881 a.undo(at.extract()); 21882 } // and reapply it after 21883 21884 21885 at = at.multiply(a.at(s.ease(this.pos))); 21886 } // set new matrix on element 21887 21888 21889 target.matrix(at); 21890 } 21891 21892 return this; 21893 }, 21894 // adds an once-callback which is called at a specific position and never again 21895 once: function once(pos, fn, isEased) { 21896 var c = this.last(); 21897 if (!isEased) pos = c.ease(pos); 21898 c.once[pos] = fn; 21899 return this; 21900 }, 21901 _callStart: function _callStart() { 21902 setTimeout(function () { 21903 this.start(); 21904 }.bind(this), 0); 21905 return this; 21906 } 21907 }, 21908 parent: SVG.Element, 21909 // Add method to parent elements 21910 construct: { 21911 // Get fx module or create a new one, then animate with given duration and ease 21912 animate: function animate(o, ease, delay) { 21913 return (this.fx || (this.fx = new SVG.FX(this))).animate(o, ease, delay); 21914 }, 21915 delay: function delay(_delay2) {
21916 return (this.fx || (this.fx = new SVG.FX(this))).delay(_delay2); 21917 }, 21918 stop: function stop(jumpToEnd, clearQueue) { 21919 if (this.fx) { 21920 this.fx.stop(jumpToEnd, clearQueue); 21921 } 21922 21923 return this; 21924 }, 21925 finish: function finish() { 21926 if (this.fx) { 21927 this.fx.finish(); 21928 } 21929 21930 return this; 21931 }, 21932 // Pause current animation 21933 pause: function pause() { 21934 if (this.fx) { 21935 this.fx.pause(); 21936 } 21937 21938 return this; 21939 }, 21940 // Play paused current animation 21941 play: function play() { 21942 if (this.fx) { 21943 this.fx.play(); 21944 } 21945 21946 return this; 21947 }, 21948 // Set/Get the speed of the animations 21949 speed: function speed(_speed2) { 21950 if (this.fx) { 21951 if (_speed2 == null) { 21952 return this.fx.speed(); 21953 } else { 21954 this.fx.speed(_speed2); 21955 } 21956 } 21957 21958 return this; 21959 } 21960 } 21961 }); // MorphObj is used whenever no morphable object is given 21962 21963 SVG.MorphObj = SVG.invent({ 21964 create: function create(from, to) { 21965 // prepare color for morphing 21966 if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to); // check if we have a list of values 21967 21968 if (SVG.regex.delimiter.test(from)) { 21969 // prepare path for morphing 21970 if (SVG.regex.pathLetters.test(from)) return new SVG.PathArray(from).morph(to); // prepare value list for morphing 21971 else return new SVG.Array(from).morph(to); 21972 } // prepare number for morphing 21973 21974 21975 if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to); // prepare for plain morphing 21976 21977 this.value = from; 21978 this.destination = to; 21979 }, 21980 extend: { 21981 at: function at(pos, real) { 21982 return real < 1 ? this.value : this.destination; 21983 }, 21984 valueOf: function valueOf() { 21985 return this.value; 21986 } 21987 } 21988 }); 21989 SVG.extend(SVG.FX, { 21990 // Add animatable attributes 21991 attr: function attr(a, v, relative) { 21992 // apply attributes individually 21993 if (_typeof(a) === 'object') { 21994 for (var key in a) { 21995 this.attr(key, a[key]); 21996 } 21997 } else { 21998 this.add(a, v, 'attrs'); 21999 } 22000 22001 return this; 22002 }, 22003 // Add animatable styles 22004 style: function style(s, v) { 22005 if (_typeof(s) === 'object') { 22006 for (var key in s) { 22007 this.style(key, s[key]); 22008 } 22009 } else { 22010 this.add(s, v, 'styles'); 22011 } 22012 22013 return this; 22014 }, 22015 // Animatable x-axis 22016 x: function x(_x2, relative) { 22017 if (this.target() instanceof SVG.G) { 22018 this.transform({ 22019 x: _x2 22020 }, relative); 22021 return this; 22022 } 22023 22024 var num = new SVG.Number(_x2); 22025 num.relative = relative; 22026 return this.add('x', num); 22027 }, 22028 // Animatable y-axis 22029 y: function y(_y2, relative) { 22030 if (this.target() instanceof SVG.G) { 22031 this.transform({ 22032 y: _y2 22033 }, relative); 22034 return this; 22035 } 22036 22037 var num = new SVG.Number(_y2); 22038 num.relative = relative; 22039 return this.add('y', num); 22040 }, 22041 // Animatable center x-axis 22042 cx: function cx(x) { 22043 return this.add('cx', new SVG.Number(x)); 22044 }, 22045 // Animatable center y-axis 22046 cy: function cy(y) { 22047 return this.add('cy', new SVG.Number(y)); 22048 }, 22049 // Add animatable move 22050 move: function move(x, y) { 22051 return this.x(x).y(y); 22052 }, 22053 // Add animatable center 22054 center: function center(x, y) { 22055 return this.cx(x).cy(y); 22056 }, 22057 // Add animatable size 22058 size: function size(width, height) { 22059 if (this.target() instanceof SVG.Text) { 22060 // animate font size for Text elements 22061 this.attr('font-size', width); 22062 } else { 22063 // animate bbox based size for all other elements 22064 var box; 22065 22066 if (!width || !height) { 22067 box = this.target().bbox(); 22068 } 22069 22070 if (!width) { 22071 width = box.width / box.height * height; 22072 } 22073 22074 if (!height) { 22075 height = box.height / box.width * width; 22076 } 22077 22078 this.add('width', new SVG.Number(width)).add('height', new SVG.Number(height)); 22079 } 22080 22081 return this; 22082 }, 22083 // Add animatable width 22084 width: function width(_width2) { 22085 return this.add('width', new SVG.Number(_width2)); 22086 }, 22087 // Add animatable height 22088 height: function height(_height2) { 22089 return this.add('height', new SVG.Number(_height2)); 22090 }, 22091 // Add animatable plot 22092 plot: function plot(a, b, c, d) { 22093 // Lines can be plotted with 4 arguments 22094 if (arguments.length == 4) { 22095 return this.plot([a, b, c, d]); 22096 } 22097 22098 return this.add('plot', new (this.target().morphArray)(a)); 22099 }, 22100 // Add leading method 22101 leading: function leading(value) { 22102 return this.target().leading ? this.add('leading', new SVG.Number(value)) : this; 22103 }, 22104 // Add animatable viewbox 22105 viewbox: function viewbox(x, y, width, height) { 22106 if (this.target() instanceof SVG.Container) { 22107 this.add('viewbox', new SVG.ViewBox(x, y, width, height)); 22108 } 22109 22110 return this; 22111 }, 22112 update: function update(o) { 22113 if (this.target() instanceof SVG.Stop) { 22114 if (typeof o === 'number' || o instanceof SVG.Number) { 22115 return this.update({ 22116 offset: arguments[0], 22117 color: arguments[1], 22118 opacity: arguments[2] 22119 }); 22120 } 22121 22122 if (o.opacity != null) this.attr('stop-opacity', o.opacity); 22123 if (o.color != null) this.attr('stop-color', o.color); 22124 if (o.offset != null) this.attr('offset', o.offset); 22125 } 22126 22127 return this; 22128 } 22129 });
22130 SVG.Box = SVG.invent({ 22131 create: function create(x, y, width, height) { 22132 if (_typeof(x) === 'object' && !(x instanceof SVG.Element)) { 22133 // chromes getBoundingClientRect has no x and y property 22134 return SVG.Box.call(this, x.left != null ? x.left : x.x, x.top != null ? x.top : x.y, x.width, x.height); 22135 } else if (arguments.length == 4) { 22136 this.x = x; 22137 this.y = y; 22138 this.width = width; 22139 this.height = height; 22140 } // add center, right, bottom... 22141 22142 22143 fullBox(this); 22144 }, 22145 extend: { 22146 // Merge rect box with another, return a new instance 22147 merge: function merge(box) { 22148 var b = new this.constructor(); // merge boxes 22149 22150 b.x = Math.min(this.x, box.x); 22151 b.y = Math.min(this.y, box.y); 22152 b.width = Math.max(this.x + this.width, box.x + box.width) - b.x; 22153 b.height = Math.max(this.y + this.height, box.y + box.height) - b.y; 22154 return fullBox(b); 22155 }, 22156 transform: function transform(m) { 22157 var xMin = Infinity, 22158 xMax = -Infinity, 22159 yMin = Infinity, 22160 yMax = -Infinity, 22161 bbox; 22162 var pts = [new SVG.Point(this.x, this.y), new SVG.Point(this.x2, this.y), new SVG.Point(this.x, this.y2), new SVG.Point(this.x2, this.y2)]; 22163 pts.forEach(function (p) { 22164 p = p.transform(m); 22165 xMin = Math.min(xMin, p.x); 22166 xMax = Math.max(xMax, p.x); 22167 yMin = Math.min(yMin, p.y); 22168 yMax = Math.max(yMax, p.y); 22169 }); 22170 bbox = new this.constructor(); 22171 bbox.x = xMin; 22172 bbox.width = xMax - xMin; 22173 bbox.y = yMin; 22174 bbox.height = yMax - yMin; 22175 fullBox(bbox); 22176 return bbox; 22177 } 22178 } 22179 }); 22180 SVG.BBox = SVG.invent({ 22181 // Initialize 22182 create: function create(element) { 22183 SVG.Box.apply(this, [].slice.call(arguments)); // get values if element is given 22184 22185 if (element instanceof SVG.Element) { 22186 var box; // yes this is ugly, but Firefox can be a pain when it comes to elements that are not yet rendered 22187 22188 try { 22189 if (!document.documentElement.contains) { 22190 // This is IE - it does not support contains() for top-level SVGs 22191 var topParent = element.node; 22192 22193 while (topParent.parentNode) { 22194 topParent = topParent.parentNode; 22195 } 22196 22197 if (topParent != document) throw new Error('Element not in the dom'); 22198 } // the element is NOT in the dom, throw error 22199 // disabling the check below which fixes issue #76 22200 // if (!document.documentElement.contains(element.node)) throw new Exception('Element not in the dom') 22201 // find native bbox 22202 22203 22204 box = element.node.getBBox(); 22205 } catch (e) { 22206 if (element instanceof SVG.Shape) { 22207 if (!SVG.parser.draw) { 22208 // fixes apexcharts/vue-apexcharts #14 22209 SVG.prepare(); 22210 } 22211 22212 var clone = element.clone(SVG.parser.draw.instance).show(); 22213 box = clone.node.getBBox(); 22214 clone.remove(); 22215 } else { 22216 box = { 22217 x: element.node.clientLeft, 22218 y: element.node.clientTop, 22219 width: element.node.clientWidth, 22220 height: element.node.clientHeight 22221 }; 22222 } 22223 } 22224 22225 SVG.Box.call(this, box); 22226 } 22227 }, 22228 // Define ancestor 22229 inherit: SVG.Box, 22230 // Define Parent 22231 parent: SVG.Element, 22232 // Constructor 22233 construct: { 22234 // Get bounding box 22235 bbox: function bbox() { 22236 return new SVG.BBox(this); 22237 } 22238 } 22239 }); 22240 SVG.BBox.prototype.constructor = SVG.BBox; 22241 SVG.extend(SVG.Element, { 22242 tbox: function tbox() { 22243 console.warn('Use of TBox is deprecated and mapped to RBox. Use .rbox() instead.'); 22244 return this.rbox(this.doc()); 22245 } 22246 });
22247 SVG.RBox = SVG.invent({ 22248 // Initialize 22249 create: function create(element) { 22250 SVG.Box.apply(this, [].slice.call(arguments)); 22251 22252 if (element instanceof SVG.Element) { 22253 SVG.Box.call(this, element.node.getBoundingClientRect()); 22254 } 22255 }, 22256 inherit: SVG.Box, 22257 // define Parent 22258 parent: SVG.Element, 22259 extend: { 22260 addOffset: function addOffset() { 22261 // offset by window scroll position, because getBoundingClientRect changes when window is scrolled 22262 this.x += window.pageXOffset; 22263 this.y += window.pageYOffset; 22264 return this; 22265 } 22266 }, 22267 // Constructor 22268 construct: { 22269 // Get rect box 22270 rbox: function rbox(el) { 22271 if (el) return new SVG.RBox(this).transform(el.screenCTM().inverse()); 22272 return new SVG.RBox(this).addOffset(); 22273 } 22274 } 22275 }); 22276 SVG.RBox.prototype.constructor = SVG.RBox; 22277 SVG.Matrix = SVG.invent({ 22278 // Initialize 22279 create: function create(source) { 22280 var i, 22281 base = arrayToMatrix([1, 0, 0, 1, 0, 0]); // ensure source as object 22282 22283 source = source instanceof SVG.Element ? source.matrixify() : typeof source === 'string' ? arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat)) : arguments.length == 6 ? arrayToMatrix([].slice.call(arguments)) : Array.isArray(source) ? arrayToMatrix(source) : _typeof(source) === 'object' ? source : base; // merge source 22284 22285 for (i = abcdef.length - 1; i >= 0; --i) { 22286 this[abcdef[i]] = source[abcdef[i]] != null ? source[abcdef[i]] : base[abcdef[i]]; 22287 } 22288 }, 22289 // Add methods 22290 extend: { 22291 // Extract individual transformations 22292 extract: function extract() { 22293 // find delta transform points 22294 var px = deltaTransformPoint(this, 0, 1), 22295 py = deltaTransformPoint(this, 1, 0), 22296 skewX = 180 / Math.PI * Math.atan2(px.y, px.x) - 90; 22297 return { 22298 // translation 22299 x: this.e, 22300 y: this.f, 22301 transformedX: (this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b), 22302 transformedY: (this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d), 22303 // skew 22304 skewX: -skewX, 22305 skewY: 180 / Math.PI * Math.atan2(py.y, py.x), 22306 // scale 22307 scaleX: Math.sqrt(this.a * this.a + this.b * this.b), 22308 scaleY: Math.sqrt(this.c * this.c + this.d * this.d), 22309 // rotation 22310 rotation: skewX, 22311 a: this.a, 22312 b: this.b, 22313 c: this.c, 22314 d: this.d, 22315 e: this.e, 22316 f: this.f, 22317 matrix: new SVG.Matrix(this) 22318 }; 22319 }, 22320 // Clone matrix 22321 clone: function clone() { 22322 return new SVG.Matrix(this); 22323 }, 22324 // Morph one matrix into another 22325 morph: function morph(matrix) { 22326 // store new destination 22327 this.destination = new SVG.Matrix(matrix); 22328 return this; 22329 }, 22330 // Get morphed matrix at a given position 22331 at: function at(pos) { 22332 // make sure a destination is defined 22333 if (!this.destination) return this; // calculate morphed matrix at a given position 22334 22335 var matrix = new SVG.Matrix({ 22336 a: this.a + (this.destination.a - this.a) * pos, 22337 b: this.b + (this.destination.b - this.b) * pos, 22338 c: this.c + (this.destination.c - this.c) * pos, 22339 d: this.d + (this.destination.d - this.d) * pos, 22340 e: this.e + (this.destination.e - this.e) * pos, 22341 f: this.f + (this.destination.f - this.f) * pos 22342 }); 22343 return matrix; 22344 }, 22345 // Multiplies by given matrix 22346 multiply: function multiply(matrix) {
22347 return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native())); 22348 }, 22349 // Inverses matrix 22350 inverse: function inverse() { 22351 return new SVG.Matrix(this.native().inverse()); 22352 }, 22353 // Translate matrix 22354 translate: function translate(x, y) { 22355 return new SVG.Matrix(this.native().translate(x || 0, y || 0)); 22356 }, 22357 // Scale matrix 22358 scale: function scale(x, y, cx, cy) { 22359 // support uniformal scale 22360 if (arguments.length == 1) { 22361 y = x; 22362 } else if (arguments.length == 3) { 22363 cy = cx; 22364 cx = y; 22365 y = x; 22366 } 22367 22368 return this.around(cx, cy, new SVG.Matrix(x, 0, 0, y, 0, 0)); 22369 }, 22370 // Rotate matrix 22371 rotate: function rotate(r, cx, cy) { 22372 // convert degrees to radians 22373 r = SVG.utils.radians(r); 22374 return this.around(cx, cy, new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0)); 22375 }, 22376 // Flip matrix on x or y, at a given offset 22377 flip: function flip(a, o) { 22378 return a == 'x' ? this.scale(-1, 1, o, 0) : a == 'y' ? this.scale(1, -1, 0, o) : this.scale(-1, -1, a, o != null ? o : a); 22379 }, 22380 // Skew 22381 skew: function skew(x, y, cx, cy) { 22382 // support uniformal skew 22383 if (arguments.length == 1) { 22384 y = x; 22385 } else if (arguments.length == 3) { 22386 cy = cx; 22387 cx = y; 22388 y = x; 22389 } // convert degrees to radians 22390 22391 22392 x = SVG.utils.radians(x); 22393 y = SVG.utils.radians(y); 22394 return this.around(cx, cy, new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0)); 22395 }, 22396 // SkewX 22397 skewX: function skewX(x, cx, cy) { 22398 return this.skew(x, 0, cx, cy); 22399 }, 22400 // SkewY 22401 skewY: function skewY(y, cx, cy) { 22402 return this.skew(0, y, cx, cy); 22403 }, 22404 // Transform around a center point 22405 around: function around(cx, cy, matrix) { 22406 return this.multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0)).multiply(matrix).multiply(new SVG.Matrix(1, 0, 0, 1, -cx || 0, -cy || 0)); 22407 }, 22408 // Convert to native SVGMatrix 22409 native: function native() { 22410 // create new matrix 22411 var matrix = SVG.parser.native.createSVGMatrix(); // update with current values 22412 22413 for (var i = abcdef.length - 1; i >= 0; i--) { 22414 matrix[abcdef[i]] = this[abcdef[i]]; 22415 } 22416 22417 return matrix; 22418 }, 22419 // Convert matrix to string 22420 toString: function toString() { 22421 // Construct the matrix directly, avoid values that are too small 22422 return 'matrix(' + float32String(this.a) + ',' + float32String(this.b) + ',' + float32String(this.c) + ',' + float32String(this.d) + ',' + float32String(this.e) + ',' + float32String(this.f) + ')'; 22423 } 22424 }, 22425 // Define parent 22426 parent: SVG.Element, 22427 // Add parent method 22428 construct: { 22429 // Get current matrix 22430 ctm: function ctm() { 22431 return new SVG.Matrix(this.node.getCTM()); 22432 }, 22433 // Get current screen matrix 22434 screenCTM: function screenCTM() { 22435 /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537 22436 This is needed because FF does not return the transformation matrix 22437 for the inner coordinate system when getScreenCTM() is called on nested svgs. 22438 However all other Browsers do that */ 22439 if (this instanceof SVG.Nested) { 22440 var rect = this.rect(1, 1); 22441 var m = rect.node.getScreenCTM(); 22442 rect.remove(); 22443 return new SVG.Matrix(m); 22444 } 22445 22446 return new SVG.Matrix(this.node.getScreenCTM()); 22447 } 22448 } 22449 }); 22450 SVG.Point = SVG.invent({ 22451 // Initialize 22452 create: function create(x, y) { 22453 var source, 22454 base = { 22455 x: 0, 22456 y: 0 // ensure source as object 22457 22458 }; 22459 source = Array.isArray(x) ? { 22460 x: x[0], 22461 y: x[1] 22462 } : _typeof(x) === 'object' ? { 22463 x: x.x, 22464 y: x.y 22465 } : x != null ? { 22466 x: x, 22467 y: y != null ? y : x 22468 } : base; // If y has no value, then x is used has its value 22469 // merge source 22470 22471 this.x = source.x; 22472 this.y = source.y; 22473 }, 22474 // Add methods 22475 extend: { 22476 // Clone point 22477 clone: function clone() { 22478 return new SVG.Point(this); 22479 }, 22480 // Morph one point into another 22481 morph: function morph(x, y) { 22482 // store new destination 22483 this.destination = new SVG.Point(x, y); 22484 return this; 22485 }, 22486 // Get morphed point at a given position 22487 at: function at(pos) { 22488 // make sure a destination is defined 22489 if (!this.destination) return this; // calculate morphed matrix at a given position 22490 22491 var point = new SVG.Point({ 22492 x: this.x + (this.destination.x - this.x) * pos, 22493 y: this.y + (this.destination.y - this.y) * pos 22494 }); 22495 return point; 22496 }, 22497 // Convert to native SVGPoint 22498 native: function native() { 22499 // create new point
22500 var point = SVG.parser.native.createSVGPoint(); // update with current values 22501 22502 point.x = this.x; 22503 point.y = this.y; 22504 return point; 22505 }, 22506 // transform point with matrix 22507 transform: function transform(matrix) { 22508 return new SVG.Point(this.native().matrixTransform(matrix.native())); 22509 } 22510 } 22511 }); 22512 SVG.extend(SVG.Element, { 22513 // Get point 22514 point: function point(x, y) { 22515 return new SVG.Point(x, y).transform(this.screenCTM().inverse()); 22516 } 22517 }); 22518 SVG.extend(SVG.Element, { 22519 // Set svg element attribute 22520 attr: function attr(a, v, n) { 22521 // act as full getter 22522 if (a == null) { 22523 // get an object of attributes 22524 a = {}; 22525 v = this.node.attributes; 22526 22527 for (n = v.length - 1; n >= 0; n--) { 22528 a[v[n].nodeName] = SVG.regex.isNumber.test(v[n].nodeValue) ? parseFloat(v[n].nodeValue) : v[n].nodeValue; 22529 } 22530 22531 return a; 22532 } else if (_typeof(a) === 'object') { 22533 // apply every attribute individually if an object is passed 22534 for (v in a) { 22535 this.attr(v, a[v]); 22536 } 22537 } else if (v === null) { 22538 // remove value 22539 this.node.removeAttribute(a); 22540 } else if (v == null) { 22541 // act as a getter if the first and only argument is not an object 22542 v = this.node.getAttribute(a); 22543 return v == null ? SVG.defaults.attrs[a] : SVG.regex.isNumber.test(v) ? parseFloat(v) : v; 22544 } else { 22545 // BUG FIX: some browsers will render a stroke if a color is given even though stroke width is 0 22546 if (a == 'stroke-width') { 22547 this.attr('stroke', parseFloat(v) > 0 ? this._stroke : null); 22548 } else if (a == 'stroke') { 22549 this._stroke = v; 22550 } // convert image fill and stroke to patterns 22551 22552 22553 if (a == 'fill' || a == 'stroke') { 22554 if (SVG.regex.isImage.test(v)) { 22555 v = this.doc().defs().image(v, 0, 0); 22556 } 22557 22558 if (v instanceof SVG.Image) { 22559 v = this.doc().defs().pattern(0, 0, function () { 22560 this.add(v); 22561 }); 22562 } 22563 } // ensure correct numeric values (also accepts NaN and Infinity) 22564 22565 22566 if (typeof v === 'number') { 22567 v = new SVG.Number(v); 22568 } // ensure full hex color 22569 else if (SVG.Color.isColor(v)) { 22570 v = new SVG.Color(v); 22571 } // parse array values 22572 else if (Array.isArray(v)) { 22573 v = new SVG.Array(v); 22574 } // if the passed attribute is leading... 22575 22576 22577 if (a == 'leading') { 22578 // ... call the leading method instead 22579 if (this.leading) { 22580 this.leading(v); 22581 } 22582 } else { 22583 // set given attribute on node 22584 typeof n === 'string' ? this.node.setAttributeNS(n, a, v.toString()) : this.node.setAttribute(a, v.toString()); 22585 } // rebuild if required 22586 22587 22588 if (this.rebuild && (a == 'font-size' || a == 'x')) { 22589 this.rebuild(a, v); 22590 } 22591 } 22592 22593 return this; 22594 } 22595 }); 22596 SVG.extend(SVG.Element, { 22597 // Add transformations 22598 transform: function transform(o, relative) { 22599 // get target in case of the fx module, otherwise reference this 22600 var target = this, 22601 matrix, 22602 bbox; // act as a getter 22603 22604 if (_typeof(o) !== 'object') { 22605 // get current matrix 22606 matrix = new SVG.Matrix(target).extract(); 22607 return typeof o === 'string' ? matrix[o] : matrix; 22608 } // get current matrix 22609 22610 22611 matrix = new SVG.Matrix(target); // ensure relative flag 22612 22613 relative = !!relative || !!o.relative; // act on matrix 22614 22615 if (o.a != null) { 22616 matrix = relative // relative 22617 ? matrix.multiply(new SVG.Matrix(o)) // absolute 22618 : new SVG.Matrix(o); // act on rotation 22619 } else if (o.rotation != null) { 22620 // ensure centre point 22621 ensureCentre(o, target); // apply transformation 22622 22623 matrix = relative // relative 22624 ? matrix.rotate(o.rotation, o.cx, o.cy) // absolute 22625 : matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy); // act on scale 22626 } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { 22627 // ensure centre point 22628 ensureCentre(o, target); // ensure scale values on both axes 22629 22630 o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1; 22631 o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1; 22632 22633 if (!relative) { 22634 // absolute; multiply inversed values 22635 var e = matrix.extract(); 22636 o.scaleX = o.scaleX * 1 / e.scaleX; 22637 o.scaleY = o.scaleY * 1 / e.scaleY; 22638 } 22639 22640 matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy); // act on skew 22641 }
22641 else if (o.skew != null || o.skewX != null || o.skewY != null) { 22642 // ensure centre point 22643 ensureCentre(o, target); // ensure skew values on both axes 22644 22645 o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0; 22646 o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0; 22647 22648 if (!relative) { 22649 // absolute; reset skew values 22650 var e = matrix.extract(); 22651 matrix = matrix.multiply(new SVG.Matrix().skew(e.skewX, e.skewY, o.cx, o.cy).inverse()); 22652 } 22653 22654 matrix = matrix.skew(o.skewX, o.skewY, o.cx, o.cy); // act on flip 22655 } else if (o.flip) { 22656 if (o.flip == 'x' || o.flip == 'y') { 22657 o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset; 22658 } else { 22659 if (o.offset == null) { 22660 bbox = target.bbox(); 22661 o.flip = bbox.cx; 22662 o.offset = bbox.cy; 22663 } else { 22664 o.flip = o.offset; 22665 } 22666 } 22667 22668 matrix = new SVG.Matrix().flip(o.flip, o.offset); // act on translate 22669 } else if (o.x != null || o.y != null) { 22670 if (relative) { 22671 // relative 22672 matrix = matrix.translate(o.x, o.y); 22673 } else { 22674 // absolute 22675 if (o.x != null) matrix.e = o.x; 22676 if (o.y != null) matrix.f = o.y; 22677 } 22678 } 22679 22680 return this.attr('transform', matrix); 22681 } 22682 }); 22683 SVG.extend(SVG.FX, { 22684 transform: function transform(o, relative) { 22685 // get target in case of the fx module, otherwise reference this 22686 var target = this.target(), 22687 matrix, 22688 bbox; // act as a getter 22689 22690 if (_typeof(o) !== 'object') { 22691 // get current matrix 22692 matrix = new SVG.Matrix(target).extract(); 22693 return typeof o === 'string' ? matrix[o] : matrix; 22694 } // ensure relative flag 22695 22696 22697 relative = !!relative || !!o.relative; // act on matrix 22698 22699 if (o.a != null) { 22700 matrix = new SVG.Matrix(o); // act on rotation 22701 } else if (o.rotation != null) { 22702 // ensure centre point 22703 ensureCentre(o, target); // apply transformation 22704
22705 matrix = new SVG.Rotate(o.rotation, o.cx, o.cy); // act on scale 22706 } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { 22707 // ensure centre point 22708 ensureCentre(o, target); // ensure scale values on both axes 22709 22710 o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1; 22711 o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1; 22712 matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy); // act on skew 22713 } else if (o.skewX != null || o.skewY != null) { 22714 // ensure centre point 22715 ensureCentre(o, target); // ensure skew values on both axes 22716 22717 o.skewX = o.skewX != null ? o.skewX : 0; 22718 o.skewY = o.skewY != null ? o.skewY : 0; 22719 matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy); // act on flip 22720 } else if (o.flip) { 22721 if (o.flip == 'x' || o.flip == 'y') { 22722 o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset; 22723 } else { 22724 if (o.offset == null) { 22725 bbox = target.bbox(); 22726 o.flip = bbox.cx; 22727 o.offset = bbox.cy; 22728 } else { 22729 o.flip = o.offset; 22730 } 22731 } 22732 22733 matrix = new SVG.Matrix().flip(o.flip, o.offset); // act on translate 22734 } else if (o.x != null || o.y != null) { 22735 matrix = new SVG.Translate(o.x, o.y); 22736 } 22737 22738 if (!matrix) return this; 22739 matrix.relative = relative; 22740 this.last().transforms.push(matrix); 22741 return this._callStart(); 22742 } 22743 }); 22744 SVG.extend(SVG.Element, { 22745 // Reset all transformations 22746 untransform: function untransform() { 22747 return this.attr('transform', null); 22748 }, 22749 // merge the whole transformation chain into one matrix and returns it 22750 matrixify: function matrixify() { 22751 var matrix = (this.attr('transform') || ''). // split transformations 22752 split(SVG.regex.transforms).slice(0, -1).map(function (str) { 22753 // generate key => value pairs 22754 var kv = str.trim().split('('); 22755 return [kv[0], kv[1].split(SVG.regex.delimiter).map(function (str) { 22756 return parseFloat(str); 22757 })]; 22758 }) // merge every transformation into one matrix 22759 .reduce(function (matrix, transform) { 22760 if (transform[0] == 'matrix') return matrix.multiply(arrayToMatrix(transform[1])); 22761 return matrix[transform[0]].apply(matrix, transform[1]); 22762 }, new SVG.Matrix()); 22763 return matrix; 22764 }, 22765 // add an element to another parent without changing the visual representation on the screen 22766 toParent: function toParent(parent) { 22767 if (this == parent) return this; 22768 var ctm = this.screenCTM(); 22769 var pCtm = parent.screenCTM().inverse(); 22770 this.addTo(parent).untransform().transform(pCtm.multiply(ctm)); 22771 return this; 22772 }, 22773 // same as above with parent equals root-svg 22774 toDoc: function toDoc() { 22775 return this.toParent(this.doc()); 22776 } 22777 }); 22778 SVG.Transformation = SVG.invent({ 22779 create: function create(source, inversed) { 22780 if (arguments.length > 1 && typeof inversed !== 'boolean') { 22781 return this.constructor.call(this, [].slice.call(arguments)); 22782 } 22783 22784 if (Array.isArray(source)) { 22785 for (var i = 0, len = this.arguments.length; i < len; ++i) { 22786 this[this.arguments[i]] = source[i]; 22787 } 22788 } else if (_typeof(source) === 'object') { 22789 for (var i = 0, len = this.arguments.length; i < len; ++i) { 22790 this[this.arguments[i]] = source[this.arguments[i]]; 22791 } 22792 } 22793 22794 this.inversed = false; 22795 22796 if (inversed === true) { 22797 this.inversed = true; 22798 } 22799 }, 22800 extend: { 22801 arguments: [], 22802 method: '', 22803 at: function at(pos) { 22804 var params = []; 22805 22806 for (var i = 0, len = this.arguments.length; i < len; ++i) { 22807 params.push(this[this.arguments[i]]); 22808 } 22809
22810 var m = this._undo || new SVG.Matrix(); 22811 m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos); 22812 return this.inversed ? m.inverse() : m; 22813 }, 22814 undo: function undo(o) { 22815 for (var i = 0, len = this.arguments.length; i < len; ++i) { 22816 o[this.arguments[i]] = typeof this[this.arguments[i]] === 'undefined' ? 0 : o[this.arguments[i]]; 22817 } // The method SVG.Matrix.extract which was used before calling this 22818 // method to obtain a value for the parameter o doesn't return a cx and 22819 // a cy so we use the ones that were provided to this object at its creation 22820 22821 22822 o.cx = this.cx; 22823 o.cy = this.cy; 22824 this._undo = new SVG[capitalize(this.method)](o, true).at(1); 22825 return this; 22826 } 22827 } 22828 }); 22829 SVG.Translate = SVG.invent({ 22830 parent: SVG.Matrix, 22831 inherit: SVG.Transformation, 22832 create: function create(source, inversed) { 22833 this.constructor.apply(this, [].slice.call(arguments)); 22834 }, 22835 extend: { 22836 arguments: ['transformedX', 'transformedY'], 22837 method: 'translate' 22838 } 22839 }); 22840 SVG.Rotate = SVG.invent({ 22841 parent: SVG.Matrix, 22842 inherit: SVG.Transformation, 22843 create: function create(source, inversed) { 22844 this.constructor.apply(this, [].slice.call(arguments)); 22845 }, 22846 extend: { 22847 arguments: ['rotation', 'cx', 'cy'], 22848 method: 'rotate', 22849 at: function at(pos) { 22850 var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy); 22851 return this.inversed ? m.inverse() : m; 22852 }, 22853 undo: function undo(o) { 22854 this._undo = o; 22855 return this; 22856 } 22857 } 22858 }); 22859 SVG.Scale = SVG.invent({ 22860 parent: SVG.Matrix, 22861 inherit: SVG.Transformation, 22862 create: function create(source, inversed) { 22863 this.constructor.apply(this, [].slice.call(arguments)); 22864 }, 22865 extend: { 22866 arguments: ['scaleX', 'scaleY', 'cx', 'cy'], 22867 method: 'scale' 22868 } 22869 }); 22870 SVG.Skew = SVG.invent({ 22871 parent: SVG.Matrix, 22872 inherit: SVG.Transformation, 22873 create: function create(source, inversed) { 22874 this.constructor.apply(this, [].slice.call(arguments)); 22875 }, 22876 extend: { 22877 arguments: ['skewX', 'skewY', 'cx', 'cy'], 22878 method: 'skew' 22879 } 22880 }); 22881 SVG.extend(SVG.Element, { 22882 // Dynamic style generator 22883 style: function style(s, v) { 22884 if (arguments.length == 0) { 22885 // get full style 22886 return this.node.style.cssText || ''; 22887 } else if (arguments.length < 2) { 22888 // apply every style individually if an object is passed 22889 if (_typeof(s) === 'object') { 22890 for (v in s) { 22891 this.style(v, s[v]); 22892 } 22893 } else if (SVG.regex.isCss.test(s)) { 22894 // parse css string 22895 s = s.split(/\s*;\s*/) // filter out suffix ; and stuff like ;; 22896 .filter(function (e) { 22897 return !!e; 22898 }).map(function (e) { 22899 return e.split(/\s*:\s*/); 22900 }); // apply every definition individually 22901 22902 while (v = s.pop()) { 22903 this.style(v[0], v[1]); 22904 } 22905 } else { 22906 // act as a getter if the first and only argument is not an object 22907 return this.node.style[camelCase(s)]; 22908 } 22909 } else { 22910 this.node.style[camelCase(s)] = v === null || SVG.regex.isBlank.test(v) ? '' : v; 22911 } 22912 22913 return this; 22914 } 22915 }); 22916 SVG.Parent = SVG.invent({ 22917 // Initialize node 22918 create: function create(element) { 22919 this.constructor.call(this, element); 22920 }, 22921 // Inherit from 22922 inherit: SVG.Element, 22923 // Add class methods 22924 extend: { 22925 // Returns all child elements 22926 children: function children() { 22927 return SVG.utils.map(SVG.utils.filterSVGElements(this.node.childNodes), function (node) { 22928 return SVG.adopt(node); 22929 }); 22930 }, 22931 // Add given element at a position 22932 add: function add(element, i) { 22933 if (i == null) { 22934 this.node.appendChild(element.node); 22935 } else if (element.node != this.node.childNodes[i]) { 22936 this.node.insertBefore(element.node, this.node.childNodes[i]); 22937 } 22938 22939 return this; 22940 }, 22941 // Basically does the same as `add()` but returns the added element instead 22942 put: function put(element, i) { 22943 this.add(element, i); 22944 return element; 22945 }, 22946 // Checks if the given element is a child 22947 has: function has(element) { 22948 return this.index(element) >= 0; 22949 }, 22950 // Gets index of given element 22951 index: function index(element) { 22952 return [].slice.call(this.node.childNodes).indexOf(element.node); 22953 }, 22954 // Get a element at the given index 22955 get: function get(i) { 22956 return SVG.adopt(this.node.childNodes[i]); 22957 }, 22958 // Get first child 22959 first: function first() { 22960 return this.get(0); 22961 }, 22962 // Get the last child 22963 last: function last() { 22964 return this.get(this.node.childNodes.length - 1); 22965 }, 22966 // Iterates over all children and invokes a given block 22967 each: function each(block, deep) { 22968 var i, 22969 il, 22970 children = this.children();
22971 22972 for (i = 0, il = children.length; i < il; i++) { 22973 if (children[i] instanceof SVG.Element) { 22974 block.apply(children[i], [i, children]); 22975 } 22976 22977 if (deep && children[i] instanceof SVG.Container) { 22978 children[i].each(block, deep); 22979 } 22980 } 22981 22982 return this; 22983 }, 22984 // Remove a given child 22985 removeElement: function removeElement(element) { 22986 this.node.removeChild(element.node); 22987 return this; 22988 }, 22989 // Remove all elements in this container 22990 clear: function clear() { 22991 // remove children 22992 while (this.node.hasChildNodes()) { 22993 this.node.removeChild(this.node.lastChild); 22994 } // remove defs reference 22995 22996 22997 delete this._defs; 22998 return this; 22999 }, 23000 // Get defs 23001 defs: function defs() { 23002 return this.doc().defs(); 23003 } 23004 } 23005 }); 23006 SVG.extend(SVG.Parent, { 23007 ungroup: function ungroup(parent, depth) { 23008 if (depth === 0 || this instanceof SVG.Defs || this.node == SVG.parser.draw) return this; 23009 parent = parent || (this instanceof SVG.Doc ? this : this.parent(SVG.Parent)); 23010 depth = depth || Infinity; 23011 this.each(function () { 23012 if (this instanceof SVG.Defs) return this; 23013 if (this instanceof SVG.Parent) return this.ungroup(parent, depth - 1); 23014 return this.toParent(parent); 23015 }); 23016 this.node.firstChild || this.remove(); 23017 return this; 23018 }, 23019 flatten: function flatten(parent, depth) { 23020 return this.ungroup(parent, depth); 23021 } 23022 }); 23023 SVG.Container = SVG.invent({ 23024 // Initialize node 23025 create: function create(element) { 23026 this.constructor.call(this, element); 23027 }, 23028 // Inherit from 23029 inherit: SVG.Parent 23030 }); 23031 SVG.ViewBox = SVG.invent({ 23032 create: function create(source) { 23033 var base = [0, 0, 0, 0]; 23034 var x, 23035 y, 23036 width, 23037 height, 23038 box, 23039 view, 23040 we, 23041 he, 23042 wm = 1, 23043 // width multiplier 23044 hm = 1, 23045 // height multiplier 23046 reg = /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/gi; 23047 23048 if (source instanceof SVG.Element) { 23049 we = source; 23050 he = source; 23051 view = (source.attr('viewBox') || '').match(reg); 23052 box = source.bbox; // get dimensions of current node 23053 23054 width = new SVG.Number(source.width()); 23055 height = new SVG.Number(source.height()); // find nearest non-percentual dimensions 23056 23057 while (width.unit == '%') { 23058 wm *= width.value; 23059 width = new SVG.Number(we instanceof SVG.Doc ? we.parent().offsetWidth : we.parent().width()); 23060 we = we.parent(); 23061 } 23062 23063 while (height.unit == '%') { 23064 hm *= height.value; 23065 height = new SVG.Number(he instanceof SVG.Doc ? he.parent().offsetHeight : he.parent().height()); 23066 he = he.parent(); 23067 } // ensure defaults 23068 23069 23070 this.x = 0; 23071 this.y = 0; 23072 this.width = width * wm; 23073 this.height = height * hm; 23074 this.zoom = 1; 23075 23076 if (view) { 23077 // get width and height from viewbox 23078 x = parseFloat(view[0]); 23079 y = parseFloat(view[1]); 23080 width = parseFloat(view[2]); 23081 height = parseFloat(view[3]); // calculate zoom accoring to viewbox 23082 23083 this.zoom = this.width / this.height > width / height ? this.height / height : this.width / width; // calculate real pixel dimensions on parent SVG.Doc element 23084 23085 this.x = x; 23086 this.y = y; 23087 this.width = width; 23088 this.height = height; 23089 } 23090 } else { 23091 // ensure source as object 23092 source = typeof source === 'string' ? source.match(reg).map(function (el) { 23093 return parseFloat(el); 23094 }) : Array.isArray(source) ? source : _typeof(source) === 'object' ? [source.x, source.y, source.width, source.height] : arguments.length == 4 ? [].slice.call(arguments) : base; 23095 this.x = source[0]; 23096 this.y = source[1]; 23097 this.width = source[2]; 23098 this.height = source[3]; 23099 } 23100 }, 23101 extend: { 23102 toString: function toString() { 23103 return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height; 23104 }, 23105 morph: function morph(x, y, width, height) { 23106 this.destination = new SVG.ViewBox(x, y, width, height); 23107 return this; 23108 }, 23109 at: function at(pos) { 23110 if (!this.destination) return this; 23111 return new SVG.ViewBox([this.x + (this.destination.x - this.x) * pos, this.y + (this.destination.y - this.y) * pos, this.width + (this.destination.width - this.width) * pos, this.height + (this.destination.height - this.height) * pos]
23111); 23112 } 23113 }, 23114 // Define parent 23115 parent: SVG.Container, 23116 // Add parent method 23117 construct: { 23118 // get/set viewbox 23119 viewbox: function viewbox(x, y, width, height) { 23120 if (arguments.length == 0) // act as a getter if there are no arguments 23121 { 23122 return new SVG.ViewBox(this); 23123 } // otherwise act as a setter 23124 23125 23126 return this.attr('viewBox', new SVG.ViewBox(x, y, width, height)); 23127 } 23128 } 23129 }) // Add events to elements 23130 ; 23131 ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove', // , 'mouseenter' -> not supported by IE 23132 // , 'mouseleave' -> not supported by IE 23133 'touchstart', 'touchmove', 'touchleave', 'touchend', 'touchcancel'].forEach(function (event) { 23134 // add event to SVG.Element 23135 SVG.Element.prototype[event] = function (f) { 23136 // bind event to element rather than element node 23137 SVG.on(this.node, event, f); 23138 return this; 23139 }; 23140 }); // Initialize listeners stack 23141 23142 SVG.listeners = []; 23143 SVG.handlerMap = []; 23144 SVG.listenerId = 0; // Add event binder in the SVG namespace 23145 23146 SVG.on = function (node, event, listener, binding, options) { 23147 // create listener, get object-index 23148 var l = listener.bind(binding || node.instance || node), 23149 index = (SVG.handlerMap.indexOf(node) + 1 || SVG.handlerMap.push(node)) - 1, 23150 ev = event.split('.')[0], 23151 ns = event.split('.')[1] || '*'; // ensure valid object 23152 23153 SVG.listeners[index] = SVG.listeners[index] || {}; 23154 SVG.listeners[index][ev] = SVG.listeners[index][ev] || {}; 23155 SVG.listeners[index][ev][ns] = SVG.listeners[index][ev][ns] || {}; 23156 23157 if (!listener._svgjsListenerId) { 23158 listener._svgjsListenerId = ++SVG.listenerId; 23159 } // reference listener 23160 23161 23162 SVG.listeners[index][ev][ns][listener._svgjsListenerId] = l; // add listener 23163 23164 node.addEventListener(ev, l, options || false); 23165 }; // Add event unbinder in the SVG namespace 23166 23167 23168 SVG.off = function (node, event, listener) { 23169 var index = SVG.handlerMap.indexOf(node), 23170 ev = event && event.split('.')[0], 23171 ns = event && event.split('.')[1], 23172 namespace = ''; 23173 if (index == -1) return; 23174 23175 if (listener) { 23176 if (typeof listener === 'function') listener = listener._svgjsListenerId; 23177 if (!listener) return; // remove listener reference 23178 23179 if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns || '*']) { 23180 // remove listener 23181 node.removeEventListener(ev, SVG.listeners[index][ev][ns || '*'][listener], false); 23182 delete SVG.listeners[index][ev][ns || '*'][listener]; 23183 } 23184 } else if (ns && ev) { 23185 // remove all listeners for a namespaced event 23186 if (SVG.listeners[index][ev] && SVG.listeners[index][ev][ns]) { 23187 for (listener in SVG.listeners[index][ev][ns]) { 23188 SVG.off(node, [ev, ns].join('.'), listener); 23189 } 23190 23191 delete SVG.listeners[index][ev][ns]; 23192 } 23193 } else if (ns) { 23194 // remove all listeners for a specific namespace 23195 for (event in SVG.listeners[index]) { 23196 for (namespace in SVG.listeners[index][event]) { 23197 if (ns === namespace) { 23198 SVG.off(node, [event, ns].join('.')); 23199 } 23200 } 23201 } 23202 } else if (ev) { 23203 // remove all listeners for the event 23204 if (SVG.listeners[index][ev]) { 23205 for (namespace in SVG.listeners[index][ev]) { 23206 SVG.off(node, [ev, namespace].join('.')); 23207 } 23208 23209 delete SVG.listeners[index][ev]; 23210 } 23211 } else { 23212 // remove all listeners on a given node 23213 for (event in SVG.listeners[index]) { 23214 SVG.off(node, event); 23215 } 23216 23217 delete SVG.listeners[index]; 23218 delete SVG.handlerMap[index]; 23219 } 23220 }; // 23221 23222 23223 SVG.extend(SVG.Element, { 23224 // Bind given event to listener 23225 on: function on(event, listener, binding, options) { 23226 SVG.on(this.node, event, listener, binding, options); 23227 return this; 23228 }, 23229 // Unbind event from listener 23230 off: function off(event, listener) { 23231 SVG.off(this.node, event, listener); 23232 return this; 23233 }, 23234 // Fire given event 23235 fire: function fire(event, data) { 23236 // Dispatch event 23237 if (event instanceof window.Event) { 23238 this.node.dispatchEvent(event); 23239 } else { 23240 this.node.dispatchEvent(event = new SVG.CustomEvent(event, { 23241 detail: data, 23242 cancelable: true 23243 })); 23244 } 23245 23246 this._event = event; 23247 return this; 23248 }, 23249 event: function event() { 23250 return this._event; 23251 } 23252 });
23253 SVG.Defs = SVG.invent({ 23254 // Initialize node 23255 create: 'defs', 23256 // Inherit from 23257 inherit: SVG.Container 23258 }); 23259 SVG.G = SVG.invent({ 23260 // Initialize node 23261 create: 'g', 23262 // Inherit from 23263 inherit: SVG.Container, 23264 // Add class methods 23265 extend: { 23266 // Move over x-axis 23267 x: function x(_x3) { 23268 return _x3 == null ? this.transform('x') : this.transform({ 23269 x: _x3 - this.x() 23270 }, true); 23271 }, 23272 // Move over y-axis 23273 y: function y(_y3) { 23274 return _y3 == null ? this.transform('y') : this.transform({ 23275 y: _y3 - this.y() 23276 }, true); 23277 }, 23278 // Move by center over x-axis 23279 cx: function cx(x) { 23280 return x == null ? this.gbox().cx : this.x(x - this.gbox().width / 2); 23281 }, 23282 // Move by center over y-axis 23283 cy: function cy(y) { 23284 return y == null ? this.gbox().cy : this.y(y - this.gbox().height / 2); 23285 }, 23286 gbox: function gbox() { 23287 var bbox = this.bbox(), 23288 trans = this.transform(); 23289 bbox.x += trans.x; 23290 bbox.x2 += trans.x; 23291 bbox.cx += trans.x; 23292 bbox.y += trans.y; 23293 bbox.y2 += trans.y; 23294 bbox.cy += trans.y; 23295 return bbox; 23296 } 23297 }, 23298 // Add parent method 23299 construct: { 23300 // Create a group element 23301 group: function group() { 23302 return this.put(new SVG.G()); 23303 } 23304 } 23305 }); 23306 SVG.Doc = SVG.invent({ 23307 // Initialize node 23308 create: function create(element) { 23309 if (element) { 23310 // ensure the presence of a dom element 23311 element = typeof element === 'string' ? document.getElementById(element) : element; // If the target is an svg element, use that element as the main wrapper. 23312 // This allows svg.js to work with svg documents as well. 23313 23314 if (element.nodeName == 'svg') { 23315 this.constructor.call(this, element); 23316 } else { 23317 this.constructor.call(this, SVG.create('svg')); 23318 element.appendChild(this.node); 23319 this.size('100%', '100%'); 23320 } // set svg element attributes and ensure defs node 23321 23322 23323 this.namespace().defs(); 23324 } 23325 }, 23326 // Inherit from 23327 inherit: SVG.Container, 23328 // Add class methods 23329 extend: { 23330 // Add namespaces 23331 namespace: function namespace() { 23332 return this.attr({ 23333 xmlns: SVG.ns, 23334 version: '1.1' 23335 }).attr('xmlns:xlink', SVG.xlink, SVG.xmlns).attr('xmlns:svgjs', SVG.svgjs, SVG.xmlns); 23336 }, 23337 // Creates and returns defs element 23338 defs: function defs() { 23339 if (!this._defs) { 23340 var defs; // Find or create a defs element in this instance 23341 23342 if (defs = this.node.getElementsByTagName('defs')[0]) { 23343 this._defs = SVG.adopt(defs); 23344 } else { 23345 this._defs = new SVG.Defs(); 23346 } // Make sure the defs node is at the end of the stack 23347 23348 23349 this.node.appendChild(this._defs.node); 23350 } 23351 23352 return this._defs; 23353 }, 23354 // custom parent method 23355 parent: function parent() { 23356 if (!this.node.parentNode || this.node.parentNode.nodeName == '#document') return null; 23357 return this.node.parentNode; 23358 }, 23359 // Fix for possible sub-pixel offset. See: 23360 // https://bugzilla.mozilla.org/show_bug.cgi?id=608812 23361 spof: function spof() { 23362 var pos = this.node.getScreenCTM(); 23363 23364 if (pos) { 23365 this.style('left', -pos.e % 1 + 'px').style('top', -pos.f % 1 + 'px'); 23366 } 23367 23368 return this; 23369 }, 23370 // Removes the doc from the DOM 23371 remove: function remove() { 23372 if (this.parent()) { 23373 this.parent().removeChild(this.node); 23374 } 23375 23376 return this; 23377 }, 23378 clear: function clear() { 23379 // remove children 23380 while (this.node.hasChildNodes()) { 23381 this.node.removeChild(this.node.lastChild); 23382 } // remove defs reference 23383 23384 23385 delete this._defs; // add back parser 23386 23387 if (SVG.parser.draw && !SVG.parser.draw.parentNode) { 23388 this.node.appendChild(SVG.parser.draw); 23389 } 23390 23391 return this; 23392 }, 23393 clone: function clone(parent) { 23394 // write dom data to the dom so the clone can pickup the data 23395 this.writeDataToDom(); // get reference to node 23396 23397 var node = this.node; // clone element and assign new id 23398 23399 var clone = assignNewId(node.cloneNode(true)); // insert the clone in the given parent or after myself 23400 23401 if (parent) { 23402 (parent.node || parent).appendChild(clone.node); 23403 } else { 23404 node.parentNode.insertBefore(clone.node, node.nextSibling); 23405 } 23406 23407 return clone; 23408 } 23409 } 23410 }); // ### This module adds backward / forward functionality to elements. 23411 // 23412 23413 SVG.extend(SVG.Element, { 23414 // Get all siblings, including myself 23415 siblings: function siblings() { 23416 return this.parent().children();
23417 }, 23418 // Get the curent position siblings 23419 position: function position() { 23420 return this.parent().index(this); 23421 }, 23422 // Get the next element (will return null if there is none) 23423 next: function next() { 23424 return this.siblings()[this.position() + 1]; 23425 }, 23426 // Get the next element (will return null if there is none) 23427 previous: function previous() { 23428 return this.siblings()[this.position() - 1]; 23429 }, 23430 // Send given element one step forward 23431 forward: function forward() { 23432 var i = this.position() + 1, 23433 p = this.parent(); // move node one step forward 23434 23435 p.removeElement(this).add(this, i); // make sure defs node is always at the top 23436 23437 if (p instanceof SVG.Doc) { 23438 p.node.appendChild(p.defs().node); 23439 } 23440 23441 return this; 23442 }, 23443 // Send given element one step backward 23444 backward: function backward() { 23445 var i = this.position(); 23446 23447 if (i > 0) { 23448 this.parent().removeElement(this).add(this, i - 1); 23449 } 23450 23451 return this; 23452 }, 23453 // Send given element all the way to the front 23454 front: function front() { 23455 var p = this.parent(); // Move node forward 23456 23457 p.node.appendChild(this.node); // Make sure defs node is always at the top 23458 23459 if (p instanceof SVG.Doc) { 23460 p.node.appendChild(p.defs().node); 23461 } 23462 23463 return this; 23464 }, 23465 // Send given element all the way to the back 23466 back: function back() { 23467 if (this.position() > 0) { 23468 this.parent().removeElement(this).add(this, 0); 23469 } 23470 23471 return this; 23472 }, 23473 // Inserts a given element before the targeted element 23474 before: function before(element) { 23475 element.remove(); 23476 var i = this.position(); 23477 this.parent().add(element, i); 23478 return this; 23479 }, 23480 // Insters a given element after the targeted element 23481 after: function after(element) { 23482 element.remove(); 23483 var i = this.position(); 23484 this.parent().add(element, i + 1); 23485 return this; 23486 } 23487 }); 23488 SVG.Mask = SVG.invent({ 23489 // Initialize node 23490 create: function create() { 23491 this.constructor.call(this, SVG.create('mask')); // keep references to masked elements 23492 23493 this.targets = []; 23494 }, 23495 // Inherit from 23496 inherit: SVG.Container, 23497 // Add class methods 23498 extend: { 23499 // Unmask all masked elements and remove itself 23500 remove: function remove() { 23501 // unmask all targets 23502 for (var i = this.targets.length - 1; i >= 0; i--) { 23503 if (this.targets[i]) { 23504 this.targets[i].unmask(); 23505 } 23506 } 23507 23508 this.targets = []; // remove mask from parent 23509 23510 SVG.Element.prototype.remove.call(this); 23511 return this; 23512 } 23513 }, 23514 // Add parent method 23515 construct: { 23516 // Create masking element 23517 mask: function mask() { 23518 return this.defs().put(new SVG.Mask()); 23519 } 23520 } 23521 }); 23522 SVG.extend(SVG.Element, { 23523 // Distribute mask to svg element 23524 maskWith: function maskWith(element) { 23525 // use given mask or create a new one 23526 this.masker = element instanceof SVG.Mask ? element : this.parent().mask().add(element); // store reverence on self in mask 23527 23528 this.masker.targets.push(this); // apply mask 23529 23530 return this.attr('mask', 'url("#' + this.masker.attr('id') + '")'); 23531 }, 23532 // Unmask element 23533 unmask: function unmask() { 23534 delete this.masker; 23535 return this.attr('mask', null); 23536 } 23537 }); 23538 SVG.ClipPath = SVG.invent({ 23539 // Initialize node 23540 create: function create() { 23541 this.constructor.call(this, SVG.create('clipPath')); // keep references to clipped elements 23542 23543 this.targets = []; 23544 }, 23545 // Inherit from 23546 inherit: SVG.Container, 23547 // Add class methods 23548 extend: { 23549 // Unclip all clipped elements and remove itself 23550 remove: function remove() { 23551 // unclip all targets 23552 for (var i = this.targets.length - 1; i >= 0; i--) { 23553 if (this.targets[i]) { 23554 this.targets[i].unclip(); 23555 } 23556 } 23557 23558 this.targets = []; // remove clipPath from parent 23559 23560 this.parent().removeElement(this); 23561 return this; 23562 } 23563 }, 23564 // Add parent method 23565 construct: { 23566 // Create clipping element 23567 clip: function clip() { 23568 return this.defs().put(new SVG.ClipPath()); 23569 } 23570 } 23571 }); // 23572 23573 SVG.extend(SVG.Element, { 23574 // Distribute clipPath to svg element 23575 clipWith: function clipWith(element) { 23576 // use given clip or create a new one 23577 this.clipper = element instanceof SVG.ClipPath ? element : this.parent().clip().add(element); // store reverence on self in mask 23578 23579 this.clipper.targets.push(this); // apply mask 23580 23581 return this.attr('clip-path', 'url("#' + this.clipper.attr('id') + '")'); 23582 }, 23583 // Unclip element 23584 unclip: function unclip() { 23585 delete this.clipper; 23586 return this.attr('clip-path', null); 23587 } 23588 });
23589 SVG.Gradient = SVG.invent({ 23590 // Initialize node 23591 create: function create(type) { 23592 this.constructor.call(this, SVG.create(type + 'Gradient')); // store type 23593 23594 this.type = type; 23595 }, 23596 // Inherit from 23597 inherit: SVG.Container, 23598 // Add class methods 23599 extend: { 23600 // Add a color stop 23601 at: function at(offset, color, opacity) { 23602 return this.put(new SVG.Stop()).update(offset, color, opacity); 23603 }, 23604 // Update gradient 23605 update: function update(block) { 23606 // remove all stops 23607 this.clear(); // invoke passed block 23608 23609 if (typeof block === 'function') { 23610 block.call(this, this); 23611 } 23612 23613 return this; 23614 }, 23615 // Return the fill id 23616 fill: function fill() { 23617 return 'url(#' + this.id() + ')'; 23618 }, 23619 // Alias string convertion to fill 23620 toString: function toString() { 23621 return this.fill(); 23622 }, 23623 // custom attr to handle transform 23624 attr: function attr(a, b, c) { 23625 if (a == 'transform') a = 'gradientTransform'; 23626 return SVG.Container.prototype.attr.call(this, a, b, c); 23627 } 23628 }, 23629 // Add parent method 23630 construct: { 23631 // Create gradient element in defs 23632 gradient: function gradient(type, block) { 23633 return this.defs().gradient(type, block); 23634 } 23635 } 23636 }); // Add animatable methods to both gradient and fx module 23637 23638 SVG.extend(SVG.Gradient, SVG.FX, { 23639 // From position 23640 from: function from(x, y) { 23641 return (this._target || this).type == 'radial' ? this.attr({ 23642 fx: new SVG.Number(x), 23643 fy: new SVG.Number(y) 23644 }) : this.attr({ 23645 x1: new SVG.Number(x), 23646 y1: new SVG.Number(y) 23647 }); 23648 }, 23649 // To position 23650 to: function to(x, y) { 23651 return (this._target || this).type == 'radial' ? this.attr({ 23652 cx: new SVG.Number(x), 23653 cy: new SVG.Number(y) 23654 }) : this.attr({ 23655 x2: new SVG.Number(x), 23656 y2: new SVG.Number(y) 23657 }); 23658 } 23659 }); // Base gradient generation 23660 23661 SVG.extend(SVG.Defs, { 23662 // define gradient 23663 gradient: function gradient(type, block) { 23664 return this.put(new SVG.Gradient(type)).update(block); 23665 } 23666 }); 23667 SVG.Stop = SVG.invent({ 23668 // Initialize node 23669 create: 'stop', 23670 // Inherit from 23671 inherit: SVG.Element, 23672 // Add class methods 23673 extend: { 23674 // add color stops 23675 update: function update(o) { 23676 if (typeof o === 'number' || o instanceof SVG.Number) { 23677 o = { 23678 offset: arguments[0], 23679 color: arguments[1], 23680 opacity: arguments[2] 23681 }; 23682 } // set attributes 23683 23684 23685 if (o.opacity != null) this.attr('stop-opacity', o.opacity); 23686 if (o.color != null) this.attr('stop-color', o.color); 23687 if (o.offset != null) this.attr('offset', new SVG.Number(o.offset)); 23688 return this; 23689 } 23690 } 23691 }); 23692 SVG.Pattern = SVG.invent({ 23693 // Initialize node 23694 create: 'pattern', 23695 // Inherit from 23696 inherit: SVG.Container, 23697 // Add class methods 23698 extend: { 23699 // Return the fill id 23700 fill: function fill() { 23701 return 'url(#' + this.id() + ')'; 23702 }, 23703 // Update pattern by rebuilding 23704 update: function update(block) { 23705 // remove content 23706 this.clear(); // invoke passed block 23707 23708 if (typeof block === 'function') { 23709 block.call(this, this); 23710 } 23711 23712 return this; 23713 }, 23714 // Alias string convertion to fill 23715 toString: function toString() { 23716 return this.fill(); 23717 }, 23718 // custom attr to handle transform 23719 attr: function attr(a, b, c) { 23720 if (a == 'transform') a = 'patternTransform'; 23721 return SVG.Container.prototype.attr.call(this, a, b, c); 23722 } 23723 }, 23724 // Add parent method 23725 construct: { 23726 // Create pattern element in defs 23727 pattern: function pattern(width, height, block) { 23728 return this.defs().pattern(width, height, block); 23729 } 23730 } 23731 });
23732 SVG.extend(SVG.Defs, { 23733 // Define gradient 23734 pattern: function pattern(width, height, block) { 23735 return this.put(new SVG.Pattern()).update(block).attr({ 23736 x: 0, 23737 y: 0, 23738 width: width, 23739 height: height, 23740 patternUnits: 'userSpaceOnUse' 23741 }); 23742 } 23743 }); 23744 SVG.Shape = SVG.invent({ 23745 // Initialize node 23746 create: function create(element) { 23747 this.constructor.call(this, element); 23748 }, 23749 // Inherit from 23750 inherit: SVG.Element 23751 }); 23752 SVG.Bare = SVG.invent({ 23753 // Initialize 23754 create: function create(element, inherit) { 23755 // construct element 23756 this.constructor.call(this, SVG.create(element)); // inherit custom methods 23757 23758 if (inherit) { 23759 for (var method in inherit.prototype) { 23760 if (typeof inherit.prototype[method] === 'function') { 23761 this[method] = inherit.prototype[method]; 23762 } 23763 } 23764 } 23765 }, 23766 // Inherit from 23767 inherit: SVG.Element, 23768 // Add methods 23769 extend: { 23770 // Insert some plain text 23771 words: function words(text) { 23772 // remove contents 23773 while (this.node.hasChildNodes()) { 23774 this.node.removeChild(this.node.lastChild); 23775 } // create text node 23776 23777 23778 this.node.appendChild(document.createTextNode(text)); 23779 return this; 23780 } 23781 } 23782 }); 23783 SVG.extend(SVG.Parent, { 23784 // Create an element that is not described by SVG.js 23785 element: function element(_element, inherit) { 23786 return this.put(new SVG.Bare(_element, inherit)); 23787 } 23788 }); 23789 SVG.Symbol = SVG.invent({ 23790 // Initialize node 23791 create: 'symbol', 23792 // Inherit from 23793 inherit: SVG.Container, 23794 construct: { 23795 // create symbol 23796 symbol: function symbol() { 23797 return this.put(new SVG.Symbol()); 23798 } 23799 } 23800 }); 23801 SVG.Use = SVG.invent({ 23802 // Initialize node 23803 create: 'use', 23804 // Inherit from 23805 inherit: SVG.Shape, 23806 // Add class methods 23807 extend: { 23808 // Use element as a reference 23809 element: function element(_element2, file) { 23810 // Set lined element 23811 return this.attr('href', (file || '') + '#' + _element2, SVG.xlink); 23812 } 23813 }, 23814 // Add parent method 23815 construct: { 23816 // Create a use element 23817 use: function use(element, file) { 23818 return this.put(new SVG.Use()).element(element, file); 23819 } 23820 } 23821 }); 23822 SVG.Rect = SVG.invent({ 23823 // Initialize node 23824 create: 'rect', 23825 // Inherit from 23826 inherit: SVG.Shape, 23827 // Add parent method 23828 construct: { 23829 // Create a rect element 23830 rect: function rect(width, height) { 23831 return this.put(new SVG.Rect()).size(width, height); 23832 } 23833 } 23834 }); 23835 SVG.Circle = SVG.invent({ 23836 // Initialize node 23837 create: 'circle', 23838 // Inherit from 23839 inherit: SVG.Shape, 23840 // Add parent method 23841 construct: { 23842 // Create circle element, based on ellipse 23843 circle: function circle(size) { 23844 return this.put(new SVG.Circle()).rx(new SVG.Number(size).divide(2)).move(0, 0); 23845 } 23846 } 23847 }); 23848 SVG.extend(SVG.Circle, SVG.FX, { 23849 // Radius x value 23850 rx: function rx(_rx) { 23851 return this.attr('r', _rx); 23852 }, 23853 // Alias radius x value 23854 ry: function ry(_ry) { 23855 return this.rx(_ry); 23856 } 23857 }); 23858 SVG.Ellipse = SVG.invent({ 23859 // Initialize node 23860 create: 'ellipse', 23861 // Inherit from 23862 inherit: SVG.Shape, 23863 // Add parent method 23864 construct: { 23865 // Create an ellipse 23866 ellipse: function ellipse(width, height) { 23867 return this.put(new SVG.Ellipse()).size(width, height).move(0, 0); 23868 } 23869 } 23870 }); 23871 SVG.extend(SVG.Ellipse, SVG.Rect, SVG.FX, { 23872 // Radius x value 23873 rx: function rx(_rx2) { 23874 return this.attr('rx', _rx2); 23875 }, 23876 // Radius y value 23877 ry: function ry(_ry2) { 23878 return this.attr('ry', _ry2); 23879 } 23880 }); // Add common method 23881
23882 SVG.extend(SVG.Circle, SVG.Ellipse, { 23883 // Move over x-axis 23884 x: function x(_x4) { 23885 return _x4 == null ? this.cx() - this.rx() : this.cx(_x4 + this.rx()); 23886 }, 23887 // Move over y-axis 23888 y: function y(_y4) { 23889 return _y4 == null ? this.cy() - this.ry() : this.cy(_y4 + this.ry()); 23890 }, 23891 // Move by center over x-axis 23892 cx: function cx(x) { 23893 return x == null ? this.attr('cx') : this.attr('cx', x); 23894 }, 23895 // Move by center over y-axis 23896 cy: function cy(y) { 23897 return y == null ? this.attr('cy') : this.attr('cy', y); 23898 }, 23899 // Set width of element 23900 width: function width(_width3) { 23901 return _width3 == null ? this.rx() * 2 : this.rx(new SVG.Number(_width3).divide(2)); 23902 }, 23903 // Set height of element 23904 height: function height(_height3) { 23905 return _height3 == null ? this.ry() * 2 : this.ry(new SVG.Number(_height3).divide(2)); 23906 }, 23907 // Custom size function 23908 size: function size(width, height) { 23909 var p = proportionalSize(this, width, height); 23910 return this.rx(new SVG.Number(p.width).divide(2)).ry(new SVG.Number(p.height).divide(2)); 23911 } 23912 }); 23913 SVG.Line = SVG.invent({ 23914 // Initialize node 23915 create: 'line', 23916 // Inherit from 23917 inherit: SVG.Shape, 23918 // Add class methods 23919 extend: { 23920 // Get array 23921 array: function array() { 23922 return new SVG.PointArray([[this.attr('x1'), this.attr('y1')], [this.attr('x2'), this.attr('y2')]]); 23923 }, 23924 // Overwrite native plot() method 23925 plot: function plot(x1, y1, x2, y2) { 23926 if (x1 == null) { 23927 return this.array(); 23928 } else if (typeof y1 !== 'undefined') { 23929 x1 = { 23930 x1: x1, 23931 y1: y1, 23932 x2: x2, 23933 y2: y2 23934 }; 23935 } else { 23936 x1 = new SVG.PointArray(x1).toLine(); 23937 } 23938 23939 return this.attr(x1); 23940 }, 23941 // Move by left top corner 23942 move: function move(x, y) { 23943 return this.attr(this.array().move(x, y).toLine()); 23944 }, 23945 // Set element size to given width and height 23946 size: function size(width, height) { 23947 var p = proportionalSize(this, width, height); 23948 return this.attr(this.array().size(p.width, p.height).toLine()); 23949 } 23950 }, 23951 // Add parent method 23952 construct: { 23953 // Create a line element 23954 line: function line(x1, y1, x2, y2) { 23955 // make sure plot is called as a setter 23956 // x1 is not necessarily a number, it can also be an array, a string and a SVG.PointArray 23957 return SVG.Line.prototype.plot.apply(this.put(new SVG.Line()), x1 != null ? [x1, y1, x2, y2] : [0, 0, 0, 0]); 23958 } 23959 } 23960 }); 23961 SVG.Polyline = SVG.invent({ 23962 // Initialize node 23963 create: 'polyline', 23964 // Inherit from 23965 inherit: SVG.Shape, 23966 // Add parent method 23967 construct: { 23968 // Create a wrapped polyline element 23969 polyline: function polyline(p) { 23970 // make sure plot is called as a setter 23971 return this.put(new SVG.Polyline()).plot(p || new SVG.PointArray()); 23972 } 23973 } 23974 }); 23975 SVG.Polygon = SVG.invent({ 23976 // Initialize node 23977 create: 'polygon', 23978 // Inherit from 23979 inherit: SVG.Shape, 23980 // Add parent method 23981 construct: { 23982 // Create a wrapped polygon element 23983 polygon: function polygon(p) { 23984 // make sure plot is called as a setter 23985 return this.put(new SVG.Polygon()).plot(p || new SVG.PointArray()); 23986 } 23987 } 23988 }); // Add polygon-specific functions 23989 23990 SVG.extend(SVG.Polyline, SVG.Polygon, { 23991 // Get array 23992 array: function array() { 23993 return this._array || (this._array = new SVG.PointArray(this.attr('points'))); 23994 }, 23995 // Plot new path 23996 plot: function plot(p) { 23997 return p == null ? this.array() : this.clear().attr('points', typeof p === 'string' ? p : this._array = new SVG.PointArray(p)); 23998 }, 23999 // Clear array cache 24000 clear: function clear() { 24001 delete this._array; 24002 return this; 24003 }, 24004 // Move by left top corner 24005 move: function move(x, y) { 24006 return this.attr('points', this.array().move(x, y)); 24007 }, 24008 // Set element size to given width and height 24009 size: function size(width, height) { 24010 var p = proportionalSize(this, width, height); 24011 return this.attr('points', this.array().size(p.width, p.height)); 24012 } 24013 }); // unify all point to point elements 24014 24015 SVG.extend(SVG.Line, SVG.Polyline, SVG.Polygon, { 24016 // Define morphable array 24017 morphArray: SVG.PointArray, 24018 // Move by left top corner over x-axis 24019 x: function x(_x5) { 24020 return _x5 == null ? this.bbox().x : this.move(_x5, this.bbox().y); 24021 }, 24022 // Move by left top corner over y-axis 24023 y: function y(_y5) { 24024 return _y5 == null ? this.bbox().y : this.move(this.bbox().x, _y5); 24025 }, 24026 // Set width of element 24027 width: function width(_width4) { 24028 var b = this.bbox(); 24029 return _width4 == null ? b.width : this.size(_width4, b.height); 24030 }, 24031 // Set height of element 24032 height: function height(_height4) { 24033 var b = this.bbox(); 24034 return _height4 == null ? b.height : this.size(b.width, _height4); 24035 } 24036 });
24037 SVG.Path = SVG.invent({ 24038 // Initialize node 24039 create: 'path', 24040 // Inherit from 24041 inherit: SVG.Shape, 24042 // Add class methods 24043 extend: { 24044 // Define morphable array 24045 morphArray: SVG.PathArray, 24046 // Get array 24047 array: function array() { 24048 return this._array || (this._array = new SVG.PathArray(this.attr('d'))); 24049 }, 24050 // Plot new path 24051 plot: function plot(d) { 24052 return d == null ? this.array() : this.clear().attr('d', typeof d === 'string' ? d : this._array = new SVG.PathArray(d)); 24053 }, 24054 // Clear array cache 24055 clear: function clear() { 24056 delete this._array; 24057 return this; 24058 }, 24059 // Move by left top corner 24060 move: function move(x, y) { 24061 return this.attr('d', this.array().move(x, y)); 24062 }, 24063 // Move by left top corner over x-axis 24064 x: function x(_x6) { 24065 return _x6 == null ? this.bbox().x : this.move(_x6, this.bbox().y); 24066 }, 24067 // Move by left top corner over y-axis 24068 y: function y(_y6) { 24069 return _y6 == null ? this.bbox().y : this.move(this.bbox().x, _y6); 24070 }, 24071 // Set element size to given width and height 24072 size: function size(width, height) { 24073 var p = proportionalSize(this, width, height); 24074 return this.attr('d', this.array().size(p.width, p.height)); 24075 }, 24076 // Set width of element 24077 width: function width(_width5) { 24078 return _width5 == null ? this.bbox().width : this.size(_width5, this.bbox().height); 24079 }, 24080 // Set height of element 24081 height: function height(_height5) { 24082 return _height5 == null ? this.bbox().height : this.size(this.bbox().width, _height5); 24083 } 24084 }, 24085 // Add parent method 24086 construct: { 24087 // Create a wrapped path element 24088 path: function path(d) { 24089 // make sure plot is called as a setter 24090 return this.put(new SVG.Path()).plot(d || new SVG.PathArray()); 24091 } 24092 } 24093 }); 24094 SVG.Image = SVG.invent({ 24095 // Initialize node 24096 create: 'image', 24097 // Inherit from 24098 inherit: SVG.Shape, 24099 // Add class methods 24100 extend: { 24101 // (re)load image 24102 load: function load(url) { 24103 if (!url) return this; 24104 var self = this, 24105 img = new window.Image(); // preload image 24106 24107 SVG.on(img, 'load', function () { 24108 SVG.off(img); 24109 var p = self.parent(SVG.Pattern); 24110 if (p === null) return; // ensure image size 24111 24112 if (self.width() == 0 && self.height() == 0) { 24113 self.size(img.width, img.height); 24114 } // ensure pattern size if not set 24115 24116 24117 if (p && p.width() == 0 && p.height() == 0) { 24118 p.size(self.width(), self.height()); 24119 } // callback 24120 24121 24122 if (typeof self._loaded === 'function') { 24123 self._loaded.call(self, { 24124 width: img.width, 24125 height: img.height, 24126 ratio: img.width / img.height, 24127 url: url 24128 }); 24129 } 24130 }); 24131 SVG.on(img, 'error', function (e) { 24132 SVG.off(img); 24133 24134 if (typeof self._error === 'function') { 24135 self._error.call(self, e); 24136 } 24137 }); 24138 return this.attr('href', img.src = this.src = url, SVG.xlink); 24139 }, 24140 // Add loaded callback 24141 loaded: function loaded(_loaded) { 24142 this._loaded = _loaded; 24143 return this; 24144 }, 24145 error: function error(_error) { 24146 this._error = _error; 24147 return this; 24148 } 24149 }, 24150 // Add parent method 24151 construct: { 24152 // create image element, load image and set its size 24153 image: function image(source, width, height) { 24154 return this.put(new SVG.Image()).load(source).size(width || 0, height || width || 0); 24155 } 24156 } 24157 });
24158 SVG.Text = SVG.invent({ 24159 // Initialize node 24160 create: function create() { 24161 this.constructor.call(this, SVG.create('text')); 24162 this.dom.leading = new SVG.Number(1.3); // store leading value for rebuilding 24163 24164 this._rebuild = true; // enable automatic updating of dy values 24165 24166 this._build = false; // disable build mode for adding multiple lines 24167 // set default font 24168 24169 this.attr('font-family', SVG.defaults.attrs['font-family']); 24170 }, 24171 // Inherit from 24172 inherit: SVG.Shape, 24173 // Add class methods 24174 extend: { 24175 // Move over x-axis 24176 x: function x(_x7) { 24177 // act as getter 24178 if (_x7 == null) { 24179 return this.attr('x'); 24180 } 24181 24182 return this.attr('x', _x7); 24183 }, 24184 // Move over y-axis 24185 y: function y(_y7) { 24186 var oy = this.attr('y'), 24187 o = typeof oy === 'number' ? oy - this.bbox().y : 0; // act as getter 24188 24189 if (_y7 == null) { 24190 return typeof oy === 'number' ? oy - o : oy; 24191 } 24192 24193 return this.attr('y', typeof _y7.valueOf() === 'number' ? _y7 + o : _y7); 24194 }, 24195 // Move center over x-axis 24196 cx: function cx(x) { 24197 return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2); 24198 }, 24199 // Move center over y-axis 24200 cy: function cy(y) { 24201 return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2); 24202 }, 24203 // Set the text content 24204 text: function text(_text) { 24205 // act as getter 24206 if (typeof _text === 'undefined') { 24207 var _text = ''; 24208 var children = this.node.childNodes; 24209 24210 for (var i = 0, len = children.length; i < len; ++i) { 24211 // add newline if its not the first child and newLined is set to true 24212 if (i != 0 && children[i].nodeType != 3 && SVG.adopt(children[i]).dom.newLined == true) { 24213 _text += '\n'; 24214 } // add content of this node 24215 24216 24217 _text += children[i].textContent; 24218 } 24219 24220 return _text; 24221 } // remove existing content 24222 24223 24224 this.clear().build(true); 24225 24226 if (typeof _text === 'function') { 24227 // call block 24228 _text.call(this, this); 24229 } else { 24230 // store text and make sure text is not blank 24231 _text = _text.split('\n'); // build new lines 24232 24233 for (var i = 0, il = _text.length; i < il; i++) { 24234 this.tspan(_text[i]).newLine(); 24235 } 24236 } // disable build mode and rebuild lines 24237 24238 24239 return this.build(false).rebuild(); 24240 }, 24241 // Set font size 24242 size: function size(_size) { 24243 return this.attr('font-size', _size).rebuild(); 24244 }, 24245 // Set / get leading 24246 leading: function leading(value) { 24247 // act as getter 24248 if (value == null) { 24249 return this.dom.leading; 24250 } // act as setter 24251 24252 24253 this.dom.leading = new SVG.Number(value); 24254 return this.rebuild(); 24255 }, 24256 // Get all the first level lines 24257 lines: function lines() { 24258 var node = (this.textPath && this.textPath() || this).node; // filter tspans and map them to SVG.js instances 24259 24260 var lines = SVG.utils.map(SVG.utils.filterSVGElements(node.childNodes), function (el) { 24261 return SVG.adopt(el); 24262 }); // return an instance of SVG.set 24263 24264 return new SVG.Set(lines); 24265 }, 24266 // Rebuild appearance type 24267 rebuild: function rebuild(_rebuild) { 24268 // store new rebuild flag if given 24269 if (typeof _rebuild === 'boolean') { 24270 this._rebuild = _rebuild; 24271 } // define position of all lines 24272 24273 24274 if (this._rebuild) { 24275 var self = this, 24276 blankLineOffset = 0, 24277 dy = this.dom.leading * new SVG.Number(this.attr('font-size')); 24278 this.lines().each(function () { 24279 if (this.dom.newLined) { 24280 if (!self.textPath()) { 24281 this.attr('x', self.attr('x')); 24282 } 24283 24284 if (this.text() == '\n') { 24285 blankLineOffset += dy; 24286 } else { 24287 this.attr('dy', dy + blankLineOffset); 24288 blankLineOffset = 0; 24289 } 24290 } 24291 }); 24292 this.fire('rebuild'); 24293 } 24294 24295 return this; 24296 }, 24297 // Enable / disable build mode 24298 build: function build(_build) { 24299 this._build = !!_build; 24300 return this; 24301 }, 24302 // overwrite method from parent to set data properly 24303 setData: function setData(o) { 24304 this.dom = o; 24305 this.dom.leading = new SVG.Number(o.leading || 1.3); 24306 return this; 24307 } 24308 }, 24309 // Add parent method 24310 construct: { 24311 // Create text element 24312 text: function text(_text2) { 24313 return this.put(new SVG.Text()).text(_text2); 24314 }, 24315 // Create plain text element 24316 plain: function plain(text) { 24317 return this.put(new SVG.Text()).plain(text); 24318 } 24319 } 24320 });
24321 SVG.Tspan = SVG.invent({ 24322 // Initialize node 24323 create: 'tspan', 24324 // Inherit from 24325 inherit: SVG.Shape, 24326 // Add class methods 24327 extend: { 24328 // Set text content 24329 text: function text(_text3) { 24330 if (_text3 == null) return this.node.textContent + (this.dom.newLined ? '\n' : ''); 24331 typeof _text3 === 'function' ? _text3.call(this, this) : this.plain(_text3); 24332 return this; 24333 }, 24334 // Shortcut dx 24335 dx: function dx(_dx) { 24336 return this.attr('dx', _dx); 24337 }, 24338 // Shortcut dy 24339 dy: function dy(_dy) { 24340 return this.attr('dy', _dy); 24341 }, 24342 // Create new line 24343 newLine: function newLine() { 24344 // fetch text parent 24345 var t = this.parent(SVG.Text); // mark new line 24346 24347 this.dom.newLined = true; // apply new hy¡n 24348 24349 return this.dy(t.dom.leading * t.attr('font-size')).attr('x', t.x()); 24350 } 24351 } 24352 }); 24353 SVG.extend(SVG.Text, SVG.Tspan, { 24354 // Create plain text node 24355 plain: function plain(text) { 24356 // clear if build mode is disabled 24357 if (this._build === false) { 24358 this.clear(); 24359 } // create text node 24360 24361 24362 this.node.appendChild(document.createTextNode(text)); 24363 return this; 24364 }, 24365 // Create a tspan 24366 tspan: function tspan(text) { 24367 var node = (this.textPath && this.textPath() || this).node, 24368 tspan = new SVG.Tspan(); // clear if build mode is disabled 24369 24370 if (this._build === false) { 24371 this.clear(); 24372 } // add new tspan 24373 24374 24375 node.appendChild(tspan.node); 24376 return tspan.text(text); 24377 }, 24378 // Clear all lines 24379 clear: function clear() { 24380 var node = (this.textPath && this.textPath() || this).node; // remove existing child nodes 24381 24382 while (node.hasChildNodes()) { 24383 node.removeChild(node.lastChild); 24384 } 24385 24386 return this; 24387 }, 24388 // Get length of text element 24389 length: function length() { 24390 return this.node.getComputedTextLength(); 24391 } 24392 }); 24393 SVG.TextPath = SVG.invent({ 24394 // Initialize node 24395 create: 'textPath', 24396 // Inherit from 24397 inherit: SVG.Parent, 24398 // Define parent class 24399 parent: SVG.Text, 24400 // Add parent method 24401 construct: { 24402 morphArray: SVG.PathArray, 24403 // Create path for text to run on 24404 path: function path(d) { 24405 // create textPath element 24406 var path = new SVG.TextPath(), 24407 track = this.doc().defs().path(d); // move lines to textpath 24408 24409 while (this.node.hasChildNodes()) { 24410 path.node.appendChild(this.node.firstChild); 24411 } // add textPath element as child node 24412 24413 24414 this.node.appendChild(path.node); // link textPath to path and add content 24415 24416 path.attr('href', '#' + track, SVG.xlink); 24417 return this; 24418 }, 24419 // return the array of the path track element 24420 array: function array() { 24421 var track = this.track(); 24422 return track ? track.array() : null; 24423 }, 24424 // Plot path if any 24425 plot: function plot(d) { 24426 var track = this.track(), 24427 pathArray = null; 24428 24429 if (track) { 24430 pathArray = track.plot(d); 24431 } 24432 24433 return d == null ? pathArray : this; 24434 }, 24435 // Get the path track element 24436 track: function track() { 24437 var path = this.textPath(); 24438 24439 if (path) { 24440 return path.reference('href'); 24441 } 24442 }, 24443 // Get the textPath child 24444 textPath: function textPath() { 24445 if (this.node.firstChild && this.node.firstChild.nodeName == 'textPath') { 24446 return SVG.adopt(this.node.firstChild); 24447 } 24448 } 24449 } 24450 }); 24451 SVG.Nested = SVG.invent({ 24452 // Initialize node 24453 create: function create() { 24454 this.constructor.call(this, SVG.create('svg')); 24455 this.style('overflow', 'visible'); 24456 }, 24457 // Inherit from 24458 inherit: SVG.Container, 24459 // Add parent method 24460 construct: { 24461 // Create nested svg document 24462 nested: function nested() { 24463 return this.put(new SVG.Nested()); 24464 } 24465 } 24466 });
24467 SVG.A = SVG.invent({ 24468 // Initialize node 24469 create: 'a', 24470 // Inherit from 24471 inherit: SVG.Container, 24472 // Add class methods 24473 extend: { 24474 // Link url 24475 to: function to(url) { 24476 return this.attr('href', url, SVG.xlink); 24477 }, 24478 // Link show attribute 24479 show: function show(target) { 24480 return this.attr('show', target, SVG.xlink); 24481 }, 24482 // Link target attribute 24483 target: function target(_target2) { 24484 return this.attr('target', _target2); 24485 } 24486 }, 24487 // Add parent method 24488 construct: { 24489 // Create a hyperlink element 24490 link: function link(url) { 24491 return this.put(new SVG.A()).to(url); 24492 } 24493 } 24494 }); 24495 SVG.extend(SVG.Element, { 24496 // Create a hyperlink element 24497 linkTo: function linkTo(url) { 24498 var link = new SVG.A(); 24499 24500 if (typeof url === 'function') { 24501 url.call(link, link); 24502 } else { 24503 link.to(url); 24504 } 24505 24506 return this.parent().put(link).put(this); 24507 } 24508 }); 24509 SVG.Marker = SVG.invent({ 24510 // Initialize node 24511 create: 'marker', 24512 // Inherit from 24513 inherit: SVG.Container, 24514 // Add class methods 24515 extend: { 24516 // Set width of element 24517 width: function width(_width6) { 24518 return this.attr('markerWidth', _width6); 24519 }, 24520 // Set height of element 24521 height: function height(_height6) { 24522 return this.attr('markerHeight', _height6); 24523 }, 24524 // Set marker refX and refY 24525 ref: function ref(x, y) { 24526 return this.attr('refX', x).attr('refY', y); 24527 }, 24528 // Update marker 24529 update: function update(block) { 24530 // remove all content 24531 this.clear(); // invoke passed block 24532 24533 if (typeof block === 'function') { 24534 block.call(this, this); 24535 } 24536 24537 return this; 24538 }, 24539 // Return the fill id 24540 toString: function toString() { 24541 return 'url(#' + this.id() + ')'; 24542 } 24543 }, 24544 // Add parent method 24545 construct: { 24546 marker: function marker(width, height, block) { 24547 // Create marker element in defs 24548 return this.defs().marker(width, height, block); 24549 } 24550 } 24551 }); 24552 SVG.extend(SVG.Defs, { 24553 // Create marker 24554 marker: function marker(width, height, block) { 24555 // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto 24556 return this.put(new SVG.Marker()).size(width, height).ref(width / 2, height / 2).viewbox(0, 0, width, height).attr('orient', 'auto').update(block); 24557 } 24558 }); 24559 SVG.extend(SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path, { 24560 // Create and attach markers 24561 marker: function marker(_marker, width, height, block) { 24562 var attr = ['marker']; // Build attribute name 24563 24564 if (_marker != 'all') attr.push(_marker); 24565 attr = attr.join('-'); // Set marker attribute 24566 24567 _marker = arguments[1] instanceof SVG.Marker ? arguments[1] : this.doc().marker(width, height, block); 24568 return this.attr(attr, _marker); 24569 } 24570 }); // Define list of available attributes for stroke and fill 24571 24572 var sugar = { 24573 stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'], 24574 fill: ['color', 'opacity', 'rule'], 24575 prefix: function prefix(t, a) { 24576 return a == 'color' ? t : t + '-' + a; 24577 } // Add sugar for fill and stroke 24578 24579 }; 24580 ['fill', 'stroke'].forEach(function (m) { 24581 var i, 24582 extension = {}; 24583 24584 extension[m] = function (o) { 24585 if (typeof o === 'undefined') { 24586 return this; 24587 } 24588 24589 if (typeof o === 'string' || SVG.Color.isRgb(o) || o && typeof o.fill === 'function') { 24590 this.attr(m, o); 24591 } else // set all attributes from sugar.fill and sugar.stroke list 24592 { 24593 for (i = sugar[m].length - 1; i >= 0; i--) { 24594 if (o[sugar[m][i]] != null) { 24595 this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]]); 24596 } 24597 } 24598 } 24599 24600 return this; 24601 }; 24602 24603 SVG.extend(SVG.Element, SVG.FX, extension); 24604 });
24605 SVG.extend(SVG.Element, SVG.FX, { 24606 // Map rotation to transform 24607 rotate: function rotate(d, cx, cy) { 24608 return this.transform({ 24609 rotation: d, 24610 cx: cx, 24611 cy: cy 24612 }); 24613 }, 24614 // Map skew to transform 24615 skew: function skew(x, y, cx, cy) { 24616 return arguments.length == 1 || arguments.length == 3 ? this.transform({ 24617 skew: x, 24618 cx: y, 24619 cy: cx 24620 }) : this.transform({ 24621 skewX: x, 24622 skewY: y, 24623 cx: cx, 24624 cy: cy 24625 }); 24626 }, 24627 // Map scale to transform 24628 scale: function scale(x, y, cx, cy) { 24629 return arguments.length == 1 || arguments.length == 3 ? this.transform({ 24630 scale: x, 24631 cx: y, 24632 cy: cx 24633 }) : this.transform({ 24634 scaleX: x, 24635 scaleY: y, 24636 cx: cx, 24637 cy: cy 24638 }); 24639 }, 24640 // Map translate to transform 24641 translate: function translate(x, y) { 24642 return this.transform({ 24643 x: x, 24644 y: y 24645 }); 24646 }, 24647 // Map flip to transform 24648 flip: function flip(a, o) { 24649 o = typeof a === 'number' ? a : o; 24650 return this.transform({ 24651 flip: a || 'both', 24652 offset: o 24653 }); 24654 }, 24655 // Map matrix to transform 24656 matrix: function matrix(m) { 24657 return this.attr('transform', new SVG.Matrix(arguments.length == 6 ? [].slice.call(arguments) : m)); 24658 }, 24659 // Opacity 24660 opacity: function opacity(value) { 24661 return this.attr('opacity', value); 24662 }, 24663 // Relative move over x axis 24664 dx: function dx(x) { 24665 return this.x(new SVG.Number(x).plus(this instanceof SVG.FX ? 0 : this.x()), true); 24666 }, 24667 // Relative move over y axis 24668 dy: function dy(y) { 24669 return this.y(new SVG.Number(y).plus(this instanceof SVG.FX ? 0 : this.y()), true); 24670 }, 24671 // Relative move over x and y axes 24672 dmove: function dmove(x, y) { 24673 return this.dx(x).dy(y); 24674 } 24675 }); 24676 SVG.extend(SVG.Rect, SVG.Ellipse, SVG.Circle, SVG.Gradient, SVG.FX, { 24677 // Add x and y radius 24678 radius: function radius(x, y) { 24679 var type = (this._target || this).type; 24680 return type == 'radial' || type == 'circle' ? this.attr('r', new SVG.Number(x)) : this.rx(x).ry(y == null ? x : y); 24681 } 24682 }); 24683 SVG.extend(SVG.Path, { 24684 // Get path length 24685 length: function length() { 24686 return this.node.getTotalLength(); 24687 }, 24688 // Get point at length 24689 pointAt: function pointAt(length) { 24690 return this.node.getPointAtLength(length); 24691 } 24692 }); 24693 SVG.extend(SVG.Parent, SVG.Text, SVG.Tspan, SVG.FX, { 24694 // Set font 24695 font: function font(a, v) { 24696 if (_typeof(a) === 'object') { 24697 for (v in a) { 24698 this.font(v, a[v]); 24699 } 24700 } 24701 24702 return a == 'leading' ? this.leading(v) : a == 'anchor' ? this.attr('text-anchor', v) : a == 'size' || a == 'family' || a == 'weight' || a == 'stretch' || a == 'variant' || a == 'style' ? this.attr('font-' + a, v) : this.attr(a, v); 24703 } 24704 }); 24705 SVG.Set = SVG.invent({ 24706 // Initialize 24707 create: function create(members) { 24708 // Set initial state 24709 Array.isArray(members) ? this.members = members : this.clear(); 24710 }, 24711 // Add class methods 24712 extend: { 24713 // Add element to set 24714 add: function add() { 24715 var i, 24716 il, 24717 elements = [].slice.call(arguments); 24718 24719 for (i = 0, il = elements.length; i < il; i++) { 24720 this.members.push(elements[i]); 24721 } 24722 24723 return this; 24724 }, 24725 // Remove element from set 24726 remove: function remove(element) { 24727 var i = this.index(element); // remove given child 24728 24729 if (i > -1) { 24730 this.members.splice(i, 1); 24731 } 24732 24733 return this; 24734 }, 24735 // Iterate over all members 24736 each: function each(block) { 24737 for (var i = 0, il = this.members.length; i < il; i++) { 24738 block.apply(this.members[i], [i, this.members]); 24739 } 24740 24741 return this; 24742 }, 24743 // Restore to defaults 24744 clear: function clear() { 24745 // initialize store 24746 this.members = []; 24747 return this; 24748 }, 24749 // Get the length of a set 24750 length: function length() { 24751 return this.members.length; 24752 }, 24753 // Checks if a given element is present in set 24754 has: function has(element) { 24755 return this.index(element) >= 0; 24756 }, 24757 // retuns index of given element in set 24758 index: function index(element) { 24759 return this.members.indexOf(element); 24760 }, 24761 // Get member at given index 24762 get: function get(i) { 24763 return this.members[i]; 24764 }, 24765 // Get first member 24766 first: function first() { 24767 return this.get(0); 24768 }, 24769 // Get last member 24770 last: function last() { 24771 return this.get(this.members.length - 1); 24772 }, 24773 // Default value
24774 valueOf: function valueOf() { 24775 return this.members; 24776 }, 24777 // Get the bounding box of all members included or empty box if set has no items 24778 bbox: function bbox() { 24779 // return an empty box of there are no members 24780 if (this.members.length == 0) { 24781 return new SVG.RBox(); 24782 } // get the first rbox and update the target bbox 24783 24784 24785 var rbox = this.members[0].rbox(this.members[0].doc()); 24786 this.each(function () { 24787 // user rbox for correct position and visual representation 24788 rbox = rbox.merge(this.rbox(this.doc())); 24789 }); 24790 return rbox; 24791 } 24792 }, 24793 // Add parent method 24794 construct: { 24795 // Create a new set 24796 set: function set(members) { 24797 return new SVG.Set(members); 24798 } 24799 } 24800 }); 24801 SVG.FX.Set = SVG.invent({ 24802 // Initialize node 24803 create: function create(set) { 24804 // store reference to set 24805 this.set = set; 24806 } 24807 }); // Alias methods 24808 24809 SVG.Set.inherit = function () { 24810 var m, 24811 methods = []; // gather shape methods 24812 24813 for (var m in SVG.Shape.prototype) { 24814 if (typeof SVG.Shape.prototype[m] === 'function' && typeof SVG.Set.prototype[m] !== 'function') { 24815 methods.push(m); 24816 } 24817 } // apply shape aliasses 24818 24819 24820 methods.forEach(function (method) { 24821 SVG.Set.prototype[method] = function () { 24822 for (var i = 0, il = this.members.length; i < il; i++) { 24823 if (this.members[i] && typeof this.members[i][method] === 'function') { 24824 this.members[i][method].apply(this.members[i], arguments); 24825 } 24826 } 24827 24828 return method == 'animate' ? this.fx || (this.fx = new SVG.FX.Set(this)) : this; 24829 }; 24830 }); // clear methods for the next round 24831 24832 methods = []; // gather fx methods 24833 24834 for (var m in SVG.FX.prototype) { 24835 if (typeof SVG.FX.prototype[m] === 'function' && typeof SVG.FX.Set.prototype[m] !== 'function') { 24836 methods.push(m); 24837 } 24838 } // apply fx aliasses 24839 24840 24841 methods.forEach(function (method) { 24842 SVG.FX.Set.prototype[method] = function () { 24843 for (var i = 0, il = this.set.members.length; i < il; i++) { 24844 this.set.members[i].fx[method].apply(this.set.members[i].fx, arguments); 24845 } 24846 24847 return this; 24848 }; 24849 }); 24850 }; 24851 24852 SVG.extend(SVG.Element, { 24853 // Store data values on svg nodes 24854 data: function data(a, v, r) { 24855 if (_typeof(a) === 'object') { 24856 for (v in a) { 24857 this.data(v, a[v]); 24858 } 24859 } else if (arguments.length < 2) { 24860 try { 24861 return JSON.parse(this.attr('data-' + a)); 24862 } catch (e) { 24863 return this.attr('data-' + a); 24864 } 24865 } else { 24866 this.attr('data-' + a, v === null ? null : r === true || typeof v === 'string' || typeof v === 'number' ? v : JSON.stringify(v)); 24867 } 24868 24869 return this; 24870 } 24871 }); 24872 SVG.extend(SVG.Element, { 24873 // Remember arbitrary data 24874 remember: function remember(k, v) { 24875 // remember every item in an object individually 24876 if (_typeof(arguments[0]) === 'object') { 24877 for (var v in k) { 24878 this.remember(v, k[v]); 24879 } 24880 } // retrieve memory 24881 else if (arguments.length == 1) { 24882 return this.memory()[k]; 24883 } // store memory 24884 else { 24885 this.memory()[k] = v; 24886 } 24887 24888 return this; 24889 }, 24890 // Erase a given memory 24891 forget: function forget() { 24892 if (arguments.length == 0) { 24893 this._memory = {}; 24894 } else { 24895 for (var i = arguments.length - 1; i >= 0; i--) { 24896 delete this.memory()[arguments[i]]; 24897 } 24898 } 24899 24900 return this; 24901 }, 24902 // Initialize or return local memory object 24903 memory: function memory() { 24904 return this._memory || (this._memory = {}); 24905 } 24906 }); // Method for getting an element by id 24907 24908 SVG.get = function (id) { 24909 var node = document.getElementById(idFromReference(id) || id); 24910 return SVG.adopt(node); 24911 }; // Select elements by query string 24912 24913 24914 SVG.select = function (query, parent) { 24915 return new SVG.Set(SVG.utils.map((parent || document).querySelectorAll(query), function (node) { 24916 return SVG.adopt(node); 24917 })); 24918 }; 24919 24920 SVG.extend(SVG.Parent, { 24921 // Scoped select method 24922 select: function select(query) { 24923 return SVG.select(query, this.node); 24924 } 24925 });
24926 24927 function pathRegReplace(a, b, c, d) { 24928 return c + d.replace(SVG.regex.dots, ' .'); 24929 } // creates deep clone of array 24930 24931 24932 function array_clone(arr) { 24933 var clone = arr.slice(0); 24934 24935 for (var i = clone.length; i--;) { 24936 if (Array.isArray(clone[i])) { 24937 clone[i] = array_clone(clone[i]); 24938 } 24939 } 24940 24941 return clone; 24942 } // tests if a given element is instance of an object 24943 24944 24945 function _is(el, obj) { 24946 return el instanceof obj; 24947 } // tests if a given selector matches an element 24948 24949 24950 function _matches(el, selector) { 24951 return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); 24952 } // Convert dash-separated-string to camelCase 24953 24954 24955 function camelCase(s) { 24956 return s.toLowerCase().replace(/-(.)/g, function (m, g) { 24957 return g.toUpperCase(); 24958 }); 24959 } // Capitalize first letter of a string 24960 24961 24962 function capitalize(s) { 24963 return s.charAt(0).toUpperCase() + s.slice(1); 24964 } // Ensure to six-based hex 24965 24966 24967 function fullHex(hex) { 24968 return hex.length == 4 ? ['#', hex.substring(1, 2), hex.substring(1, 2), hex.substring(2, 3), hex.substring(2, 3), hex.substring(3, 4), hex.substring(3, 4)].join('') : hex; 24969 } // Component to hex value 24970 24971 24972 function compToHex(comp) { 24973 var hex = comp.toString(16); 24974 return hex.length == 1 ? '0' + hex : hex; 24975 } // Calculate proportional width and height values when necessary 24976 24977 24978 function proportionalSize(element, width, height) { 24979 if (width == null || height == null) { 24980 var box = element.bbox(); 24981 24982 if (width == null) { 24983 width = box.width / box.height * height; 24984 } else if (height == null) { 24985 height = box.height / box.width * width; 24986 } 24987 } 24988 24989 return { 24990 width: width, 24991 height: height 24992 }; 24993 } // Delta transform point 24994 24995 24996 function deltaTransformPoint(matrix, x, y) { 24997 return { 24998 x: x * matrix.a + y * matrix.c + 0, 24999 y: x * matrix.b + y * matrix.d + 0 25000 }; 25001 } // Map matrix array to object 25002 25003 25004 function arrayToMatrix(a) { 25005 return { 25006 a: a[0], 25007 b: a[1], 25008 c: a[2], 25009 d: a[3], 25010 e: a[4], 25011 f: a[5] 25012 }; 25013 } // Parse matrix if required 25014 25015 25016 function parseMatrix(matrix) { 25017 if (!(matrix instanceof SVG.Matrix)) { 25018 matrix = new SVG.Matrix(matrix); 25019 } 25020 25021 return matrix; 25022 } // Add centre point to transform object 25023 25024 25025 function ensureCentre(o, target) { 25026 o.cx = o.cx == null ? target.bbox().cx : o.cx; 25027 o.cy = o.cy == null ? target.bbox().cy : o.cy; 25028 } // PathArray Helpers 25029 25030 25031 function arrayToString(a) { 25032 for (var i = 0, il = a.length, s = ''; i < il; i++) { 25033 s += a[i][0]; 25034 25035 if (a[i][1] != null) { 25036 s += a[i][1]; 25037 25038 if (a[i][2] != null) { 25039 s += ' '; 25040 s += a[i][2]; 25041 25042 if (a[i][3] != null) { 25043 s += ' '; 25044 s += a[i][3]; 25045 s += ' '; 25046 s += a[i][4]; 25047 25048 if (a[i][5] != null) { 25049 s += ' '; 25050 s += a[i][5]; 25051 s += ' '; 25052 s += a[i][6]; 25053 25054 if (a[i][7] != null) { 25055 s += ' '; 25056 s += a[i][7]; 25057 } 25058 } 25059 } 25060 } 25061 } 25062 } 25063 25064 return s + ' '; 25065 } // Deep new id assignment 25066 25067 25068 function assignNewId(node) { 25069 // do the same for SVG child nodes as well 25070 for (var i = node.childNodes.length - 1; i >= 0; i--) { 25071 if (node.childNodes[i] instanceof window.SVGElement) { 25072 assignNewId(node.childNodes[i]); 25073 } 25074 } 25075 25076 return SVG.adopt(node).id(SVG.eid(node.nodeName)); 25077 } // Add more bounding box properties 25078 25079 25080 function fullBox(b) { 25081 if (b.x == null) { 25082 b.x = 0; 25083 b.y = 0; 25084 b.width = 0; 25085 b.height = 0; 25086 } 25087 25088 b.w = b.width; 25089 b.h = b.height; 25090 b.x2 = b.x + b.width;
25091 b.y2 = b.y + b.height; 25092 b.cx = b.x + b.width / 2; 25093 b.cy = b.y + b.height / 2; 25094 return b; 25095 } // Get id from reference string 25096 25097 25098 function idFromReference(url) { 25099 var m = (url || '').toString().match(SVG.regex.reference); 25100 if (m) return m[1]; 25101 } // If values like 1e-88 are passed, this is not a valid 32 bit float, 25102 // but in those cases, we are so close to 0 that 0 works well! 25103 25104 25105 function float32String(v) { 25106 return Math.abs(v) > 1e-37 ? v : 0; 25107 } // Create matrix array for looping 25108 25109 25110 var abcdef = 'abcdef'.split(''); // Add CustomEvent to IE9 and IE10 25111 25112 if (typeof window.CustomEvent !== 'function') { 25113 // Code from: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent 25114 var CustomEventPoly = function CustomEventPoly(event, options) { 25115 options = options || { 25116 bubbles: false, 25117 cancelable: false, 25118 detail: undefined 25119 }; 25120 var e = document.createEvent('CustomEvent'); 25121 e.initCustomEvent(event, options.bubbles, options.cancelable, options.detail); 25122 return e; 25123 }; 25124 25125 CustomEventPoly.prototype = window.Event.prototype; 25126 SVG.CustomEvent = CustomEventPoly; 25127 } else { 25128 SVG.CustomEvent = window.CustomEvent; 25129 } // requestAnimationFrame / cancelAnimationFrame Polyfill with fallback based on Paul Irish 25130 25131 25132 (function (w) { 25133 var lastTime = 0; 25134 var vendors = ['moz', 'webkit']; 25135 25136 for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 25137 w.requestAnimationFrame = w[vendors[x] + 'RequestAnimationFrame']; 25138 w.cancelAnimationFrame = w[vendors[x] + 'CancelAnimationFrame'] || w[vendors[x] + 'CancelRequestAnimationFrame']; 25139 } 25140 25141 w.requestAnimationFrame = w.requestAnimationFrame || function (callback) { 25142 var currTime = new Date().getTime(); 25143 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 25144 var id = w.setTimeout(function () { 25145 callback(currTime + timeToCall); 25146 }, timeToCall); 25147 lastTime = currTime + timeToCall; 25148 return id; 25149 }; 25150 25151 w.cancelAnimationFrame = w.cancelAnimationFrame || w.clearTimeout; 25152 })(window); 25153 25154 return SVG; 25155 }); 25156 25157 /*! svg.filter.js - v2.0.2 - 2016-02-24 25158 * https://github.com/wout/svg.filter.js 25159 * Copyright (c) 2016 Wout Fierens; Licensed MIT */ 25160 (function() { 25161 25162 // Main filter class 25163 SVG.Filter = SVG.invent({ 25164 create: 'filter', 25165 inherit: SVG.Parent, 25166 extend: { 25167 // Static strings 25168 source: 'SourceGraphic', 25169 sourceAlpha: 'SourceAlpha', 25170 background: 'BackgroundImage', 25171 backgroundAlpha: 'BackgroundAlpha', 25172 fill: 'FillPaint', 25173 stroke: 'StrokePaint', 25174 25175 autoSetIn: true, 25176 // Custom put method for leaner code 25177 put: function(element, i) { 25178 this.add(element, i); 25179 25180 if(!element.attr('in') && this.autoSetIn){ 25181 element.attr('in',this.source); 25182 } 25183 if(!element.attr('result')){ 25184 element.attr('result',element); 25185 } 25186 25187 return element 25188 }, 25189 // Blend effect 25190 blend: function(in1, in2, mode) { 25191 return this.put(new SVG.BlendEffect(in1, in2, mode)) 25192 }, 25193 // ColorMatrix effect 25194 colorMatrix: function(type, values) { 25195 return this.put(new SVG.ColorMatrixEffect(type, values)) 25196 }, 25197 // ConvolveMatrix effect 25198 convolveMatrix: function(matrix) { 25199 return this.put(new SVG.ConvolveMatrixEffect(matrix)) 25200 }, 25201 // ComponentTransfer effect 25202 componentTransfer: function(components) { 25203 return this.put(new SVG.ComponentTransferEffect(components)) 25204 }, 25205 // Composite effect 25206 composite: function(in1, in2, operator) { 25207 return this.put(new SVG.CompositeEffect(in1, in2, operator)) 25208 }, 25209 // Flood effect 25210 flood: function(color, opacity) { 25211 return this.put(new SVG.FloodEffect(color, opacity)) 25212 }, 25213 // Offset effect 25214 offset: function(x, y) { 25215 return this.put(new SVG.OffsetEffect(x,y)) 25216 }, 25217 // Image effect 25218 image: function(src) {
25219 return this.put(new SVG.ImageEffect(src)) 25220 }, 25221 // Merge effect 25222 merge: function() { 25223 //pass the array of arguments to the constructor because we dont know if the user gave us an array as the first arguemnt or wether they listed the effects in the arguments 25224 var args = [undefined]; 25225 for(var i in arguments) args.push(arguments[i]); 25226 return this.put(new (SVG.MergeEffect.bind.apply(SVG.MergeEffect,args))) 25227 }, 25228 // Gaussian Blur effect 25229 gaussianBlur: function(x,y) { 25230 return this.put(new SVG.GaussianBlurEffect(x,y)) 25231 }, 25232 // Morphology effect 25233 morphology: function(operator,radius){ 25234 return this.put(new SVG.MorphologyEffect(operator,radius)) 25235 }, 25236 // DiffuseLighting effect 25237 diffuseLighting: function(surfaceScale,diffuseConstant,kernelUnitLength){ 25238 return this.put(new SVG.DiffuseLightingEffect(surfaceScale,diffuseConstant,kernelUnitLength)) 25239 }, 25240 // DisplacementMap effect 25241 displacementMap: function(in1,in2,scale,xChannelSelector,yChannelSelector){ 25242 return this.put(new SVG.DisplacementMapEffect(in1,in2,scale,xChannelSelector,yChannelSelector)) 25243 }, 25244 // SpecularLighting effect 25245 specularLighting: function(surfaceScale,diffuseConstant,specularExponent,kernelUnitLength){ 25246 return this.put(new SVG.SpecularLightingEffect(surfaceScale,diffuseConstant,specularExponent,kernelUnitLength)) 25247 }, 25248 // Tile effect 25249 tile: function(){ 25250 return this.put(new SVG.TileEffect()); 25251 }, 25252 // Turbulence effect 25253 turbulence: function(baseFrequency,numOctaves,seed,stitchTiles,type){ 25254 return this.put(new SVG.TurbulenceEffect(baseFrequency,numOctaves,seed,stitchTiles,type)) 25255 }, 25256 // Default string value 25257 toString: function() { 25258 return 'url(#' + this.attr('id') + ')' 25259 } 25260 } 25261 }); 25262 25263 //add .filter function 25264 SVG.extend(SVG.Defs, { 25265 // Define filter 25266 filter: function(block) { 25267 var filter = this.put(new SVG.Filter); 25268 25269 /* invoke passed block */ 25270 if (typeof block === 'function') 25271 block.call(filter, filter); 25272 25273 return filter 25274 } 25275 }); 25276 SVG.extend(SVG.Container, { 25277 // Define filter on defs 25278 filter: function(block) { 25279 return this.defs().filter(block) 25280 } 25281 }); 25282 SVG.extend(SVG.Element, SVG.G, SVG.Nested, { 25283 // Create filter element in defs and store reference 25284 filter: function(block) { 25285 this.filterer = block instanceof SVG.Element ? 25286 block : this.doc().filter(block); 25287 25288 if(this.doc() && this.filterer.doc() !== this.doc()){ 25289 this.doc().defs().add(this.filterer); 25290 } 25291 25292 this.attr('filter', this.filterer); 25293 25294 return this.filterer 25295 }, 25296 // Remove filter 25297 unfilter: function(remove) { 25298 /* also remove the filter node */ 25299 if (this.filterer && remove === true) 25300 this.filterer.remove(); 25301 25302 /* delete reference to filterer */ 25303 delete this.filterer; 25304 25305 /* remove filter attribute */ 25306 return this.attr('filter', null) 25307 } 25308 }); 25309 25310 // Create SVG.Effect class 25311 SVG.Effect = SVG.invent({ 25312 create: function(){ 25313 this.constructor.call(this); 25314 }, 25315 inherit: SVG.Element, 25316 extend: { 25317 // Set in attribute 25318 in: function(effect) { 25319 return effect == null? this.parent() && this.parent().select('[result="'+this.attr('in')+'"]').get(0) || this.attr('in') : this.attr('in', effect) 25320 }, 25321 // Named result 25322 result: function(result) { 25323 return result == null? this.attr('result') : this.attr('result',result) 25324 }, 25325 // Stringification 25326 toString: function() { 25327 return this.result() 25328 } 25329 } 25330 }); 25331 25332 // create class for parent effects like merge 25333 // Inherit from SVG.Parent 25334 SVG.ParentEffect = SVG.invent({ 25335 create: function(){ 25336 this.constructor.call(this); 25337 }, 25338 inherit: SVG.Parent, 25339 extend: { 25340 // Set in attribute 25341 in: function(effect) { 25342 return effect == null? this.parent() && this.parent().select('[result="'+this.attr('in')+'"]').get(0) || this.attr('in') : this.attr('in', effect) 25343 }, 25344 // Named result 25345 result: function(result) { 25346 return result == null? this.attr('result') : this.attr('result',result) 25347 }, 25348 // Stringification 25349 toString: function() { 25350 return this.result() 25351 } 25352 } 25353 });
25354 25355 //chaining 25356 var chainingEffects = { 25357 // Blend effect 25358 blend: function(in2, mode) { 25359 return this.parent() && this.parent().blend(this, in2, mode) //pass this as the first input 25360 }, 25361 // ColorMatrix effect 25362 colorMatrix: function(type, values) { 25363 return this.parent() && this.parent().colorMatrix(type, values).in(this) 25364 }, 25365 // ConvolveMatrix effect 25366 convolveMatrix: function(matrix) { 25367 return this.parent() && this.parent().convolveMatrix(matrix).in(this) 25368 }, 25369 // ComponentTransfer effect 25370 componentTransfer: function(components) { 25371 return this.parent() && this.parent().componentTransfer(components).in(this) 25372 }, 25373 // Composite effect 25374 composite: function(in2, operator) { 25375 return this.parent() && this.parent().composite(this, in2, operator) //pass this as the first input 25376 }, 25377 // Flood effect 25378 flood: function(color, opacity) { 25379 return this.parent() && this.parent().flood(color, opacity) //this effect dont have inputs 25380 }, 25381 // Offset effect 25382 offset: function(x, y) { 25383 return this.parent() && this.parent().offset(x,y).in(this) 25384 }, 25385 // Image effect 25386 image: function(src) { 25387 return this.parent() && this.parent().image(src) //this effect dont have inputs 25388 }, 25389 // Merge effect 25390 merge: function() { 25391 return this.parent() && this.parent().merge.apply(this.parent(),[this].concat(arguments)) //pass this as the first argument 25392 }, 25393 // Gaussian Blur effect 25394 gaussianBlur: function(x,y) { 25395 return this.parent() && this.parent().gaussianBlur(x,y).in(this) 25396 }, 25397 // Morphology effect 25398 morphology: function(operator,radius){ 25399 return this.parent() && this.parent().morphology(operator,radius).in(this) 25400 }, 25401 // DiffuseLighting effect 25402 diffuseLighting: function(surfaceScale,diffuseConstant,kernelUnitLength){ 25403 return this.parent() && this.parent().diffuseLighting(surfaceScale,diffuseConstant,kernelUnitLength).in(this) 25404 }, 25405 // DisplacementMap effect 25406 displacementMap: function(in2,scale,xChannelSelector,yChannelSelector){ 25407 return this.parent() && this.parent().displacementMap(this,in2,scale,xChannelSelector,yChannelSelector) //pass this as the first input 25408 }, 25409 // SpecularLighting effect 25410 specularLighting: function(surfaceScale,diffuseConstant,specularExponent,kernelUnitLength){ 25411 return this.parent() && this.parent().specularLighting(surfaceScale,diffuseConstant,specularExponent,kernelUnitLength).in(this) 25412 }, 25413 // Tile effect 25414 tile: function(){ 25415 return this.parent() && this.parent().tile().in(this) 25416 }, 25417 // Turbulence effect 25418 turbulence: function(baseFrequency,numOctaves,seed,stitchTiles,type){ 25419 return this.parent() && this.parent().turbulence(baseFrequency,numOctaves,seed,stitchTiles,type).in(this) 25420 } 25421 }; 25422 SVG.extend(SVG.Effect,chainingEffects); 25423 SVG.extend(SVG.ParentEffect,chainingEffects); 25424 25425 //crea class for child effects, like MergeNode, FuncR and lights 25426 SVG.ChildEffect = SVG.invent({ 25427 create: function(){ 25428 this.constructor.call(this); 25429 }, 25430 inherit: SVG.Element, 25431 extend: { 25432 in: function(effect){ 25433 this.attr('in',effect); 25434 } 25435 //dont include any "result" functions because these types of nodes dont have them 25436 } 25437 }); 25438 25439 // Create all different effects 25440 var effects = { 25441 blend: function(in1,in2,mode){ 25442 this.attr({ 25443 in: in1, 25444 in2: in2, 25445 mode: mode || 'normal' 25446 }); 25447 }, 25448 colorMatrix: function(type,values){ 25449 if (type == 'matrix') 25450 values = normaliseMatrix(values); 25451 25452 this.attr({ 25453 type: type 25454 , values: typeof values == 'undefined' ? null : values 25455 }); 25456 }, 25457 convolveMatrix: function(matrix){ 25458 matrix = normaliseMatrix(matrix); 25459 25460 this.attr({ 25461 order: Math.sqrt(matrix.split(' ').length) 25462 , kernelMatrix: matrix 25463 }); 25464 }, 25465 composite: function(in1, in2, operator){ 25466 this.attr({ 25467 in: in1, 25468 in2: in2, 25469 operator: operator 25470 }); 25471 }, 25472 flood: function(color,opacity){ 25473 this.attr('flood-color',color); 25474 if(opacity != null) this.attr('flood-opacity',opacity); 25475 }, 25476 offset: function(x,y){ 25477 this.attr({ 25478 dx: x, 25479 dy: y 25480 }); 25481 }, 25482 image: function(src){ 25483 this.attr('href', src, SVG.xlink); 25484 }, 25485 displacementMap: function(in1,in2,scale,xChannelSelector,yChannelSelector){ 25486 this.attr({ 25487 in: in1, 25488 in2: in2, 25489 scale: scale, 25490 xChannelSelector: xChannelSelector, 25491 yChannelSelector: yChannelSelector 25492 }); 25493 }, 25494 gaussianBlur: function(x,y){ 25495 if(x != null || y != null) 25496 this.attr('stdDeviation', listString(Array.prototype.slice.call(arguments))); 25497 else 25498 this.attr('stdDeviation', '0 0'); 25499 }, 25500 morphology: function(operator,radius){ 25501 this.attr({ 25502 operator: operator, 25503 radius: radius 25504 }); 25505 }, 25506 tile: function(){ 25507 25508 }, 25509 turbulence: function(baseFrequency,numOctaves,seed,stitchTiles,type){ 25510 this.attr({ 25511 numOctaves: numOctaves, 25512 seed: seed, 25513 stitchTiles: stitchTiles, 25514 baseFrequency: baseFrequency, 25515 type: type 25516 }); 25517 } 25518 }; 25519 25520 // Create all parent effects 25521 var parentEffects = { 25522 merge: function(){ 25523 var children; 25524 25525 //test to see if we have a set 25526 if(arguments[0] instanceof SVG.Set){ 25527 var that = this; 25528 arguments[0].each(function(i){ 25529 if(this instanceof SVG.MergeNode) 25530 that.put(this); 25531 else if(this instanceof SVG.Effect || this instanceof SVG.ParentEffect) 25532 that.put(new SVG.MergeNode(this)); 25533 }); 25534 } 25535 else{ 25536 //if the first argument is an array use it 25537 if(Array.isArray(arguments[0])) 25538 children = arguments[0]; 25539 else 25540 children = arguments; 25541 25542 for(var i = 0; i < children.length; i++){ 25543 if(children[i] instanceof SVG.MergeNode){ 25544 this.put(children[i]); 25545 } 25546 else this.put(new SVG.MergeNode(children[i])); 25547 } 25548 } 25549 }, 25550 componentTransfer: function(compontents){ 25551 /* create rgb set */ 25552 this.rgb = new SVG.Set 25553 25554 /* create components */ 25555 ;
25555(['r', 'g', 'b', 'a']).forEach(function(c) { 25556 /* create component */ 25557 this[c] = new SVG['Func' + c.toUpperCase()]('identity'); 25558 25559 /* store component in set */ 25560 this.rgb.add(this[c]); 25561 25562 /* add component node */ 25563 this.node.appendChild(this[c].node); 25564 }.bind(this)); //lost context in foreach 25565 25566 /* set components */ 25567 if (compontents) { 25568 if (compontents.rgb) { 25569 (['r', 'g', 'b']).forEach(function(c) { 25570 this[c].attr(compontents.rgb); 25571 }.bind(this)); 25572 25573 delete compontents.rgb; 25574 } 25575 25576 /* set individual components */ 25577 for (var c in compontents) 25578 this[c].attr(compontents[c]); 25579 } 25580 }, 25581 diffuseLighting: function(surfaceScale,diffuseConstant,kernelUnitLength){ 25582 this.attr({ 25583 surfaceScale: surfaceScale, 25584 diffuseConstant: diffuseConstant, 25585 kernelUnitLength: kernelUnitLength 25586 }); 25587 }, 25588 specularLighting: function(surfaceScale,diffuseConstant,specularExponent,kernelUnitLength){ 25589 this.attr({ 25590 surfaceScale: surfaceScale, 25591 diffuseConstant: diffuseConstant, 25592 specularExponent: specularExponent, 25593 kernelUnitLength: kernelUnitLength 25594 }); 25595 }, 25596 }; 25597 25598 // Create child effects like PointLight and MergeNode 25599 var childEffects = { 25600 distantLight: function(azimuth, elevation){ 25601 this.attr({ 25602 azimuth: azimuth, 25603 elevation: elevation 25604 }); 25605 }, 25606 pointLight: function(x,y,z){ 25607 this.attr({ 25608 x: x, 25609 y: y, 25610 z: z 25611 }); 25612 }, 25613 spotLight: function(x,y,z,pointsAtX,pointsAtY,pointsAtZ){ 25614 this.attr({ 25615 x: x, 25616 y: y, 25617 z: z, 25618 pointsAtX: pointsAtX, 25619 pointsAtY: pointsAtY, 25620 pointsAtZ: pointsAtZ 25621 }); 25622 }, 25623 mergeNode: function(in1){ 25624 this.attr('in',in1); 25625 } 25626 } 25627 25628 // Create compontent functions 25629 ;(['r', 'g', 'b', 'a']).forEach(function(c) { 25630 /* create class */ 25631 childEffects['Func' + c.toUpperCase()] = function(type) { 25632 this.attr('type',type); 25633 25634 // take diffent arguments based on the type 25635 switch(type){ 25636 case 'table': 25637 this.attr('tableValues',arguments[1]); 25638 break 25639 case 'linear': 25640 this.attr('slope',arguments[1]); 25641 this.attr('intercept',arguments[2]); 25642 break 25643 case 'gamma': 25644 this.attr('amplitude',arguments[1]); 25645 this.attr('exponent',arguments[2]); 25646 this.attr('offset',arguments[2]); 25647 break 25648 } 25649 }; 25650 }); 25651 25652 //create effects 25653 foreach(effects,function(effect,i){ 25654 25655 /* capitalize name */ 25656 var name = i.charAt(0).toUpperCase() + i.slice(1); 25657 var proto = {}; 25658 25659 /* create class */ 25660 SVG[name + 'Effect'] = SVG.invent({ 25661 create: function() { 25662 //call super 25663 this.constructor.call(this, SVG.create('fe' + name)); 25664 25665 //call constructor for this effect 25666 effect.apply(this,arguments); 25667 25668 //set the result 25669 this.result(this.attr('id') + 'Out'); 25670 }, 25671 inherit: SVG.Effect, 25672 extend: proto 25673 }); 25674 }); 25675 25676 //create parent effects 25677 foreach(parentEffects,function(effect,i){ 25678 25679 /* capitalize name */ 25680 var name = i.charAt(0).toUpperCase() + i.slice(1); 25681 var proto = {}; 25682 25683 /* create class */ 25684 SVG[name + 'Effect'] = SVG.invent({ 25685 create: function() { 25686 //call super 25687 this.constructor.call(this, SVG.create('fe' + name)); 25688 25689 //call constructor for this effect 25690 effect.apply(this,arguments); 25691 25692 //set the result 25693 this.result(this.attr('id') + 'Out'); 25694 }, 25695 inherit: SVG.ParentEffect, 25696 extend: proto 25697 }); 25698 }); 25699 25700 //create child effects 25701 foreach(childEffects,function(effect,i){ 25702 25703 /* capitalize name */ 25704 var name = i.charAt(0).toUpperCase() + i.slice(1); 25705 var proto = {}; 25706 25707 /* create class */ 25708 SVG[name] = SVG.invent({ 25709 create: function() { 25710 //call super 25711 this.constructor.call(this, SVG.create('fe' + name)); 25712 25713 //call constructor for this effect 25714 effect.apply(this,arguments); 25715 }, 25716 inherit: SVG.ChildEffect, 25717 extend: proto 25718 }); 25719 });
25720 25721 // Effect-specific extensions 25722 SVG.extend(SVG.MergeEffect,{ 25723 in: function(effect){ 25724 if(effect instanceof SVG.MergeNode) 25725 this.add(effect,0); 25726 else 25727 this.add(new SVG.MergeNode(effect),0); 25728 25729 return this 25730 } 25731 }); 25732 SVG.extend(SVG.CompositeEffect,SVG.BlendEffect,SVG.DisplacementMapEffect,{ 25733 in2: function(effect){ 25734 return effect == null? this.parent() && this.parent().select('[result="'+this.attr('in2')+'"]').get(0) || this.attr('in2') : this.attr('in2', effect) 25735 } 25736 }); 25737 25738 // Presets 25739 SVG.filter = { 25740 sepiatone: [ .343, .669, .119, 0, 0 25741 , .249, .626, .130, 0, 0 25742 , .172, .334, .111, 0, 0 25743 , .000, .000, .000, 1, 0 ] 25744 }; 25745 25746 // Helpers 25747 function normaliseMatrix(matrix) { 25748 /* convert possible array value to string */ 25749 if (Array.isArray(matrix)) 25750 matrix = new SVG.Array(matrix); 25751 25752 /* ensure there are no leading, tailing or double spaces */ 25753 return matrix.toString().replace(/^\s+/, '').replace(/\s+$/, '').replace(/\s+/g, ' ') 25754 } 25755 25756 function listString(list) { 25757 if (!Array.isArray(list)) 25758 return list 25759 25760 for (var i = 0, l = list.length, s = []; i < l; i++) 25761 s.push(list[i]); 25762 25763 return s.join(' ') 25764 } 25765 25766 function foreach(){ //loops through mutiple objects 25767 var fn = function(){}; 25768 if(typeof arguments[arguments.length-1] == 'function'){ 25769 fn = arguments[arguments.length-1]; 25770 Array.prototype.splice.call(arguments,arguments.length-1,1); 25771 } 25772 for(var k in arguments){ 25773 for(var i in arguments[k]){ 25774 fn(arguments[k][i],i,arguments[k]); 25775 } 25776 } 25777 } 25778 25779 }).call(undefined); 25780 25781 (function() { 25782 25783 SVG.extend(SVG.PathArray, { 25784 morph: function(array) { 25785 25786 var startArr = this.value 25787 , destArr = this.parse(array); 25788 25789 var startOffsetM = 0 25790 , destOffsetM = 0; 25791 25792 var startOffsetNextM = false 25793 , destOffsetNextM = false; 25794 25795 while(true){ 25796 // stop if there is no M anymore 25797 if(startOffsetM === false && destOffsetM === false) break 25798 25799 // find the next M in path array 25800 startOffsetNextM = findNextM(startArr, startOffsetM === false ? false : startOffsetM+1); 25801 destOffsetNextM = findNextM( destArr, destOffsetM === false ? false : destOffsetM+1); 25802 25803 // We have to add one M to the startArray 25804 if(startOffsetM === false){ 25805 var bbox = new SVG.PathArray(result.start).bbox(); 25806 25807 // when the last block had no bounding box we simply take the first M we got 25808 if(bbox.height == 0 || bbox.width == 0){ 25809 startOffsetM = startArr.push(startArr[0]) - 1; 25810 }else{ 25811 // we take the middle of the bbox instead when we got one 25812 startOffsetM = startArr.push( ['M', bbox.x + bbox.width/2, bbox.y + bbox.height/2 ] ) - 1; 25813 } 25814 } 25815 25816 // We have to add one M to the destArray 25817 if( destOffsetM === false){ 25818 var bbox = new SVG.PathArray(result.dest).bbox(); 25819 25820 if(bbox.height == 0 || bbox.width == 0){ 25821 destOffsetM = destArr.push(destArr[0]) - 1; 25822 }else{ 25823 destOffsetM = destArr.push( ['M', bbox.x + bbox.width/2, bbox.y + bbox.height/2 ] ) - 1; 25824 } 25825 } 25826 25827 // handle block from M to next M 25828 var result = handleBlock(startArr, startOffsetM, startOffsetNextM, destArr, destOffsetM, destOffsetNextM); 25829 25830 // update the arrays to their new values 25831 startArr = startArr.slice(0, startOffsetM).concat(result.start, startOffsetNextM === false ? [] : startArr.slice(startOffsetNextM)); 25832 destArr = destArr.slice(0, destOffsetM).concat(result.dest , destOffsetNextM === false ? [] : destArr.slice( destOffsetNextM)); 25833 25834 // update offsets 25835 startOffsetM = startOffsetNextM === false ? false : startOffsetM + result.start.length;
25836 destOffsetM = destOffsetNextM === false ? false : destOffsetM + result.dest.length; 25837 25838 } 25839 25840 // copy back arrays 25841 this.value = startArr; 25842 this.destination = new SVG.PathArray(); 25843 this.destination.value = destArr; 25844 25845 return this 25846 } 25847 }); 25848 25849 25850 25851 // sorry for the long declaration 25852 // slices out one block (from M to M) and syncronize it so the types and length match 25853 function handleBlock(startArr, startOffsetM, startOffsetNextM, destArr, destOffsetM, destOffsetNextM, undefined){ 25854 25855 // slice out the block we need 25856 var startArrTemp = startArr.slice(startOffsetM, startOffsetNextM || undefined) 25857 , destArrTemp = destArr.slice( destOffsetM, destOffsetNextM || undefined); 25858 25859 var i = 0 25860 , posStart = {pos:[0,0], start:[0,0]} 25861 , posDest = {pos:[0,0], start:[0,0]}; 25862 25863 do{ 25864 25865 // convert shorthand types to long form 25866 startArrTemp[i] = simplyfy.call(posStart, startArrTemp[i]); 25867 destArrTemp[i] = simplyfy.call(posDest , destArrTemp[i]); 25868 25869 // check if both shape types match 25870 // 2 elliptical arc curve commands ('A'), are considered different if the 25871 // flags (large-arc-flag, sweep-flag) don't match 25872 if(startArrTemp[i][0] != destArrTemp[i][0] || startArrTemp[i][0] == 'M' || 25873 (startArrTemp[i][0] == 'A' && 25874 (startArrTemp[i][4] != destArrTemp[i][4] || startArrTemp[i][5] != destArrTemp[i][5]) 25875 ) 25876 ) { 25877 25878 // if not, convert shapes to beziere 25879 Array.prototype.splice.apply(startArrTemp, [i, 1].concat(toBeziere.call(posStart, startArrTemp[i]))); 25880 Array.prototype.splice.apply(destArrTemp, [i, 1].concat(toBeziere.call(posDest, destArrTemp[i]))); 25881 25882 } else { 25883 25884 // only update positions otherwise 25885 startArrTemp[i] = setPosAndReflection.call(posStart, startArrTemp[i]); 25886 destArrTemp[i] = setPosAndReflection.call(posDest , destArrTemp[i]); 25887 25888 } 25889 25890 // we are at the end at both arrays. stop here 25891 if(++i == startArrTemp.length && i == destArrTemp.length) break 25892 25893 // destArray is longer. Add one element 25894 if(i == startArrTemp.length){ 25895 startArrTemp.push([ 25896 'C', 25897 posStart.pos[0], 25898 posStart.pos[1], 25899 posStart.pos[0], 25900 posStart.pos[1], 25901 posStart.pos[0], 25902 posStart.pos[1], 25903 ]); 25904 } 25905 25906 // startArr is longer. Add one element 25907 if(i == destArrTemp.length){ 25908 destArrTemp.push([ 25909 'C', 25910 posDest.pos[0], 25911 posDest.pos[1], 25912 posDest.pos[0], 25913 posDest.pos[1], 25914 posDest.pos[0], 25915 posDest.pos[1] 25916 ]); 25917 } 25918 25919 25920 }while(true) 25921 25922 // return the updated block 25923 return {start:startArrTemp, dest:destArrTemp} 25924 } 25925 25926 // converts shorthand types to long form 25927 function simplyfy(val){ 25928 25929 switch(val[0]){ 25930 case 'z': // shorthand line to start 25931 case 'Z': 25932 val[0] = 'L'; 25933 val[1] = this.start[0]; 25934 val[2] = this.start[1]; 25935 break 25936 case 'H': // shorthand horizontal line 25937 val[0] = 'L'; 25938 val[2] = this.pos[1]; 25939 break 25940 case 'V': // shorthand vertical line 25941 val[0] = 'L'; 25942 val[2] = val[1]; 25943 val[1] = this.pos[0]; 25944 break 25945 case 'T': // shorthand quadratic beziere 25946 val[0] = 'Q'; 25947 val[3] = val[1]; 25948 val[4] = val[2]; 25949 val[1] = this.reflection[1]; 25950 val[2] = this.reflection[0]; 25951 break 25952 case 'S': // shorthand cubic beziere 25953 val[0] = 'C'; 25954 val[6] = val[4]; 25955 val[5] = val[3]; 25956 val[4] = val[2]; 25957 val[3] = val[1]; 25958 val[2] = this.reflection[1]; 25959 val[1] = this.reflection[0]; 25960 break 25961 } 25962 25963 return val 25964 25965 } 25966 25967 // updates reflection point and current position 25968 function setPosAndReflection(val){ 25969 25970 var len = val.length; 25971 25972 this.pos = [ val[len-2], val[len-1] ]; 25973 25974 if('SCQT'.indexOf(val[0]) != -1) 25975 this.reflection = [ 2 * this.pos[0] - val[len-4], 2 * this.pos[1] - val[len-3] ]; 25976 25977 return val 25978 } 25979 25980 // converts all types to cubic beziere 25981 function toBeziere(val){ 25982 var retVal = [val]; 25983 25984 switch(val[0]){ 25985 case 'M': // special handling for M 25986 this.pos = this.start = [val[1], val[2]]; 25987 return retVal 25988 case 'L': 25989 val[5] = val[3] = val[1]; 25990 val[6] = val[4] = val[2]; 25991 val[1] = this.pos[0]; 25992 val[2] = this.pos[1]; 25993 break 25994 case 'Q': 25995 val[6] = val[4]; 25996 val[5] = val[3]; 25997 val[4] = val[4] * 1/3 + val[2] * 2/3; 25998 val[3] = val[3] * 1/3 + val[1] * 2/3; 25999 val[2] = this.pos[1] * 1/3 + val[2] * 2/3; 26000 val[1] = this.pos[0] * 1/3 + val[1] * 2/3; 26001 break 26002 case 'A':
26003 retVal = arcToBeziere(this.pos, val); 26004 val = retVal[0]; 26005 break 26006 } 26007 26008 val[0] = 'C'; 26009 this.pos = [val[5], val[6]]; 26010 this.reflection = [2 * val[5] - val[3], 2 * val[6] - val[4]]; 26011 26012 return retVal 26013 26014 } 26015 26016 // finds the next position of type M 26017 function findNextM(arr, offset){ 26018 26019 if(offset === false) return false 26020 26021 for(var i = offset, len = arr.length;i < len;++i){ 26022 26023 if(arr[i][0] == 'M') return i 26024 26025 } 26026 26027 return false 26028 } 26029 26030 26031 26032 // Convert an arc segment into equivalent cubic Bezier curves 26033 // Depending on the arc, up to 4 curves might be used to represent it since a 26034 // curve gives a good approximation for only a quarter of an ellipse 26035 // The curves are returned as an array of SVG curve commands: 26036 // [ ['C', x1, y1, x2, y2, x, y] ... ] 26037 function arcToBeziere(pos, val) { 26038 // Parameters extraction, handle out-of-range parameters as specified in the SVG spec 26039 // See: https://www.w3.org/TR/SVG11/implnote.html#ArcOutOfRangeParameters 26040 var rx = Math.abs(val[1]), ry = Math.abs(val[2]), xAxisRotation = val[3] % 360 26041 , largeArcFlag = val[4], sweepFlag = val[5], x = val[6], y = val[7] 26042 , A = new SVG.Point(pos), B = new SVG.Point(x, y) 26043 , primedCoord, lambda, mat, k, c, cSquare, t, O, OA, OB, tetaStart, tetaEnd 26044 , deltaTeta, nbSectors, f, arcSegPoints, angle, sinAngle, cosAngle, pt, i, il 26045 , retVal = [], x1, y1, x2, y2; 26046 26047 // Ensure radii are non-zero 26048 if(rx === 0 || ry === 0 || (A.x === B.x && A.y === B.y)) { 26049 // treat this arc as a straight line segment 26050 return [['C', A.x, A.y, B.x, B.y, B.x, B.y]] 26051 } 26052 26053 // Ensure radii are large enough using the algorithm provided in the SVG spec 26054 // See: https://www.w3.org/TR/SVG11/implnote.html#ArcCorrectionOutOfRangeRadii 26055 primedCoord = new SVG.Point((A.x-B.x)/2, (A.y-B.y)/2).transform(new SVG.Matrix().rotate(xAxisRotation)); 26056 lambda = (primedCoord.x * primedCoord.x) / (rx * rx) + (primedCoord.y * primedCoord.y) / (ry * ry); 26057 if(lambda > 1) { 26058 lambda = Math.sqrt(lambda); 26059 rx = lambda*rx; 26060 ry = lambda*ry; 26061 } 26062 26063 // To simplify calculations, we make the arc part of a unit circle (rayon is 1) instead of an ellipse 26064 mat = new SVG.Matrix().rotate(xAxisRotation).scale(1/rx, 1/ry).rotate(-xAxisRotation); 26065 A = A.transform(mat); 26066 B = B.transform(mat); 26067 26068 // Calculate the horizontal and vertical distance between the initial and final point of the arc 26069 k = [B.x-A.x, B.y-A.y]; 26070 26071 // Find the length of the chord formed by A and B 26072 cSquare = k[0]*k[0] + k[1]*k[1]; 26073 c = Math.sqrt(cSquare); 26074 26075 // Calculate the ratios of the horizontal and vertical distance on the length of the chord 26076 k[0] /= c; 26077 k[1] /= c; 26078 26079 // Calculate the distance between the circle center and the chord midpoint 26080 // using this formula: t = sqrt(r^2 - c^2 / 4) 26081 // where t is the distance between the cirle center and the chord midpoint, 26082 // r is the rayon of the circle and c is the chord length 26083 // From: http://www.ajdesigner.com/phpcircle/circle_segment_chord_t.php 26084 // Because of the imprecision of floating point numbers, cSquare might end 26085 // up being slightly above 4 which would result in a negative radicand 26086 // To prevent that, a test is made before computing the square root 26087 t = (cSquare < 4) ? Math.sqrt(1 - cSquare/4) : 0; 26088 26089 // For most situations, there are actually two different ellipses that 26090 // satisfy the constraints imposed by the points A and B, the radii rx and ry, 26091 // and the xAxisRotation 26092 // When the flags largeArcFlag and sweepFlag are equal, it means that the 26093 // second ellipse is used as a solution 26094 // See: https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands 26095 if(largeArcFlag === sweepFlag) { 26096 t *= -1; 26097 } 26098 26099 // Calculate the coordinates of the center of the circle from the midpoint of the chord 26100 // This is done by multiplying the ratios calculated previously by the distance between 26101 // the circle center and the chord midpoint and using these values to go from the midpoint 26102 // to the center of the circle 26103 // The negative of the vertical distance ratio is used to modify the x coordinate while 26104 // the horizontal distance ratio is used to modify the y coordinate 26105 // That is because the center of the circle is perpendicular to the chord and perpendicular 26106 // lines are negative reciprocals 26107 O = new SVG.Point((B.x+A.x)/2 + t*-k[1], (B.y+A.y)/2 + t*k[0]); 26108 // Move the center of the circle at the origin 26109 OA = new SVG.Point(A.x-O.x, A.y-O.y); 26110 OB = new SVG.Point(B.x-O.x, B.y-O.y); 26111 26112 // Calculate the start and end angle 26113 tetaStart = Math.acos(OA.x/Math.sqrt(OA.x*OA.x + OA.y*OA.y)); 26114 if (OA.y < 0) { 26115 tetaStart *= -1; 26116 } 26117 tetaEnd = Math.acos(OB.x/Math.sqrt(OB.x*OB.x + OB.y*OB.y)); 26118 if (OB.y < 0) { 26119 tetaEnd *= -1; 26120 } 26121 26122 // If sweep-flag is '1', then the arc will be drawn in a "positive-angle" direction, 26123 // make sure that the end angle is above the start angle 26124 if (sweepFlag && tetaStart > tetaEnd) { 26125 tetaEnd += 2*Math.PI; 26126 } 26127 // If sweep-flag is '0', then the arc will be drawn in a "negative-angle" direction, 26128 // make sure that the end angle is below the start angle 26129 if (!sweepFlag && tetaStart < tetaEnd) { 26130 tetaEnd -= 2*Math.PI; 26131 } 26132 26133 // Find the number of Bezier curves that are required to represent the arc 26134 // A cubic Bezier curve gives a good enough approximation when representing at most a quarter of a circle 26135 nbSectors = Math.ceil(Math.abs(tetaStart-tetaEnd) * 2/Math.PI); 26136 26137 // Calculate the coordinates of the points of all the Bezier curves required to represent the arc 26138 // For an in-depth explanation of this part see: http://pomax.github.io/bezierinfo/#circles_cubic 26139 arcSegPoints = []; 26140 angle = tetaStart; 26141 deltaTeta = (tetaEnd-tetaStart)/nbSectors; 26142 f = 4*Math.tan(deltaTeta/4)/3; 26143 for (i = 0; i <= nbSectors; i++) { // The <= is because a Bezier curve have a start and a endpoint
26144 cosAngle = Math.cos(angle); 26145 sinAngle = Math.sin(angle); 26146 26147 pt = new SVG.Point(O.x+cosAngle, O.y+sinAngle); 26148 arcSegPoints[i] = [new SVG.Point(pt.x+f*sinAngle, pt.y-f*cosAngle), pt, new SVG.Point(pt.x-f*sinAngle, pt.y+f*cosAngle)]; 26149 26150 angle += deltaTeta; 26151 } 26152 26153 // Remove the first control point of the first segment point and remove the second control point of the last segment point 26154 // These two control points are not used in the approximation of the arc, that is why they are removed 26155 arcSegPoints[0][0] = arcSegPoints[0][1].clone(); 26156 arcSegPoints[arcSegPoints.length-1][2] = arcSegPoints[arcSegPoints.length-1][1].clone(); 26157 26158 // Revert the transformation that was applied to make the arc part of a unit circle instead of an ellipse 26159 mat = new SVG.Matrix().rotate(xAxisRotation).scale(rx, ry).rotate(-xAxisRotation); 26160 for (i = 0, il = arcSegPoints.length; i < il; i++) { 26161 arcSegPoints[i][0] = arcSegPoints[i][0].transform(mat); 26162 arcSegPoints[i][1] = arcSegPoints[i][1].transform(mat); 26163 arcSegPoints[i][2] = arcSegPoints[i][2].transform(mat); 26164 } 26165 26166 26167 // Convert the segments points to SVG curve commands 26168 for (i = 1, il = arcSegPoints.length; i < il; i++) { 26169 pt = arcSegPoints[i-1][2]; 26170 x1 = pt.x; 26171 y1 = pt.y; 26172 26173 pt = arcSegPoints[i][0]; 26174 x2 = pt.x; 26175 y2 = pt.y; 26176 26177 pt = arcSegPoints[i][1]; 26178 x = pt.x; 26179 y = pt.y; 26180 26181 retVal.push(['C', x1, y1, x2, y2, x, y]); 26182 } 26183 26184 return retVal 26185 } 26186 }()); 26187 26188 /*! svg.draggable.js - v2.2.1 - 2016-08-25 26189 * https://github.com/wout/svg.draggable.js 26190 * Copyright (c) 2016 Wout Fierens; Licensed MIT */ 26191 (function() { 26192 26193 // creates handler, saves it 26194 function DragHandler(el){ 26195 el.remember('_draggable', this); 26196 this.el = el; 26197 } 26198 26199 26200 // Sets new parameter, starts dragging 26201 DragHandler.prototype.init = function(constraint, val){ 26202 var _this = this; 26203 this.constraint = constraint; 26204 this.value = val; 26205 this.el.on('mousedown.drag', function(e){ _this.start(e); }); 26206 this.el.on('touchstart.drag', function(e){ _this.start(e); }); 26207 }; 26208 26209 // transforms one point from screen to user coords 26210 DragHandler.prototype.transformPoint = function(event, offset){ 26211 event = event || window.event; 26212 var touches = event.changedTouches && event.changedTouches[0] || event; 26213 this.p.x = touches.pageX - (offset || 0); 26214 this.p.y = touches.pageY; 26215 return this.p.matrixTransform(this.m) 26216 }; 26217 26218 // gets elements bounding box with special handling of groups, nested and use 26219 DragHandler.prototype.getBBox = function(){ 26220 26221 var box = this.el.bbox(); 26222 26223 if(this.el instanceof SVG.Nested) box = this.el.rbox(); 26224 26225 if (this.el instanceof SVG.G || this.el instanceof SVG.Use || this.el instanceof SVG.Nested) { 26226 box.x = this.el.x(); 26227 box.y = this.el.y(); 26228 } 26229 26230 return box 26231 }; 26232 26233 // start dragging 26234 DragHandler.prototype.start = function(e){ 26235 26236 // check for left button 26237 if(e.type == 'click'|| e.type == 'mousedown' || e.type == 'mousemove'){ 26238 if((e.which || e.buttons) != 1){ 26239 return 26240 } 26241 } 26242 26243 var _this = this; 26244 26245 // fire beforedrag event 26246 this.el.fire('beforedrag', { event: e, handler: this }); 26247 26248 // search for parent on the fly to make sure we can call 26249 // draggable() even when element is not in the dom currently 26250 this.parent = this.parent || this.el.parent(SVG.Nested) || this.el.parent(SVG.Doc); 26251 this.p = this.parent.node.createSVGPoint(); 26252 26253 // save current transformation matrix 26254 this.m = this.el.node.getScreenCTM().inverse(); 26255 26256 var box = this.getBBox(); 26257 26258 var anchorOffset; 26259 26260 // fix text-anchor in text-element (#37) 26261 if(this.el instanceof SVG.Text){ 26262 anchorOffset = this.el.node.getComputedTextLength(); 26263 26264 switch(this.el.attr('text-anchor')){ 26265 case 'middle': 26266 anchorOffset /= 2; 26267 break 26268 case 'start': 26269 anchorOffset = 0; 26270 break; 26271 } 26272 } 26273 26274 this.startPoints = { 26275 // We take absolute coordinates since we are just using a delta here 26276 point: this.transformPoint(e, anchorOffset), 26277 box: box, 26278 transform: this.el.transform() 26279 }; 26280 26281 // add drag and end events to window 26282 SVG.on(window, 'mousemove.drag', function(e){ _this.drag(e); }); 26283 SVG.on(window, 'touchmove.drag', function(e){ _this.drag(e); }); 26284 SVG.on(window, 'mouseup.drag', function(e){ _this.end(e); }); 26285 SVG.on(window, 'touchend.drag', function(e){ _this.end(e); }); 26286 26287 // fire dragstart event 26288 this.el.fire('dragstart', {event: e, p: this.startPoints.point, m: this.m, handler: this}); 26289 26290 // prevent browser drag behavior 26291 e.preventDefault(); 26292 26293 // prevent propagation to a parent that might also have dragging enabled 26294 e.stopPropagation(); 26295 }; 26296 26297 // while dragging 26298 DragHandler.prototype.drag = function(e){
26299 26300 var box = this.getBBox() 26301 , p = this.transformPoint(e) 26302 , x = this.startPoints.box.x + p.x - this.startPoints.point.x 26303 , y = this.startPoints.box.y + p.y - this.startPoints.point.y 26304 , c = this.constraint 26305 , gx = p.x - this.startPoints.point.x 26306 , gy = p.y - this.startPoints.point.y; 26307 26308 var event = new CustomEvent('dragmove', { 26309 detail: { 26310 event: e 26311 , p: p 26312 , m: this.m 26313 , handler: this 26314 } 26315 , cancelable: true 26316 }); 26317 26318 this.el.fire(event); 26319 26320 if(event.defaultPrevented) return p 26321 26322 // move the element to its new position, if possible by constraint 26323 if (typeof c == 'function') { 26324 26325 var coord = c.call(this.el, x, y, this.m); 26326 26327 // bool, just show us if movement is allowed or not 26328 if (typeof coord == 'boolean') { 26329 coord = { 26330 x: coord, 26331 y: coord 26332 }; 26333 } 26334 26335 // if true, we just move. If !false its a number and we move it there 26336 if (coord.x === true) { 26337 this.el.x(x); 26338 } else if (coord.x !== false) { 26339 this.el.x(coord.x); 26340 } 26341 26342 if (coord.y === true) { 26343 this.el.y(y); 26344 } else if (coord.y !== false) { 26345 this.el.y(coord.y); 26346 } 26347 26348 } else if (typeof c == 'object') { 26349 26350 // keep element within constrained box 26351 if (c.minX != null && x < c.minX) 26352 x = c.minX; 26353 else if (c.maxX != null && x > c.maxX - box.width){ 26354 x = c.maxX - box.width; 26355 }if (c.minY != null && y < c.minY) 26356 y = c.minY; 26357 else if (c.maxY != null && y > c.maxY - box.height) 26358 y = c.maxY - box.height; 26359 26360 if(this.el instanceof SVG.G) 26361 this.el.matrix(this.startPoints.transform).transform({x:gx, y: gy}, true); 26362 else 26363 this.el.move(x, y); 26364 } 26365 26366 // so we can use it in the end-method, too 26367 return p 26368 }; 26369 26370 DragHandler.prototype.end = function(e){ 26371 26372 // final drag 26373 var p = this.drag(e); 26374 26375 // fire dragend event 26376 this.el.fire('dragend', { event: e, p: p, m: this.m, handler: this }); 26377 26378 // unbind events 26379 SVG.off(window, 'mousemove.drag'); 26380 SVG.off(window, 'touchmove.drag'); 26381 SVG.off(window, 'mouseup.drag'); 26382 SVG.off(window, 'touchend.drag'); 26383 26384 }; 26385 26386 SVG.extend(SVG.Element, { 26387 // Make element draggable 26388 // Constraint might be an object (as described in readme.md) or a function in the form "function (x, y)" that gets called before every move. 26389 // The function can return a boolean or an object of the form {x, y}, to which the element will be moved. "False" skips moving, true moves to raw x, y. 26390 draggable: function(value, constraint) { 26391 26392 // Check the parameters and reassign if needed 26393 if (typeof value == 'function' || typeof value == 'object') { 26394 constraint = value; 26395 value = true; 26396 } 26397 26398 var dragHandler = this.remember('_draggable') || new DragHandler(this); 26399 26400 // When no parameter is given, value is true 26401 value = typeof value === 'undefined' ? true : value; 26402 26403 if(value) dragHandler.init(constraint || {}, value); 26404 else { 26405 this.off('mousedown.drag'); 26406 this.off('touchstart.drag'); 26407 } 26408 26409 return this 26410 } 26411 26412 }); 26413 26414 }).call(undefined); 26415 26416 (function() { 26417 26418 function SelectHandler(el) { 26419 26420 this.el = el; 26421 el.remember('_selectHandler', this); 26422 this.pointSelection = {isSelected: false}; 26423 this.rectSelection = {isSelected: false}; 26424 26425 } 26426 26427 SelectHandler.prototype.init = function (value, options) { 26428 26429 var bbox = this.el.bbox(); 26430 this.options = {}; 26431 26432 // Merging the defaults and the options-object together 26433 for (var i in this.el.selectize.defaults) { 26434 this.options[i] = this.el.selectize.defaults[i]; 26435 if (options[i] !== undefined) { 26436 this.options[i] = options[i]; 26437 } 26438 } 26439 26440 this.parent = this.el.parent(); 26441 this.nested = (this.nested || this.parent.group()); 26442 this.nested.matrix(new SVG.Matrix(this.el).translate(bbox.x, bbox.y)); 26443 26444 // When deepSelect is enabled and the element is a line/polyline/polygon, draw only points for moving 26445 if (this.options.deepSelect && ['line', 'polyline', 'polygon'].indexOf(this.el.type) !== -1) { 26446 this.selectPoints(value); 26447 } else { 26448 this.selectRect(value); 26449 } 26450 26451 this.observe(); 26452 this.cleanup(); 26453 26454 }; 26455 26456 SelectHandler.prototype.selectPoints = function (value) { 26457 26458 this.pointSelection.isSelected = value; 26459 26460 // When set is already there we dont have to create one 26461 if (this.pointSelection.set) { 26462 return this; 26463 } 26464 26465 // Create our set of elements 26466 this.pointSelection.set = this.parent.set(); 26467 // draw the circles and mark the element as selected 26468 this.drawCircles(); 26469 26470 return this; 26471 26472 }; 26473 26474 // create the point-array which contains the 2 points of a line or simply the points-array of polyline/polygon 26475 SelectHandler.prototype.getPointArray = function () { 26476 var bbox = this.el.bbox(); 26477 26478 return this.el.array().valueOf().map(function (el) { 26479 return [el[0] - bbox.x, el[1] - bbox.y]; 26480 }); 26481 }; 26482 26483 // The function to draw the circles 26484 SelectHandler.prototype.drawCircles = function () { 26485 26486 var _this = this, array = this.getPointArray(); 26487 26488 // go through the array of points 26489 for (var i = 0, len = array.length; i < len; ++i) { 26490 26491 var curriedEvent = (function (k) { 26492 return function (ev) { 26493 ev = ev || window.event; 26494 ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; 26495 ev.stopPropagation(); 26496 26497 var x = ev.pageX || ev.touches[0].pageX; 26498 var y = ev.pageY || ev.touches[0].pageY; 26499 _this.el.fire('point', {x: x, y: y, i: k, event: ev}); 26500 }; 26501 })(i); 26502 26503 // add every point to the set 26504 this.pointSelection.set.add( 26505 // a circle with our css-classes and a touchstart-event which fires our event for moving points 26506 this.nested.circle(this.options.radius) 26507 .center(array[i][0], array[i][1]) 26508 .addClass(this.options.classPoints) 26509 .addClass(this.options.classPoints + '_point') 26510 .on('touchstart', curriedEvent) 26511 .on('mousedown', curriedEvent) 26512 ); 26513 } 26514 26515 }; 26516 26517 // every time a circle is moved, we have to update the positions of our circle 26518 SelectHandler.prototype.updatePointSelection = function () { 26519 var array = this.getPointArray(); 26520 26521 this.pointSelection.set.each(function (i) { 26522 if (this.cx() === array[i][0] && this.cy() === array[i][1]) { 26523 return; 26524 } 26525 this.center(array[i][0], array[i][1]); 26526 }); 26527 }; 26528 26529 SelectHandler.prototype.updateRectSelection = function () { 26530 var bbox = this.el.bbox(); 26531 26532 this.rectSelection.set.get(0).attr({ 26533 width: bbox.width, 26534 height: bbox.height 26535 }); 26536 26537 // set.get(1) is always in the upper left corner. no need to move it 26538 if (this.options.points) { 26539 this.rectSelection.set.get(2).center(bbox.width, 0); 26540 this.rectSelection.set.get(3).center(bbox.width, bbox.height); 26541 this.rectSelection.set.get(4).center(0, bbox.height); 26542 26543 this.rectSelection.set.get(5).center(bbox.width / 2, 0); 26544 this.rectSelection.set.get(6).center(bbox.width, bbox.height / 2); 26545 this.rectSelection.set.get(7).center(bbox.width / 2, bbox.height); 26546 this.rectSelection.set.get(8).center(0, bbox.height / 2); 26547 } 26548 26549 if (this.options.rotationPoint) { 26550 if (this.options.points) { 26551 this.rectSelection.set.get(9).center(bbox.width / 2, 20); 26552 } else { 26553 this.rectSelection.set.get(1).center(bbox.width / 2, 20); 26554 } 26555 } 26556 }; 26557 26558 SelectHandler.prototype.selectRect = function (value) { 26559 26560 var _this = this, bbox = this.el.bbox(); 26561 26562 this.rectSelection.isSelected = value; 26563 26564 // when set is already p 26565 this.rectSelection.set = this.rectSelection.set || this.parent.set(); 26566 26567 // helperFunction to create a mouse-down function which triggers the event specified in `eventName` 26568 function getMoseDownFunc(eventName) { 26569 return function (ev) { 26570 ev = ev || window.event; 26571 ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; 26572 ev.stopPropagation(); 26573 26574 var x = ev.pageX || ev.touches[0].pageX; 26575 var y = ev.pageY || ev.touches[0].pageY; 26576 _this.el.fire(eventName, {x: x, y: y, event: ev}); 26577 }; 26578 } 26579 26580 // create the selection-rectangle and add the css-class 26581 if (!this.rectSelection.set.get(0)) { 26582 this.rectSelection.set.add(this.nested.rect(bbox.width, bbox.height).addClass(this.options.classRect)); 26583 } 26584 26585 // Draw Points at the edges, if enabled 26586 if (this.options.points && !this.rectSelection.set.get(1)) { 26587 var ename ="touchstart", mname = "mousedown"; 26588 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(0, 0).attr('class', this.options.classPoints + '_lt').on(mname, getMoseDownFunc('lt')).on(ename, getMoseDownFunc('lt'))); 26589 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(bbox.width, 0).attr('class', this.options.classPoints + '_rt').on(mname, getMoseDownFunc('rt')).on(ename, getMoseDownFunc('rt'))); 26590 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(bbox.width, bbox.height).attr('class', this.options.classPoints + '_rb').on(mname, getMoseDownFunc('rb')).on(ename, getMoseDownFunc('rb'))); 26591 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(0, bbox.height).attr('class', this.options.classPoints + '_lb').on(mname, getMoseDownFunc('lb')).on(ename, getMoseDownFunc('lb'))); 26592 26593 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(bbox.width / 2, 0).attr('class', this.options.classPoints + '_t').on(mname, getMoseDownFunc('t')).on(ename, getMoseDownFunc('t'))); 26594 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(bbox.width, bbox.height / 2).attr('class', this.options.classPoints + '_r').on(mname, getMoseDownFunc('r')).on(ename, getMoseDownFunc('r'))); 26595 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(bbox.width / 2, bbox.height).attr('class', this.options.classPoints + '_b').on(mname, getMoseDownFunc('b')).on(ename, getMoseDownFunc('b'))); 26596 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(0, bbox.height / 2).attr('class', this.options.classPoints + '_l').on(mname, getMoseDownFunc('l')).on(ename, getMoseDownFunc('l'))); 26597 26598 this.rectSelection.set.each(function () { 26599 this.addClass(_this.options.classPoints); 26600 }); 26601 } 26602 26603 // draw rotationPint, if enabled 26604 if (this.options.rotationPoint && ((this.options.points && !this.rectSelection.set.get(9)) || (!this.options.points && !this.rectSelection.set.get(1)))) { 26605 26606 var curriedEvent = function (ev) { 26607 ev = ev || window.event; 26608 ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; 26609 ev.stopPropagation(); 26610 26611 var x = ev.pageX || ev.touches[0].pageX; 26612 var y = ev.pageY || ev.touches[0].pageY; 26613 _this.el.fire('rot', {x: x, y: y, event: ev}); 26614 }; 26615 this.rectSelection.set.add(this.nested.circle(this.options.radius).center(bbox.width / 2, 20).attr('class', this.options.classPoints + '_rot') 26616 .on("touchstart", curriedEvent).on("mousedown", curriedEvent)); 26617 26618 } 26619 26620 }; 26621 26622 SelectHandler.prototype.handler = function () { 26623 26624 var bbox = this.el.bbox(); 26625 this.nested.matrix(new SVG.Matrix(this.el).translate(bbox.x, bbox.y)); 26626 26627 if (this.rectSelection.isSelected) { 26628 this.updateRectSelection(); 26629 } 26630 26631 if (this.pointSelection.isSelected) { 26632 this.updatePointSelection(); 26633 } 26634 26635 }; 26636 26637 SelectHandler.prototype.observe = function () { 26638 var _this = this; 26639 26640 if (MutationObserver) { 26641 if (this.rectSelection.isSelected || this.pointSelection.isSelected) { 26642 this.observerInst = this.observerInst || new MutationObserver(function () { 26643 _this.handler(); 26644 }); 26645 this.observerInst.observe(this.el.node, {attributes: true}); 26646 } else { 26647 try { 26648 this.observerInst.disconnect(); 26649 delete this.observerInst; 26650 } catch (e) { 26651 } 26652 } 26653 } else { 26654 this.el.off('DOMAttrModified.select'); 26655 26656 if (this.rectSelection.isSelected || this.pointSelection.isSelected) { 26657 this.el.on('DOMAttrModified.select', function () { 26658 _this.handler(); 26659 }); 26660 } 26661 } 26662 }; 26663 26664 SelectHandler.prototype.cleanup = function () { 26665 26666 //var _this = this; 26667 26668 if (!this.rectSelection.isSelected && this.rectSelection.set) { 26669 // stop watching the element, remove the selection 26670 this.rectSelection.set.each(function () { 26671 this.remove(); 26672 }); 26673 26674 this.rectSelection.set.clear(); 26675 delete this.rectSelection.set; 26676 } 26677 26678 if (!this.pointSelection.isSelected && this.pointSelection.set) { 26679 // Remove all points, clear the set, stop watching the element 26680 this.pointSelection.set.each(function () { 26681 this.remove(); 26682 }); 26683 26684 this.pointSelection.set.clear(); 26685 delete this.pointSelection.set; 26686 } 26687 26688 if (!this.pointSelection.isSelected && !this.rectSelection.isSelected) { 26689 this.nested.remove(); 26690 delete this.nested; 26691 26692 } 26693 }; 26694 26695 26696 SVG.extend(SVG.Element, { 26697 // Select element with mouse 26698 selectize: function (value, options) { 26699 26700 // Check the parameters and reassign if needed 26701 if (typeof value === 'object') { 26702 options = value; 26703 value = true; 26704 } 26705 26706 var selectHandler = this.remember('_selectHandler') || new SelectHandler(this); 26707 26708 selectHandler.init(value === undefined ? true : value, options || {}); 26709 26710 return this; 26711 26712 } 26713 }); 26714 26715 SVG.Element.prototype.selectize.defaults = { 26716 points: true, // If true, points at the edges are drawn. Needed for resize! 26717 classRect: 'svg_select_boundingRect', // Css-class added to the rect 26718 classPoints: 'svg_select_points', // Css-class added to the points 26719 radius: 7, // radius of the points 26720 rotationPoint: true, // If true, rotation point is drawn. Needed for rotation! 26721 deepSelect: false // If true, moving of single points is possible (only line, polyline, polyon) 26722 }; 26723 }()); 26724 26725 (function() { 26726 (function () { 26727 26728 function ResizeHandler(el) { 26729 26730 el.remember('_resizeHandler', this); 26731 26732 this.el = el; 26733 this.parameters = {}; 26734 this.lastUpdateCall = null; 26735 this.p = el.doc().node.createSVGPoint(); 26736 } 26737 26738 ResizeHandler.prototype.transformPoint = function(x, y, m){ 26739 26740 this.p.x = x - (this.offset.x - window.pageXOffset); 26741 this.p.y = y - (this.offset.y - window.pageYOffset); 26742 26743 return this.p.matrixTransform(m || this.m); 26744 26745 }; 26746 26747 ResizeHandler.prototype._extractPosition = function(event) { 26748 // Extract a position from a mouse/touch event. 26749 // Returns { x
26749: .., y: .. } 26750 return { 26751 x: event.clientX != null ? event.clientX : event.touches[0].clientX, 26752 y: event.clientY != null ? event.clientY : event.touches[0].clientY 26753 } 26754 }; 26755 26756 ResizeHandler.prototype.init = function (options) { 26757 26758 var _this = this; 26759 26760 this.stop(); 26761 26762 if (options === 'stop') { 26763 return; 26764 } 26765 26766 this.options = {}; 26767 26768 // Merge options and defaults 26769 for (var i in this.el.resize.defaults) { 26770 this.options[i] = this.el.resize.defaults[i]; 26771 if (typeof options[i] !== 'undefined') { 26772 this.options[i] = options[i]; 26773 } 26774 } 26775 26776 // We listen to all these events which are specifying different edges 26777 this.el.on('lt.resize', function(e){ _this.resize(e || window.event); }); // Left-Top 26778 this.el.on('rt.resize', function(e){ _this.resize(e || window.event); }); // Right-Top 26779 this.el.on('rb.resize', function(e){ _this.resize(e || window.event); }); // Right-Bottom 26780 this.el.on('lb.resize', function(e){ _this.resize(e || window.event); }); // Left-Bottom 26781 26782 this.el.on('t.resize', function(e){ _this.resize(e || window.event); }); // Top 26783 this.el.on('r.resize', function(e){ _this.resize(e || window.event); }); // Right 26784 this.el.on('b.resize', function(e){ _this.resize(e || window.event); }); // Bottom 26785 this.el.on('l.resize', function(e){ _this.resize(e || window.event); }); // Left 26786 26787 this.el.on('rot.resize', function(e){ _this.resize(e || window.event); }); // Rotation 26788 26789 this.el.on('point.resize', function(e){ _this.resize(e || window.event); }); // Point-Moving 26790 26791 // This call ensures, that the plugin reacts to a change of snapToGrid immediately 26792 this.update(); 26793 26794 }; 26795 26796 ResizeHandler.prototype.stop = function(){ 26797 this.el.off('lt.resize'); 26798 this.el.off('rt.resize'); 26799 this.el.off('rb.resize'); 26800 this.el.off('lb.resize'); 26801 26802 this.el.off('t.resize'); 26803 this.el.off('r.resize'); 26804 this.el.off('b.resize'); 26805 this.el.off('l.resize'); 26806 26807 this.el.off('rot.resize'); 26808 26809 this.el.off('point.resize'); 26810 26811 return this; 26812 }; 26813 26814 ResizeHandler.prototype.resize = function (event) { 26815 26816 var _this = this; 26817 26818 this.m = this.el.node.getScreenCTM().inverse(); 26819 this.offset = { x: window.pageXOffset, y: window.pageYOffset }; 26820 26821 var txPt = this._extractPosition(event.detail.event); 26822 this.parameters = { 26823 type: this.el.type, // the type of element 26824 p: this.transformPoint(txPt.x, txPt.y), 26825 x: event.detail.x, // x-position of the mouse when resizing started 26826 y: event.detail.y, // y-position of the mouse when resizing started 26827 box: this.el.bbox(), // The bounding-box of the element 26828 rotation: this.el.transform().rotation // The current rotation of the element 26829 }; 26830 26831 // Add font-size parameter if the element type is text 26832 if (this.el.type === "text") { 26833 this.parameters.fontSize = this.el.attr()["font-size"]; 26834 } 26835 26836 // the i-param in the event holds the index of the point which is moved, when using `deepSelect` 26837 if (event.detail.i !== undefined) { 26838 26839 // get the point array 26840 var array = this.el.array().valueOf(); 26841 26842 // Save the index and the point which is moved 26843 this.parameters.i = event.detail.i; 26844 this.parameters.pointCoords = [array[event.detail.i][0], array[event.detail.i][1]]; 26845 } 26846 26847 // Lets check which edge of the bounding-box was clicked and resize the this.el according to this 26848 switch (event.type) { 26849 26850 // Left-Top-Edge 26851 case 'lt': 26852 // We build a calculating function for every case which gives us the new position of the this.el 26853 this.calc = function (diffX, diffY) { 26854 // The procedure is always the same 26855 // First we snap the edge to the given grid (snapping to 1px grid is normal resizing)
26856 var snap = this.snapToGrid(diffX, diffY); 26857 26858 // Now we check if the new height and width still valid (> 0) 26859 if (this.parameters.box.width - snap[0] > 0 && this.parameters.box.height - snap[1] > 0) { 26860 // ...if valid, we resize the this.el (which can include moving because the coord-system starts at the left-top and this edge is moving sometimes when resized) 26861 26862 /* 26863 * but first check if the element is text box, so we can change the font size instead of 26864 * the width and height 26865 */ 26866 26867 if (this.parameters.type === "text") { 26868 this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y); 26869 this.el.attr("font-size", this.parameters.fontSize - snap[0]); 26870 return; 26871 } 26872 26873 snap = this.checkAspectRatio(snap); 26874 26875 this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y + snap[1]).size(this.parameters.box.width - snap[0], this.parameters.box.height - snap[1]); 26876 } 26877 }; 26878 break; 26879 26880 // Right-Top 26881 case 'rt': 26882 // s.a. 26883 this.calc = function (diffX, diffY) { 26884 var snap = this.snapToGrid(diffX, diffY, 1 << 1); 26885 if (this.parameters.box.width + snap[0] > 0 && this.parameters.box.height - snap[1] > 0) { 26886 if (this.parameters.type === "text") { 26887 this.el.move(this.parameters.box.x - snap[0], this.parameters.box.y); 26888 this.el.attr("font-size", this.parameters.fontSize + snap[0]); 26889 return; 26890 } 26891 26892 snap = this.checkAspectRatio(snap); 26893 26894 this.el.move(this.parameters.box.x, this.parameters.box.y + snap[1]).size(this.parameters.box.width + snap[0], this.parameters.box.height - snap[1]); 26895 } 26896 }; 26897 break; 26898 26899 // Right-Bottom 26900 case 'rb': 26901 // s.a. 26902 this.calc = function (diffX, diffY) { 26903 var snap = this.snapToGrid(diffX, diffY, 0); 26904 if (this.parameters.box.width + snap[0] > 0 && this.parameters.box.height + snap[1] > 0) { 26905 if (this.parameters.type === "text") { 26906 this.el.move(this.parameters.box.x - snap[0], this.parameters.box.y); 26907 this.el.attr("font-size", this.parameters.fontSize + snap[0]); 26908 return; 26909 } 26910 26911 snap = this.checkAspectRatio(snap); 26912 26913 this.el.move(this.parameters.box.x, this.parameters.box.y).size(this.parameters.box.width + snap[0], this.parameters.box.height + snap[1]); 26914 } 26915 }; 26916 break; 26917
26918 // Left-Bottom 26919 case 'lb': 26920 // s.a. 26921 this.calc = function (diffX, diffY) { 26922 var snap = this.snapToGrid(diffX, diffY, 1); 26923 if (this.parameters.box.width - snap[0] > 0 && this.parameters.box.height + snap[1] > 0) { 26924 if (this.parameters.type === "text") { 26925 this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y); 26926 this.el.attr("font-size", this.parameters.fontSize - snap[0]); 26927 return; 26928 } 26929 26930 snap = this.checkAspectRatio(snap); 26931 26932 this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y).size(this.parameters.box.width - snap[0], this.parameters.box.height + snap[1]); 26933 } 26934 }; 26935 break; 26936 26937 // Top 26938 case 't': 26939 // s.a. 26940 this.calc = function (diffX, diffY) { 26941 var snap = this.snapToGrid(diffX, diffY, 1 << 1); 26942 if (this.parameters.box.height - snap[1] > 0) { 26943 // Disable the font-resizing if it is not from the corner of bounding-box 26944 if (this.parameters.type === "text") { 26945 return; 26946 } 26947 26948 this.el.move(this.parameters.box.x, this.parameters.box.y + snap[1]).height(this.parameters.box.height - snap[1]); 26949 } 26950 }; 26951 break; 26952 26953 // Right 26954 case 'r': 26955 // s.a. 26956 this.calc = function (diffX, diffY) { 26957 var snap = this.snapToGrid(diffX, diffY, 0); 26958 if (this.parameters.box.width + snap[0] > 0) { 26959 if (this.parameters.type === "text") { 26960 return; 26961 } 26962 26963 this.el.move(this.parameters.box.x, this.parameters.box.y).width(this.parameters.box.width + snap[0]); 26964 } 26965 }; 26966 break; 26967 26968 // Bottom 26969 case 'b': 26970 // s.a. 26971 this.calc = function (diffX, diffY) { 26972 var snap = this.snapToGrid(diffX, diffY, 0); 26973 if (this.parameters.box.height + snap[1] > 0) { 26974 if (this.parameters.type === "text") { 26975 return; 26976 } 26977 26978 this.el.move(this.parameters.box.x, this.parameters.box.y).height(this.parameters.box.height + snap[1]); 26979 } 26980 }; 26981 break; 26982 26983 // Left 26984 case 'l': 26985 // s.a. 26986 this.calc = function (diffX, diffY) { 26987 var snap = this.snapToGrid(diffX, diffY, 1); 26988 if (this.parameters.box.width - snap[0] > 0) { 26989 if (this.parameters.type === "text") { 26990 return; 26991 } 26992 26993 this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y).width(this.parameters.box.width - snap[0]); 26994 } 26995 }; 26996 break; 26997 26998 // Rotation 26999 case 'rot': 27000 // s.a. 27001 this.calc = function (diffX, diffY) { 27002 27003 // yes this is kinda stupid but we need the mouse coords back... 27004 var current = {x: diffX + this.parameters.p.x, y: diffY + this.parameters.p.y}; 27005 27006 // start minus middle 27007 var sAngle = Math.atan2((this.parameters.p.y - this.parameters.box.y - this.parameters.box.height / 2), (this.parameters.p.x - this.parameters.box.x - this.parameters.box.width / 2)); 27008 27009 // end minus middle 27010 var pAngle = Math.atan2((current.y - this.parameters.box.y - this.parameters.box.height / 2), (current.x - this.parameters.box.x - this.parameters.box.width / 2)); 27011 27012 var angle = (pAngle - sAngle) * 180 / Math.PI; 27013 27014 // We have to move the element to the center of the box first and change the rotation afterwards 27015 // because rotation always works around a rotation-center, which is changed when moving the element 27016 // We also set the new rotation center to the center of the box. 27017 this.el.center(this.parameters.box.cx, this.parameters.box.cy).rotate(this.parameters.rotation + angle - angle % this.options.snapToAngle, this.parameters.box.cx, this.parameters.box.cy); 27018 }; 27019 break; 27020 27021 // Moving one single Point (needed when an element is deepSelected which means you can move every single point of the object) 27022 case 'point': 27023 this.calc = function (diffX, diffY) { 27024 27025 // Snapping the point to the grid
27026 var snap = this.snapToGrid(diffX, diffY, this.parameters.pointCoords[0], this.parameters.pointCoords[1]); 27027 27028 // Get the point array 27029 var array = this.el.array().valueOf(); 27030 27031 // Changing the moved point in the array 27032 array[this.parameters.i][0] = this.parameters.pointCoords[0] + snap[0]; 27033 array[this.parameters.i][1] = this.parameters.pointCoords[1] + snap[1]; 27034 27035 // And plot the new this.el 27036 this.el.plot(array); 27037 }; 27038 } 27039 27040 this.el.fire('resizestart', {dx: this.parameters.x, dy: this.parameters.y, event: event}); 27041 // When resizing started, we have to register events for... 27042 // Touches. 27043 SVG.on(window, 'touchmove.resize', function(e) { 27044 _this.update(e || window.event); 27045 }); 27046 SVG.on(window, 'touchend.resize', function() { 27047 _this.done(); 27048 }); 27049 // Mouse. 27050 SVG.on(window, 'mousemove.resize', function (e) { 27051 _this.update(e || window.event); 27052 }); 27053 SVG.on(window, 'mouseup.resize', function () { 27054 _this.done(); 27055 }); 27056 27057 }; 27058 27059 // The update-function redraws the element every time the mouse is moving 27060 ResizeHandler.prototype.update = function (event) { 27061 27062 if (!event) { 27063 if (this.lastUpdateCall) { 27064 this.calc(this.lastUpdateCall[0], this.lastUpdateCall[1]); 27065 } 27066 return; 27067 } 27068 27069 // Calculate the difference between the mouseposition at start and now 27070 var txPt = this._extractPosition(event); 27071 var p = this.transformPoint(txPt.x, txPt.y); 27072 27073 var diffX = p.x - this.parameters.p.x, 27074 diffY = p.y - this.parameters.p.y; 27075 27076 this.lastUpdateCall = [diffX, diffY]; 27077 27078 // Calculate the new position and height / width of the element 27079 this.calc(diffX, diffY); 27080 27081 // Emit an event to say we have changed. 27082 this.el.fire('resizing', {dx: diffX, dy: diffY, event: event}); 27083 }; 27084 27085 // Is called on mouseup. 27086 // Removes the update-function from the mousemove event 27087 ResizeHandler.prototype.done = function () { 27088 this.lastUpdateCall = null; 27089 SVG.off(window, 'mousemove.resize'); 27090 SVG.off(window, 'mouseup.resize'); 27091 SVG.off(window, 'touchmove.resize'); 27092 SVG.off(window, 'touchend.resize'); 27093 this.el.fire('resizedone'); 27094 }; 27095 27096 // The flag is used to determine whether the resizing is used with a left-Point (first bit) and top-point (second bit) 27097 // In this cases the temp-values are calculated differently 27098 ResizeHandler.prototype.snapToGrid = function (diffX, diffY, flag, pointCoordsY) { 27099 27100 var temp; 27101 27102 // If `pointCoordsY` is given, a single Point has to be snapped (deepSelect). That's why we need a different temp-value 27103 if (typeof pointCoordsY !== 'undefined') { 27104 // Note that flag = pointCoordsX in this case 27105 temp = [(flag + diffX) % this.options.snapToGrid, (pointCoordsY + diffY) % this.options.snapToGrid]; 27106 } else { 27107 // We check if the flag is set and if not we set a default-value (both bits set - which means upper-left-edge) 27108 flag = flag == null ? 1 | 1 << 1 : flag; 27109 temp = [(this.parameters.box.x + diffX + (flag & 1 ? 0 : this.parameters.box.width)) % this.options.snapToGrid, (this.parameters.box.y + diffY + (flag & (1 << 1) ? 0 : this.parameters.box.height)) % this.options.snapToGrid]; 27110 } 27111 27112 27113 diffX -= (Math.abs(temp[0]) < this.options.snapToGrid / 2 ? 27114 temp[0] : 27115 temp[0] - (diffX < 0 ? -this.options.snapToGrid : this.options.snapToGrid)); 27116 diffY -= (Math.abs(temp[1]) < this.options.snapToGrid / 2 ? 27117 temp[1] : 27118 temp[1] - (diffY < 0 ? -this.options.snapToGri
27118d : this.options.snapToGrid)); 27119 27120 return this.constraintToBox(diffX, diffY, flag, pointCoordsY); 27121 27122 }; 27123 27124 // keep element within constrained box 27125 ResizeHandler.prototype.constraintToBox = function (diffX, diffY, flag, pointCoordsY) { 27126 //return [diffX, diffY] 27127 var c = this.options.constraint || {}; 27128 var orgX, orgY; 27129 27130 if (typeof pointCoordsY !== 'undefined') { 27131 orgX = flag; 27132 orgY = pointCoordsY; 27133 } else { 27134 orgX = this.parameters.box.x + (flag & 1 ? 0 : this.parameters.box.width); 27135 orgY = this.parameters.box.y + (flag & (1<<1) ? 0 : this.parameters.box.height); 27136 } 27137 27138 if (typeof c.minX !== 'undefined' && orgX + diffX < c.minX) { 27139 diffX = c.minX - orgX; 27140 } 27141 27142 if (typeof c.maxX !== 'undefined' && orgX + diffX > c.maxX) { 27143 diffX = c.maxX - orgX; 27144 } 27145 27146 if (typeof c.minY !== 'undefined' && orgY + diffY < c.minY) { 27147 diffY = c.minY - orgY; 27148 } 27149 27150 if (typeof c.maxY !== 'undefined' && orgY + diffY > c.maxY) { 27151 diffY = c.maxY - orgY; 27152 } 27153 27154 return [diffX, diffY]; 27155 }; 27156 27157 ResizeHandler.prototype.checkAspectRatio = function (snap) { 27158 if (!this.options.saveAspectRatio) { 27159 return snap; 27160 } 27161 27162 var updatedSnap = snap.slice(); 27163 var aspectRatio = this.parameters.box.width / this.parameters.box.height; 27164 var newW = this.parameters.box.width + snap[0]; 27165 var newH = this.parameters.box.height - snap[1]; 27166 var newAspectRatio = newW / newH; 27167 27168 if (newAspectRatio < aspectRatio) { 27169 // Height is too big. Adapt it 27170 updatedSnap[1] = newW / aspectRatio - this.parameters.box.height; 27171 } else if (newAspectRatio > aspectRatio) {
27172 // Width is too big. Adapt it 27173 updatedSnap[0] = this.parameters.box.width - newH * aspectRatio; 27174 } 27175 27176 return updatedSnap; 27177 27178 }; 27179 27180 SVG.extend(SVG.Element, { 27181 // Resize element with mouse 27182 resize: function (options) { 27183 27184 (this.remember('_resizeHandler') || new ResizeHandler(this)).init(options || {}); 27185 27186 return this; 27187 27188 } 27189 27190 }); 27191 27192 SVG.Element.prototype.resize.defaults = { 27193 snapToAngle: 0.1, // Specifies the speed the rotation is happening when moving the mouse 27194 snapToGrid: 1, // Snaps to a grid of `snapToGrid` Pixels 27195 constraint: {}, // keep element within constrained box 27196 saveAspectRatio: false // Save aspect ratio when resizing using lt, rt, rb or lb points 27197 }; 27198 27199 }).call(this); 27200 }()); 27201 27202 function styleInject(css, ref) { 27203 if ( ref === void 0 ) ref = {}; 27204 var insertAt = ref.insertAt; 27205 27206 if (!css || typeof document === 'undefined') { return; } 27207 27208 var head = document.head || document.getElementsByTagName('head')[0]; 27209 var style = document.createElement('style'); 27210 style.type = 'text/css'; 27211 27212 if (insertAt === 'top') { 27213 if (head.firstChild) { 27214 head.insertBefore(style, head.firstChild); 27215 } else { 27216 head.appendChild(style); 27217 } 27218 } else { 27219 head.appendChild(style); 27220 } 27221 27222 if (style.styleSheet) { 27223 style.styleSheet.cssText = css; 27224 } else { 27225 style.appendChild(document.createTextNode(css)); 27226 } 27227 } 27228 27229 var css = ".apexcharts-canvas {\n position: relative;\n user-select: none;\n /* cannot give overflow: hidden as it will crop tooltips which overflow outside chart area */\n}\n\n/* scrollbar is not visible by default for legend, hence forcing the visibility */\n.apexcharts-canvas ::-webkit-scrollbar {\n -webkit-appearance: none;\n width: 6px;\n}\n.apexcharts-canvas ::-webkit-scrollbar-thumb {\n border-radius: 4px;\n background-color: rgba(0,0,0,.5);\n box-shadow: 0 0 1px rgba(255,255,255,.5);\n -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);\n}\n.apexcharts-canvas.dark {\n background: #343F57;\n}\n\n.apexcharts-inner {\n position: relative;\n}\n\n.legend-mouseover-inactive {\n transition: 0.15s ease all;\n opacity: 0.20;\n}\n\n.apexcharts-series-collapsed {\n opacity: 0;\n}\n\n.apexcharts-gridline, .apexcharts-text {\n pointer-events: none;\n}\n\n.apexcharts-tooltip {\n border-radius: 5px;\n box-shadow: 2px 2px 6px -4px #999;\n cursor: default;\n font-size: 14px;\n left: 62px;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n top: 20px;\n overflow: hidden;\n white-space: nowrap;\n z-index: 12;\n transition: 0.15s ease all;\n}\n.apexcharts-tooltip.light {\n border: 1px solid #e3e3e3;\n background: rgba(255, 255, 255, 0.96);\n}\n.apexcharts-tooltip.dark {\n color: #fff;\n background: rgba(30,30,30, 0.8);\n}\n.apexcharts-tooltip * {\n font-family: inherit;\n}\n\n.apexcharts-tooltip .apexcharts-marker,\n.apexcharts-area-series .apexcharts-area,\n.apexcharts-line {\n pointer-events: none;\n}\n\n.apexcharts-tooltip.active {\n opacity: 1;\n transition: 0.15s ease all;\n}\n\n.apexcharts-tooltip-title {\n padding: 6px;\n font-size: 15px;\n margin-bottom: 4px;\n}\n.apexcharts-tooltip.light .apexcharts-tooltip-title {\n background: #ECEFF1;\n border-bottom: 1px solid #ddd;\n}\n.apexcharts-tooltip.dark .apexcharts-tooltip-title {\n background: rgba(0, 0, 0, 0.7);\n border-bottom: 1px solid #333;\n}\n\n.apexcharts-tooltip-text-value,\n.apexcharts-tooltip-text-z-value {\n display: inline-block;\n font-weight: 600;\n margin-left: 5px;\n}\n\n.apexcharts-tooltip-text-z-label:empty,\n.apexcharts-tooltip-text-z-value:empty {\n display: none;\n}\n\n.apexcharts-tooltip-text-value, \n.apexcharts-tooltip-text-z-value {\n font-weight: 600;\n}\n\n.apexcharts-tooltip-marker {\n width: 12px;\n height: 12px;\n position: relative;\n top: 0px;\n margin-right: 10px;\n border-radius: 50%;\n}\n\n.apexcharts-tooltip-series-group {\n padding: 0 10px;\n display: none;\n text-align: left;\n justify-content: left;\n align-items: center;\n}\n\n.apexcharts-tooltip-series-group.active .apexcharts-tooltip-marker {\n opacity: 1;\n}\n.apexcharts-tooltip-series-group.active, .apexcharts-tooltip-series-group:last-child {\n padding-bottom: 4px;\n}\n.apexcharts-tooltip-series-group-hidden {\n opacity: 0;\n height: 0;\n line-height: 0;\n padding: 0 !important;\n}\n.apexcharts-tooltip-y-group {\n padding: 6px 0 5px;\n}\n.apexcharts-tooltip-candlestick {\n padding: 4px 8px;\n}\n.apexcharts-tooltip-candlestick > div {\n margin: 4px 0;\n}\n.apexcharts-tooltip-candlestick span.value {\n font-weight: bold;\n}\n\n.apexcharts-tooltip-rangebar {\n padding: 5px 8px;\n}\n\n.apexcharts-tooltip-rangebar .category {\n font-weight: 600;\n color: #777;\n}\n\n.apexcharts-tooltip-rangebar .series-name {\n font-weight: bold;\n display: block;\n margin-bottom: 5px;\n}\n\n.apexcharts-xaxistooltip {\n opacity: 0;\n padding: 9px 10px;\n pointer-events: none;\n color: #373d3f;\n font-size: 13px;\n text-align: center;\n border-radius: 2px;\n position: absolute;\n z-index: 10;\n\tbackground: #ECEFF1;\n border: 1px solid #90A4AE;\n transition: 0.15s ease all;\n}\n\n.apexcharts-xaxistooltip.dark {\n background: rgba(0, 0, 0, 0.7);\n border: 1px solid rgba(0, 0, 0, 0.5);\n color: #fff;\n}\n\n.apexcharts-xaxistooltip:after, .apexcharts-xaxistooltip:before {\n\tleft: 50%;\n\tborder: solid transparent;\n\tcontent: \" \";\n\theight: 0;\n\twidth: 0;\n\tposition: absolute;\n\tpointer-events: none;\n}\n\n.apexcharts-xaxistooltip:after {\n\tborder-color: rgba(236, 239, 241, 0);\n\tborder-width: 6px;\n\tmargin-left: -6px;\n}\n.apexcharts-xaxistooltip:before {\n\tborder-color: rgba(144, 164, 174, 0);\n\tborder-width: 7px;\n\tmargin-left: -7px;\n}\n\n.apexcharts-xaxistooltip-bottom:after, .apexcharts-xaxistooltip-bottom:before {\n bottom: 100%;\n}\n\n.apexcharts-xaxistooltip-top:after, .apexcharts-xaxistooltip-top:before {\n top: 100%;\n}\n\n.apexcharts-xaxistooltip-bottom:after {\n border-bottom-color: #ECEFF1;\n}\n.apexcharts-xaxistooltip-bottom:before {\n border-bottom-color: #90A4AE;\n}\n\n.apexcharts-xaxistooltip-bottom.dark:after {\n border-bottom-color: rgba(0, 0, 0, 0.5);\n}\n.apexcharts-xaxistooltip-bottom.dark:before {\n border-bottom-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-xaxistooltip-top:after {\n border-top-color:#ECEFF1\n}\n.apexcharts-xaxistooltip-top:before {\n border-top-color: #90A4AE;\n}\n.apexcharts-xaxistooltip-top.dark:after {\n border-top-color:rgba(0, 0, 0, 0.5);\n}\n.apexcharts-xaxistooltip-top.dark:before {\n border-top-color: rgba(0, 0, 0, 0.5);\n}\n\n\n.apexcharts-xaxistooltip.active {\n opacity: 1;\n transition: 0.15s ease all;\n}\n\n.apexcharts-yaxistooltip {\n opacity: 0;\n padding: 4px 10px;\n pointer-events: none;\n color: #373d3f;\n font-size: 13px;\n text-align: center;\n border-radius: 2px;\n position: absolute;\n z-index: 10;\n\tbackground: #ECEFF1;\n border: 1px solid #90A4AE;\n}\n\n.apexcharts-yaxistooltip.dark {\n background: rgba(0, 0, 0, 0.7);\n border: 1px solid rgba(0, 0, 0, 0.5);\n color: #fff;\n}\n\n.apexcharts-yaxistooltip:after, .apexcharts-yaxistooltip:before {\n\ttop: 50%;\n\tborder: solid transparent;\n\tcontent: \" \";\n\theight: 0;\n\twidth: 0;\n\tposition: absolute;\n\tpointer-events: none;\n}\n.apexcharts-yaxistooltip:after {\n\tborder-color: rgba(236, 239, 241, 0);\n\tborder-width: 6px;\n\tmargin-top: -6px;\n}\n.apexcharts-yaxistooltip:before {\n\tborder-color: rgba(144, 164, 174, 0);\n\tborder-width: 7px;\n\tmargin-top: -7px;\n}\n\n.apexcharts-yaxistooltip-left:after, .apexcharts-yaxistooltip-left:before {\n left: 100%;\n}\n\n.apexcharts-yaxistooltip-right:after, .apexcharts-yaxistooltip-right:before {\n right: 100%;\n}\n\n.apexcharts-yaxistooltip-left:after {\n border-left-color: #ECEFF1;\n}\n.apexcharts-yaxistooltip-left:before {\n border-left-color: #90A4AE;\n}\n.apexcharts-yaxistooltip-left.dark:after {\n border-left-color: rgba(0, 0, 0, 0.5);\n}\n.apexcharts-yaxistooltip-left.dark:before {\n border-left-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-yaxistooltip-right:after {\n border-right-color: #ECEFF1;\n}\n.apexcharts-yaxistooltip-right:before {\n border-right-color: #90A4AE;\n}\n.apexcharts-yaxistooltip-right.dark:after {\n border-right-color: rgba(0, 0, 0, 0.5);\n}\n.apexcharts-yaxistooltip-right.dark:before {\n border-right-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-yaxistooltip.active {\n opacity: 1;\n}
27229\n\n.apexcharts-xcrosshairs, .apexcharts-ycrosshairs {\n pointer-events: none;\n opacity: 0;\n transition: 0.15s ease all;\n}\n\n.apexcharts-xcrosshairs.active, .apexcharts-ycrosshairs.active {\n opacity: 1;\n transition: 0.15s ease all;\n}\n\n.apexcharts-ycrosshairs-hidden {\n opacity: 0;\n}\n\n.apexcharts-zoom-rect {\n pointer-events: none;\n}\n.apexcharts-selection-rect {\n cursor: move;\n}\n\n.svg_select_points, .svg_select_points_rot {\n opacity: 0;\n visibility: hidden;\n}\n.svg_select_points_l, .svg_select_points_r {\n cursor: ew-resize;\n opacity: 1;\n visibility: visible;\n fill: #888;\n}\n.apexcharts-canvas.zoomable .hovering-zoom {\n cursor: crosshair\n}\n.apexcharts-canvas.zoomable .hovering-pan {\n cursor: move\n}\n\n.apexcharts-xaxis,\n.apexcharts-yaxis {\n pointer-events: none;\n}\n\n.apexcharts-zoom-icon, \n.apexcharts-zoom-in-icon,\n.apexcharts-zoom-out-icon,\n.apexcharts-reset-zoom-icon, \n.apexcharts-pan-icon, \n.apexcharts-selection-icon,\n.apexcharts-menu-icon, \n.apexcharts-toolbar-custom-icon {\n cursor: pointer;\n width: 20px;\n height: 20px;\n line-height: 24px;\n color: #6E8192;\n text-align: center;\n}\n\n\n.apexcharts-zoom-icon svg, \n.apexcharts-zoom-in-icon svg,\n.apexcharts-zoom-out-icon svg,\n.apexcharts-reset-zoom-icon svg,\n.apexcharts-menu-icon svg {\n fill: #6E8192;\n}\n.apexcharts-selection-icon svg {\n fill: #444;\n transform: scale(0.76)\n}\n\n.dark .apexcharts-zoom-icon svg, \n.dark .apexcharts-zoom-in-icon svg,\n.dark .apexcharts-zoom-out-icon svg,\n.dark .apexcharts-reset-zoom-icon svg, \n.dark .apexcharts-pan-icon svg, \n.dark .apexcharts-selection-icon svg,\n.dark .apexcharts-menu-icon svg, \n.dark .apexcharts-toolbar-custom-icon svg{\n fill: #f3f4f5;\n}\n\n.apexcharts-canvas .apexcharts-zoom-icon.selected svg, \n.apexcharts-canvas .apexcharts-selection-icon.selected svg, \n.apexcharts-canvas .apexcharts-reset-zoom-icon.selected svg {\n fill: #008FFB;\n}\n.light .apexcharts-selection-icon:not(.selected):hover svg,\n.light .apexcharts-zoom-icon:not(.selected):hover svg, \n.light .apexcharts-zoom-in-icon:hover svg, \n.light .apexcharts-zoom-out-icon:hover svg, \n.light .apexcharts-reset-zoom-icon:hover svg, \n.light .apexcharts-menu-icon:hover svg {\n fill: #333;\n}\n\n.apexcharts-selection-icon, .apexcharts-menu-icon {\n position: relative;\n}\n.apexcharts-reset-zoom-icon {\n margin-left: 5px;\n}\n.apexcharts-zoom-icon, .apexcharts-reset-zoom-icon, .apexcharts-menu-icon {\n transform: scale(0.85);\n}\n\n.apexcharts-zoom-in-icon, .apexcharts-zoom-out-icon {\n transform: scale(0.7)\n}\n\n.apexcharts-zoom-out-icon {\n margin-right: 3px;\n}\n\n.apexcharts-pan-icon {\n transform: scale(0.62);\n position: relative;\n left: 1px;\n top: 0px;\n}\n.apexcharts-pan-icon svg {\n fill: #fff;\n stroke: #6E8192;\n stroke-width: 2;\n}\n.apexcharts-pan-icon.selected svg {\n stroke: #008FFB;\n}\n.apexcharts-pan-icon:not(.selected):hover svg {\n stroke: #333;\n}\n\n.apexcharts-toolbar {\n position: absolute;\n z-index: 11;\n top: 0px;\n right: 3px;\n max-width: 176px;\n text-align: right;\n border-radius: 3px;\n padding: 0px 6px 2px 6px;\n display: flex;\n justify-content: space-between;\n align-items: center; \n}\n\n.apexcharts-toolbar svg {\n pointer-events: none;\n}\n\n.apexcharts-menu {\n background: #fff;\n position: absolute;\n top: 100%;\n border: 1px solid #ddd;\n border-radius: 3px;\n padding: 3px;\n right: 10px;\n opacity: 0;\n min-width: 110px;\n transition: 0.15s ease all;\n pointer-events: none;\n}\n\n.apexcharts-menu.open {\n opacity: 1;\n pointer-events: all;\n transition: 0.15s ease all;\n}\n\n.apexcharts-menu-item {\n padding: 6px 7px;\n font-size: 12px;\n cursor: pointer;\n}\n.light .apexcharts-menu-item:hover {\n background: #eee;\n}\n.dark .apexcharts-menu {\n background: rgba(0, 0, 0, 0.7);\n color: #fff;\n}\n\n@media screen and (min-width: 768px) {\n .apexcharts-toolbar {\n /*opacity: 0;*/\n }\n\n .apexcharts-canvas:hover .apexcharts-toolbar {\n opacity: 1;\n } \n}\n\n.apexcharts-datalabel.hidden {\n opacity: 0;\n}\n\n.apexcharts-pie-label,\n.apexcharts-datalabel, .apexcharts-datalabel-label, .apexcharts-datalabel-value {\n cursor: default;\n pointer-events: none;\n}\n\n.apexcharts-pie-label-delay {\n opacity: 0;\n animation-name: opaque;\n animation-duration: 0.3s;\n animation-fill-mode: forwards;\n animation-timing-function: ease;\n}\n\n.apexcharts-canvas .hidden {\n opacity: 0;\n}\n\n.apexcharts-hide .apexcharts-series-points {\n opacity: 0;\n}\n\n.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,\n.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events, .apexcharts-radar-series path, .apexcharts-radar-series polygon {\n pointer-events: none;\n}\n\n/* markers */\n\n.apexcharts-marker {\n transition: 0.15s ease all;\n}\n\n@keyframes opaque {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}"; 27230 styleInject(css); 27231 27232 /* 27233 * classList.js: Cross-browser full element.classList implementation. 27234 * 1.2.20171210 27235 * 27236 * By Eli Grey, http://eligrey.com 27237 * License: Dedicated to the public domain. 27238 * See https://github.com/eligrey/classList.js/blob/master/LICENSE.md 27239 */ 27240 27241 /*global self, document, DOMException */ 27242 27243 /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */ 27244 if ("document" in self) { 27245 // Full polyfill for browsers with no classList support 27246 // Including IE < Edge missing SVGElement.classList 27247 if (!("classList" in document.createElement("_")) || document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg", "g"))) { 27248 (function (view) { 27249 27250 if (!('Element' in view)) return; 27251 27252 var classListProp = "classList", 27253 protoProp = "prototype", 27254 elemCtrProto = view.Element[protoProp], 27255 objCtr = Object, 27256 strTrim = String[protoProp].trim || function () { 27257 return this.replace(/^\s+|\s+$/g, ""); 27258 }, 27259 arrIndexOf = Array[protoProp].indexOf || function (item) { 27260 var i = 0, 27261 len = this.length; 27262 27263 for (; i < len; i++) { 27264 if (i in this && this[i] === item) { 27265 return i; 27266 } 27267 } 27268 27269 return -1; 27270 } // Vendors: please allow content code to instantiate DOMExceptions 27271 , 27272 DOMEx = function DOMEx(type, message) { 27273 this.name = type; 27274 this.code = DOMException[type]; 27275 this.message = message; 27276 }, 27277 checkTokenAndGetIndex = function checkTokenAndGetIndex(classList, token) { 27278 if (token === "") { 27279 throw new DOMEx("SYNTAX_ERR", "The token must not be empty."); 27280 } 27281 27282 if (/\s/.test(token)) { 27283 throw new DOMEx("INVALID_CHARACTER_ERR", "The token must not contain space characters."); 27284 } 27285 27286 return arrIndexOf.call(classList, token); 27287 }, 27288 ClassList = function ClassList(elem) { 27289 var trimmedClasses = strTrim.call(elem.getAttribute("class") || ""), 27290 classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [], 27291 i = 0, 27292 len = classes.length; 27293 27294 for (; i < len; i++) { 27295 this.push(classes[i]); 27296 } 27297 27298 this._updateClassName = function () { 27299 elem.setAttribute("class", this.toString()); 27300 }; 27301 }, 27302 classListProto = ClassList[protoProp] = [], 27303 classListGetter = function classListGetter() { 27304 return new ClassList(this); 27305 }; // Most DOMException implementations don't allow calling DOMException's toString() 27306 // on non-DOMExceptions. Error's toString() is sufficient here. 27307 27308 27309 DOMEx[protoProp] = Error[protoProp]; 27310 27311 classListProto.item = function (i) { 27312 return this[i] || null; 27313 }; 27314 27315 classListProto.contains = function (token) { 27316 return ~checkTokenAndGetIndex(this, token + ""); 27317 }; 27318 27319 classListProto.add = function () { 27320 var tokens = arguments, 27321 i = 0, 27322 l = tokens.length, 27323 token, 27324 updated = false; 27325 27326 do { 27327 token = tokens[i] + ""; 27328 27329 if (!~checkTokenAndGetIndex(this, token)) { 27330 this.push(token); 27331 updated = true; 27332 } 27333 } while (++i < l); 27334 27335 if (updated) { 27336 this._updateClassName(); 27337 } 27338 }; 27339 27340 classListProto.remove = function () { 27341 var tokens = arguments, 27342 i = 0, 27343 l = tokens.length, 27344 token, 27345 updated = false, 27346 index; 27347 27348 do { 27349 token = tokens[i] + ""; 27350 index = checkTokenAndGetIndex(this, token); 27351 27352 while (~index) { 27353 this.splice(index, 1); 27354 updated = true; 27355 index = checkTokenAndGetIndex(this, token); 27356 } 27357 } while (++i < l); 27358 27359 if (updated) { 27360 this._updateClassName(); 27361 } 27362 }; 27363 27364 classListProto.toggle = function (token, force) { 27365 var result = this.contains(token), 27366 method = result ? force !== true && "remove" : force !== false && "add"; 27367 27368 if (method) { 27369 this[method](token); 27370 } 27371 27372 if (force === true || force === false) { 27373 return force; 27374 } else { 27375 return !result; 27376 } 27377 }; 27378 27379 classListProto.replace = function (token, replacement_token) { 27380 var index = checkTokenAndGetIndex(token + ""); 27381 27382 if (~index) { 27383 this.splice(index, 1, replacement_token); 27384 27385 this._updateClassName(); 27386 } 27387 }; 27388 27389 classListProto.toString = function () { 27390 return this.join(" "); 27391 }; 27392 27393 if (objCtr.defineProperty) { 27394 var classListPropDesc = { 27395 get: classListGetter, 27396 enumerable: true, 27397 configurable: true 27398 }; 27399 27400 try { 27401 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 27402 } catch (ex) { 27403 // IE 8 doesn't support enumerable:true 27404 // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36 27405 // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected 27406 if (ex.number === undefined || ex.number === -0x7FF5EC54) { 27407 classListPropDesc.enumerable = false; 27408 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 27409 } 27410 } 27411 } else if (objCtr[protoProp].__defineGetter__) { 27412 elemCtrProto.__defineGetter__(classListProp, classListGetter); 27413 } 27414 })(self); 27415 } // There is full or partial native classList support, so just check if we need 27416 // to normalize the add/remove and toggle APIs. 27417 27418 27419 (function () { 27420 27421 var testElement = document.createElement("_"); 27422 testElement.classList.add("c1", "c2"); // Polyfill for IE 10/11 and Firefox <26, where classList.add and 27423 // classList.remove exist but support only one argument at a time. 27424 27425 if (!testElement.classList.contains("c2")) {
27426 var createMethod = function createMethod(method) { 27427 var original = DOMTokenList.prototype[method]; 27428 27429 DOMTokenList.prototype[method] = function (token) { 27430 var i, 27431 len = arguments.length; 27432 27433 for (i = 0; i < len; i++) { 27434 token = arguments[i]; 27435 original.call(this, token); 27436 } 27437 }; 27438 }; 27439 27440 createMethod('add'); 27441 createMethod('remove'); 27442 } 27443 27444 testElement.classList.toggle("c3", false); // Polyfill for IE 10 and Firefox <24, where classList.toggle does not 27445 // support the second argument. 27446 27447 if (testElement.classList.contains("c3")) { 27448 var _toggle = DOMTokenList.prototype.toggle; 27449 27450 DOMTokenList.prototype.toggle = function (token, force) { 27451 if (1 in arguments && !this.contains(token) === !force) { 27452 return force; 27453 } else { 27454 return _toggle.call(this, token); 27455 } 27456 }; 27457 } // replace() polyfill 27458 27459 27460 if (!("replace" in document.createElement("_").classList)) { 27461 DOMTokenList.prototype.replace = function (token, replacement_token) { 27462 var tokens = this.toString().split(" "), 27463 index = tokens.indexOf(token + ""); 27464 27465 if (~index) { 27466 tokens = tokens.slice(index); 27467 this.remove.apply(this, tokens); 27468 this.add(replacement_token); 27469 this.add.apply(this, tokens.slice(1)); 27470 } 27471 }; 27472 } 27473 27474 testElement = null; 27475 })(); 27476 } 27477 27478 /** 27479 * Detect Element Resize 27480 * 27481 * https://github.com/sdecima/javascript-detect-element-resize 27482 * Sebastian Decima 27483 * 27484 * version: 0.5.3 27485 **/ 27486 (function () { 27487 var stylesCreated = false; 27488 27489 function resetTriggers(element) { 27490 var triggers = element.__resizeTriggers__, 27491 expand = triggers.firstElementChild, 27492 contract = triggers.lastElementChild, 27493 expandChild = expand.firstElementChild; 27494 contract.scrollLeft = contract.scrollWidth; 27495 contract.scrollTop = contract.scrollHeight; 27496 expandChild.style.width = expand.offsetWidth + 1 + 'px'; 27497 expandChild.style.height = expand.offsetHeight + 1 + 'px'; 27498 expand.scrollLeft = expand.scrollWidth; 27499 expand.scrollTop = expand.scrollHeight; 27500 } 27501 27502 function checkTriggers(element) { 27503 return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height; 27504 } 27505 27506 function scrollListener(e) { 27507 var element = this; 27508 resetTriggers(this); 27509 if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__); 27510 this.__resizeRAF__ = requestFrame(function () { 27511 if (checkTriggers(element)) { 27512 element.__resizeLast__.width = element.offsetWidth; 27513 element.__resizeLast__.height = element.offsetHeight; 27514 27515 element.__resizeListeners__.forEach(function (fn) { 27516 fn.call(e); 27517 }); 27518 } 27519 }); 27520 } 27521 27522 function createStyles() { 27523 if (!stylesCreated) { 27524 // opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360 27525 var css = (animationKeyframes || '') + '.resize-triggers { ' + (animationStyle || '') + 'visibility: hidden; opacity: 0; } ' + '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }', 27526 head = document.head || document.getElementsByTagName('head')[0], 27527 style = document.createElement('style'); 27528 style.type = 'text/css'; 27529 27530 if (style.styleSheet) { 27531 style.styleSheet.cssText = css; 27532 } else { 27533 style.appendChild(document.createTextNode(css)); 27534 } 27535 27536 head.appendChild(style); 27537 stylesCreated = true; 27538 } 27539 } 27540 27541 var requestFrame = function () { 27542 var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function (fn) { 27543 return window.setTimeout(fn, 20); 27544 }; 27545 27546 return function (fn) { 27547 return raf(fn); 27548 }; 27549 }(); 27550 27551 var cancelFrame = function () { 27552 var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout; 27553 return function (id) { 27554 return cancel(id); 27555 }; 27556 }();
27557 /* Detect CSS Animations support to detect element display/re-attach */ 27558 27559 27560 var animation = false, 27561 keyframeprefix = '', 27562 animationstartevent = 'animationstart', 27563 domPrefixes = 'Webkit Moz O ms'.split(' '), 27564 startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '), 27565 pfx = ''; 27566 { 27567 var elm = document.createElement('fakeelement'); 27568 27569 if (elm.style.animationName !== undefined) { 27570 animation = true; 27571 } 27572 27573 if (animation === false) { 27574 for (var i = 0; i < domPrefixes.length; i++) { 27575 if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { 27576 pfx = domPrefixes[i]; 27577 keyframeprefix = '-' + pfx.toLowerCase() + '-'; 27578 animationstartevent = startEvents[i]; 27579 break; 27580 } 27581 } 27582 } 27583 } 27584 var animationName = 'resizeanim'; 27585 var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } '; 27586 var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; '; 27587 27588 window.addResizeListener = function (element, fn) { 27589 if (!element.__resizeTriggers__) { 27590 if (getComputedStyle(element).position == 'static') element.style.position = 'relative'; 27591 createStyles(); 27592 element.__resizeLast__ = {}; 27593 element.__resizeListeners__ = []; 27594 (element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers'; 27595 element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' + '<div class="contract-trigger"></div>'; 27596 element.appendChild(element.__resizeTriggers__); 27597 resetTriggers(element); 27598 element.addEventListener('scroll', scrollListener, true); 27599 /* Listen for a css animation to detect element display/re-attach */ 27600 27601 animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function (e) { 27602 if (e.animationName == animationName) { 27603 resetTriggers(element); 27604 } 27605 }); 27606 } 27607 27608 element.__resizeListeners__.push(fn); 27609 }; 27610 27611 window.removeResizeListener = function (element, fn) { 27612 if (element) { 27613 element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); 27614 27615 if (!element.__resizeListeners__.length) { 27616 element.removeEventListener('scroll', scrollListener); 27617 element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); 27618 } 27619 } 27620 }; 27621 })(); 27622 27623 window.Apex = {}; 27624 /** 27625 * 27626 * @module ApexCharts 27627 **/ 27628 27629 var ApexCharts$1 = 27630 /*#__PURE__*/ 27631 function () { 27632 function ApexCharts(el, opts) { 27633 _classCallCheck(this, ApexCharts); 27634 27635 this.opts = opts; 27636 this.ctx = this; // Pass the user supplied options to the Base Class where these options will be extended with defaults. The returned object from Base Class will become the config object in the entire codebase. 27637 27638 this.w = new Base(opts).init(); 27639 this.el = el; 27640 this.w.globals.cuid = (Math.random() + 1).toString(36).substring(4); 27641 this.w.globals.chartID = this.w.config.chart.id ? this.w.config.chart.id : this.w.globals.cuid; 27642 this.initModules(); 27643 this.create = Utils.bind(this.create, this); 27644 this.windowResizeHandler = this.windowResize.bind(this); 27645 } 27646 /** 27647 * The primary method user will call to render the chart. 27648 */ 27649 27650 27651 _createClass(ApexCharts, [{ 27652 key: "render", 27653 value: function render() { 27654 var _this = this; 27655 27656 // main method 27657 return new Promise$1(function (resolve, reject) { 27658 // only draw chart, if element found 27659 if (_this.el !== null) { 27660 if (typeof Apex._chartInstances === 'undefined') { 27661 Apex._chartInstances = []; 27662 } 27663 27664 if (_this.w.config.chart.id) { 27665 Apex._chartInstances.push({ 27666 id: _this.w.globals.chartID, 27667 group: _this.w.config.chart.group, 27668 chart: _this 27669 }); 27670 } // set the locale here 27671 27672 27673 _this.setLocale(_this.w.config.chart.defaultLocale); 27674 27675 var beforeMount = _this.w.config.chart.events.beforeMount; 27676 27677 if (typeof beforeMount === 'function') { 27678 beforeMount(_this, _this.w); 27679 } 27680 27681 _this.fireEvent('beforeMount', [_this, _this.w]); 27682 27683 window.addEventListener('resize', _this.windowResizeHandler); 27684 window.addResizeListener(_this.el.parentNode, _this.parentResizeCallback.bind(_this)); 27685 27686 var graphData = _this.create(_this.w.config.series, {}); 27687 27688 if (!graphData) return resolve(_this); 27689 27690 _this.mount(graphData).then(function () { 27691 resolve(graphData); 27692
27693 if (typeof _this.w.config.chart.events.mounted === 'function') { 27694 _this.w.config.chart.events.mounted(_this, _this.w); 27695 } 27696 27697 _this.fireEvent('mounted', [_this, _this.w]); 27698 }).catch(function (e) { 27699 reject(e); // handle error in case no data or element not found 27700 }); 27701 } else { 27702 reject(new Error('Element not found')); 27703 } 27704 }); 27705 } 27706 }, { 27707 key: "initModules", 27708 value: function initModules() { 27709 this.animations = new Animations(this); 27710 this.core = new Core(this.el, this); 27711 this.grid = new Grid(this); 27712 this.coreUtils = new CoreUtils(this); 27713 this.config = new Config({}); 27714 this.crosshairs = new Crosshairs(this); 27715 this.options = new Options(); 27716 this.responsive = new Responsive(this); 27717 this.series = new Series(this); 27718 this.theme = new Theme(this); 27719 this.formatters = new Formatters(this); 27720 this.titleSubtitle = new TitleSubtitle(this); 27721 this.legend = new Legend(this); 27722 this.toolbar = new Toolbar(this); 27723 this.dimensions = new Dimensions(this); 27724 this.zoomPanSelection = new ZoomPanSelection(this); 27725 this.w.globals.tooltip = new Tooltip(this); 27726 } 27727 }, { 27728 key: "addEventListener", 27729 value: function addEventListener(name$$1, handler) { 27730 var w = this.w; 27731 27732 if (w.globals.events.hasOwnProperty(name$$1)) { 27733 w.globals.events[name$$1].push(handler); 27734 } else { 27735 w.globals.events[name$$1] = [handler]; 27736 } 27737 } 27738 }, { 27739 key: "removeEventListener", 27740 value: function removeEventListener(name$$1, handler) { 27741 var w = this.w; 27742 27743 if (!w.globals.events.hasOwnProperty(name$$1)) { 27744 return; 27745 } 27746 27747 var index = w.globals.events[name$$1].indexOf(handler); 27748 27749 if (index !== -1) { 27750 w.globals.events[name$$1].splice(index, 1); 27751 } 27752 } 27753 }, { 27754 key: "fireEvent", 27755 value: function fireEvent(name$$1, args) { 27756 var w = this.w; 27757 27758 if (!w.globals.events.hasOwnProperty(name$$1)) { 27759 return; 27760 } 27761 27762 if (!args || !args.length) { 27763 args = []; 27764 } 27765 27766 var evs = w.globals.events[name$$1]; 27767 var l = evs.length; 27768 27769 for (var i = 0; i < l; i++) { 27770 evs[i].apply(null, args); 27771 } 27772 } 27773 }, { 27774 key: "create", 27775 value: function create(ser, opts) { 27776 var w = this.w; 27777 this.initModules(); 27778 var gl = this.w.globals; 27779 gl.noData = false; 27780 gl.animationEnded = false; 27781 this.responsive.checkResponsiveConfig(opts); 27782 27783 if (this.el === null) { 27784 gl.animationEnded = true; 27785 return null; 27786 } 27787 27788 this.core.setupElements(); 27789 27790 if (gl.svgWidth === 0) { 27791 // if the element is hidden, skip drawing 27792 gl.animationEnded = true; 27793 return null; 27794 } 27795 27796 var combo = CoreUtils.checkComboSeries(ser); 27797 gl.comboCharts = combo.comboCharts; 27798 gl.comboChartsHasBars = combo.comboChartsHasBars; 27799 27800 if (ser.length === 0 || ser.length === 1 && ser[0].data && ser[0].data.length === 0) { 27801 this.series.handleNoData(); 27802 } 27803 27804 this.setupEventHandlers(); // Handle the data inputted by user and set some of the global variables (for eg, if data is datetime / numeric / category). Don't calculate the range / min / max at this time 27805 27806 this.core.parseData(ser); // this is a good time to set theme colors first 27807 27808 this.theme.init(); // as markers accepts array, we need to setup global markers for easier access 27809 27810 var markers = new Markers(this); 27811 markers.setGlobalMarkerSize(); // labelFormatters should be called before dimensions as in dimensions we need text labels width 27812 27813 this.formatters.setLabelFormatters(); 27814 this.titleSubtitle.draw(); // legend is calculated here before coreCalculations because it affects the plottable area 27815 27816 this.legend.init(); // check whether in multiple series, all series share the same X 27817 27818 this.series.hasAllSeriesEqualX(); // coreCalculations will give the min/max range and yaxis/axis values. It should be called here to set series variable from config to globals 27819 27820 if (gl.axisCharts) { 27821 this.core.coreCalculations(); 27822 27823 if (w.config.xaxis.type !== 'category') { 27824 // as we have minX and maxX values, determine the default DateTimeFormat for time series 27825 this.formatters.setLabelFormatters(); 27826 } 27827 } // we need to generate yaxis for heatmap separately as we are not showing numerics there, but seriesNames. There are some tweaks which are required for heatmap to align labels correctly which are done in below function 27828 // Also we need to do this before calcuting Dimentions plotCoords() method of Dimensions 27829 27830 27831 this.formatters.heatmapLabelFormatters(); // We got plottable area here, next task would be to calculate axis areas 27832 27833 this.dimensions.plotCoords(); 27834 var xyRatios = this.core.xySettings();
27835 this.grid.createGridMask(); 27836 var elGraph = this.core.plotChartType(ser, xyRatios); // after all the drawing calculations, shift the graphical area (actual charts/bars) excluding legends 27837 27838 this.core.shiftGraphPosition(); 27839 var dim = { 27840 plot: { 27841 left: w.globals.translateX, 27842 top: w.globals.translateY, 27843 width: w.globals.gridWidth, 27844 height: w.globals.gridHeight 27845 } 27846 }; 27847 return { 27848 elGraph: elGraph, 27849 xyRatios: xyRatios, 27850 elInner: w.globals.dom.elGraphical, 27851 dimensions: dim 27852 }; 27853 } 27854 }, { 27855 key: "mount", 27856 value: function mount() { 27857 var graphData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 27858 var me = this; 27859 var w = me.w; 27860 return new Promise$1(function (resolve, reject) { 27861 // no data to display 27862 if (me.el === null) { 27863 return reject(new Error('Not enough data to display or target element not found')); 27864 } else if (graphData === null || w.globals.allSeriesCollapsed) { 27865 me.series.handleNoData(); 27866 } 27867 27868 me.annotations = new Annotations(me); 27869 me.core.drawAxis(w.config.chart.type, graphData.xyRatios); 27870 me.grid = new Grid(me); 27871 27872 if (w.config.grid.position === 'back') { 27873 me.grid.drawGrid(); 27874 } 27875 27876 if (w.config.annotations.position === 'back') { 27877 me.annotations.drawAnnotations(); 27878 } 27879 27880 if (graphData.elGraph instanceof Array) { 27881 for (var g = 0; g < graphData.elGraph.length; g++) { 27882 w.globals.dom.elGraphical.add(graphData.elGraph[g]); 27883 } 27884 } else { 27885 w.globals.dom.elGraphical.add(graphData.elGraph); 27886 } 27887 27888 if (w.config.grid.position === 'front') { 27889 me.grid.drawGrid(); 27890 } 27891 27892 if (w.config.xaxis.crosshairs.position === 'front') { 27893 me.crosshairs.drawXCrosshairs(); 27894 } 27895 27896 if (w.config.yaxis[0].crosshairs.position === 'front') { 27897 me.crosshairs.drawYCrosshairs(); 27898 } 27899 27900 if (w.config.annotations.position === 'front') { 27901 me.annotations.drawAnnotations(); 27902 } 27903 27904 if (!w.globals.noData) { 27905 // draw tooltips at the end 27906 if (w.config.tooltip.enabled && !w.globals.noData) { 27907 me.w.globals.tooltip.drawTooltip(graphData.xyRatios); 27908 } 27909 27910 if (w.globals.axisCharts && w.globals.isXNumeric) { 27911 if (w.config.chart.zoom.enabled || w.config.chart.selection && w.config.chart.selection.enabled || w.config.chart.pan && w.config.chart.pan.enabled) { 27912 me.zoomPanSelection.init({ 27913 xyRatios: graphData.xyRatios 27914 }); 27915 } 27916 } else { 27917 var tools = w.config.chart.toolbar.tools; 27918 tools.zoom = false; 27919 tools.zoomin = false; 27920 tools.zoomout = false; 27921 tools.selection = false; 27922 tools.pan = false; 27923 tools.reset = false; 27924 } 27925 27926 if (w.config.chart.toolbar.show && !w.globals.allSeriesCollapsed) { 27927 me.toolbar.createToolbar(); 27928 } 27929 } 27930 27931 if (w.globals.memory.methodsToExec.length > 0) { 27932 w.globals.memory.methodsToExec.forEach(function (fn) { 27933 fn.method(fn.params, false, fn.context); 27934 }); 27935 } 27936 27937 resolve(me); 27938 }); 27939 } 27940 }, { 27941 key: "clearPreviousPaths", 27942 value: function clearPreviousPaths() { 27943 var w = this.w; 27944 w.globals.previousPaths = []; 27945 w.globals.allSeriesCollapsed = false; 27946 w.globals.collapsedSeries = []; 27947 w.globals.collapsedSeriesIndices = []; 27948 } 27949 /** 27950 * Allows users to update Options after the chart has rendered. 27951 * 27952 * @param {object} options - A new config object can be passed which will be merged with the existing config object 27953 * @param {boolean} redraw - should redraw from beginning or should use existing paths and redraw from there 27954 * @param {boolean} animate - should animate or not on updating Options 27955 */ 27956 27957 }, { 27958 key: "updateOptions", 27959 value: function updateOptions(options$$1) { 27960 var redraw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 27961 var animate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; 27962 var overwriteInitialConfig = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; 27963 var w = this.w; 27964 27965 if (options$$1.series) { 27966 if (options$$1.series[0].data) { 27967 options$$1.series = options$$1.series.map(function (s, i) { 27968 return _objectSpread({}, w.config.series[i], { 27969 name: s.name ? s.name : w.config.series[i] && w.config.series[i].name, 27970 type: s.type ? s.type : w.config.series[i] && w.config.series[i].type, 27971 data: s.data ? s.data : w.config.series[i] && w.config.series[i].data 27972 }); 27973 }); 27974 } // user updated the series via updateOptions() function. 27975 // Hence, we need to reset axis min/max to avoid zooming issues 27976 27977 27978 this.revertDefaultAxisMinMax(); 27979 } // user has set x-axis min/max externally - hence we need to forcefully set the xaxis min/max 27980 27981 27982 if (options$$1.xaxis) { 27983 if (options$$1.xaxis.min || options$$1.xaxis.max) { 27984 this.forceXAxisUpdate(options$$1); 27985 } 27986 /* fixes apexcharts.js#369 and react-apexcharts#46 */ 27987 27988 27989 if (options$$1.xaxis.categories && options$$1.xaxis.categories.length && w.config.xaxis.convertedCatToNumeric) { 27990 options$$1 = Defaults.convertCatToNumeric(options$$1); 27991 } 27992 } 27993 27994 if (w.globals.collapsedSeriesIndices.length > 0) { 27995 this.clearPreviousPaths(); 27996 } 27997 /* update theme mode#459 */ 27998 27999 28000 if (options$$1.theme) { 28001 options$$1 = this.theme.updateThemeOptions(options$$1); 28002 } 28003 28004 return this._updateOptions(options$$1, redraw, animate, overwriteInitialConfig); 28005 } 28006 /** 28007 * private method to update Options. 28008 * 28009 * @param {object} options - A new config object can be passed which will be merged with the existing config object 28010 * @param {boolean} redraw - should redraw from beginning or should use existing paths and redraw from there 28011 * @param {boolean} animate - should animate or not on updating Options 28012 * @param {boolean} overwriteInitialConfig - should update the initial config or not 28013 */ 28014 28015 }, { 28016 key: "_updateOptions", 28017 value: function _updateOptions(options$$1) { 28018 var redraw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 28019 var animate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; 28020 var overwriteInitialConfig = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
28021 var charts = this.getSyncedCharts(); 28022 charts.forEach(function (ch) { 28023 var w = ch.w; 28024 w.globals.shouldAnimate = animate; 28025 28026 if (!redraw) { 28027 w.globals.resized = true; 28028 w.globals.dataChanged = true; 28029 28030 if (animate) { 28031 ch.series.getPreviousPaths(); 28032 } 28033 } 28034 28035 if (options$$1 && _typeof(options$$1) === 'object') { 28036 ch.config = new Config(options$$1); 28037 options$$1 = CoreUtils.extendArrayProps(ch.config, options$$1); 28038 w.config = Utils.extend(w.config, options$$1); 28039 28040 if (overwriteInitialConfig) { 28041 // we need to forget the lastXAxis and lastYAxis is user forcefully overwriteInitialConfig. If we do not do this, and next time when user zooms the chart after setting yaxis.min/max or xaxis.min/max - the stored lastXAxis will never allow the chart to use the updated min/max by user. 28042 w.globals.lastXAxis = []; 28043 w.globals.lastYAxis = []; // After forgetting lastAxes, we need to restore the new config in initialConfig/initialSeries 28044 28045 w.globals.initialConfig = Utils.extend({}, w.config); 28046 w.globals.initialSeries = JSON.parse(JSON.stringify(w.config.series)); 28047 } 28048 } 28049 28050 return ch.update(options$$1); 28051 }); 28052 } 28053 /** 28054 * Allows users to update Series after the chart has rendered. 28055 * 28056 * @param {array} series - New series which will override the existing 28057 */ 28058 28059 }, { 28060 key: "updateSeries", 28061 value: function updateSeries() { 28062 var newSeries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 28063 var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28064 var overwriteInitialSeries = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; 28065 this.revertDefaultAxisMinMax(); 28066 return this._updateSeries(newSeries, animate, overwriteInitialSeries); 28067 } 28068 /** 28069 * Allows users to append a new series after the chart has rendered. 28070 * 28071 * @param {array} newSerie - New serie which will be appended to the existing series 28072 */ 28073 28074 }, { 28075 key: "appendSeries", 28076 value: function appendSeries(newSerie) { 28077 var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28078 var overwriteInitialSeries = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; 28079 var newSeries = this.w.config.series.slice(); 28080 newSeries.push(newSerie); 28081 this.revertDefaultAxisMinMax(); 28082 return this._updateSeries(newSeries, animate, overwriteInitialSeries); 28083 } 28084 /** 28085 * Private method to update Series. 28086 * 28087 * @param {array} series - New series which will override the existing 28088 */ 28089 28090 }, { 28091 key: "_updateSeries", 28092 value: function _updateSeries(newSeries, animate) { 28093 var overwriteInitialSeries = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 28094 var w = this.w; 28095 this.w.globals.shouldAnimate = animate; 28096 w.globals.dataChanged = true; // if user has collapsed some series with legend, we need to clear those 28097 28098 if (w.globals.allSeriesCollapsed) { 28099 w.globals.allSeriesCollapsed = false; 28100 } 28101 28102 if (animate) { 28103 this.series.getPreviousPaths(); 28104 } 28105 28106 var existingSeries; // axis charts 28107 28108 if (w.globals.axisCharts) { 28109 existingSeries = newSeries.map(function (s, i) { 28110 return _objectSpread({}, w.config.series[i], { 28111 name: s.name ? s.name : w.config.series[i] && w.config.series[i].name, 28112 type: s.type ? s.type : w.config.series[i] && w.config.series[i].type, 28113 data: s.data ? s.data : w.config.series[i] && w.config.series[i].data 28114 }); 28115 }); 28116 28117 if (existingSeries.length === 0) { 28118 existingSeries = [{ 28119 data: [] 28120 }]; 28121 } 28122 28123 w.config.series = existingSeries; 28124 } else { 28125 // non-axis chart (pie/radialbar) 28126 w.config.series = newSeries.slice(); 28127 } 28128 28129 if (overwriteInitialSeries) { 28130 w.globals.initialConfig.series = JSON.parse(JSON.stringify(w.config.series)); 28131 w.globals.initialSeries = JSON.parse(JSON.stringify(w.config.series)); 28132 } 28133 28134 return this.update(); 28135 } 28136 /** 28137 * Get all charts in the same "group" (including the instance which is called upon) to sync them when user zooms in/out or pan. 28138 */ 28139 28140 }, { 28141 key: "getSyncedCharts", 28142 value: function getSyncedCharts() { 28143 var chartGroups = this.getGroupedCharts(); 28144 var allCharts = [this]; 28145 28146 if (chartGroups.length) { 28147 allCharts = []; 28148 chartGroups.forEach(function (ch) { 28149 allCharts.push(ch); 28150 }); 28151 } 28152 28153 return allCharts; 28154 } 28155 /** 28156 * Get charts in the same "group" (excluding the instance which is called upon) to perform operations on the other charts of the same group (eg., tooltip hovering) 28157 */ 28158 28159 }, { 28160 key: "getGroupedCharts", 28161 value: function getGroupedCharts() { 28162 var _this2 = this; 28163 28164 return Apex._chartInstances.filter(function (ch) { 28165 if (ch.group) { 28166 return true; 28167 } 28168 }).map(function (ch) { 28169 return _this2.w.config.chart.group === ch.group ? ch.chart : _this2; 28170 }); 28171 } 28172 /** 28173 * Allows users to append Data to series. 28174 * 28175 * @param {array} newData - New data in the same format as series 28176 */ 28177 28178 }, { 28179 key: "appendData", 28180 value: function appendData(newData) { 28181 var overwriteInitialSeries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28182 var me = this; 28183 me.w.globals.dataChanged = true; 28184 me.series.getPreviousPaths(); 28185 var newSeries = me.w.config.series.slice(); 28186 28187 for (var i = 0; i < newSeries.length; i++) { 28188 if (typeof newData[i] !== 'undefined') { 28189 for (var j = 0; j < newData[i].data.length; j++) { 28190 newSeries[i].data.push(newData[i].data[j]); 28191 } 28192 } 28193 } 28194 28195 me.w.config.series = newSeries; 28196 28197 if (overwriteInitialSeries) { 28198 me.w.globals.initialSeries = JSON.parse(JSON.stringify(me.w.config.series)); 28199 } 28200 28201 return this.update(); 28202 } 28203 }, { 28204 key: "update", 28205 value: function update(options$$1) { 28206 var _this3 = this; 28207 28208 return new Promise$1(function (resolve, reject) { 28209 _this3.clear(); 28210 28211 var graphData = _this3.create(_this3.w.config.series, options$$1); 28212 28213 if (!graphData) return resolve(_this3); 28214 28215 _this3.mount(graphData).then(function () { 28216 if (typeof _this3.w.config.chart.events.updated === 'function') { 28217 _this3.w.config.chart.events.updated(_this3, _this3.w); 28218 } 28219 28220 _this3.fireEvent('updated', [_this3, _this3.w]); 28221 28222 _this3.w.globals.isDirty = true; 28223 resolve(_this3); 28224 }).catch(function (e) { 28225 reject(e); 28226 }); 28227 }); 28228 } 28229 }, { 28230 key: "forceXAxisUpdate", 28231 value: function forceXAxisUpdate(options$$1) { 28232 var w = this.w; 28233 28234 if (typeof options$$1.xaxis.min !== 'undefined') { 28235 w.config.xaxis.min = options$$1.xaxis.min; 28236 w.globals.lastXAxis.min = options$$1.xaxis.min; 28237 } 28238 28239 if (typeof options$$1.xaxis.max !== 'undefined') { 28240 w.config.xaxis.max = options$$1.xaxis.max; 28241 w.globals.lastXAxis.max = options$$1.xaxis.max; 28242 } 28243 } 28244 /** 28245 * This function reverts the yaxis and xaxis min/max values to what it was when the chart was defined. 28246 * This function fixes an important bug where a user might load a new series after zooming in/out of previous series which resulted in wrong min/max 28247 * Also, this should never be called internally on zoom/pan - the reset should only happen when user calls the updateSeries() function externally 28248 */ 28249 28250 }, { 28251 key: "revertDefaultAxisMinMax", 28252 value: function revertDefaultAxisMinMax() { 28253 var w = this.w; 28254 w.config.xaxis.min = w.globals.lastXAxis.min; 28255 w.config.xaxis.max = w.globals.lastXAxis.max; 28256 w.config.yaxis.map(function (yaxe, index) { 28257 if (w.globals.zoomed) { 28258 // if user has zoomed, and this function is called 28259 // then we need to get the lastAxis min and max 28260 if (typeof w.globals.lastYAxis[index] !== 'undefined') { 28261 yaxe.min = w.globals.lastYAxis[index].min; 28262 yaxe.max = w.globals.lastYAxis[index].max; 28263 } 28264 } 28265 }); 28266 } 28267 }, { 28268 key: "clear", 28269 value: function clear() { 28270 if (this.zoomPanSelection) { 28271 this.zoomPanSelection.destroy(); 28272 } 28273 28274 if (this.toolbar) { 28275 this.toolbar.destroy(); 28276 } 28277 28278 this.animations = null; 28279 this.annotations = null; 28280 this.core = null; 28281 this.grid = null; 28282 this.series = null; 28283 this.responsive = null; 28284 this.theme = null; 28285 this.formatters = null; 28286 this.titleSubtitle = null; 28287 this.legend = null; 28288 this.dimensions = null; 28289 this.options = null; 28290 this.crosshairs = null; 28291 this.zoomPanSelection = null; 28292 this.toolbar = null; 28293 this.w.globals.tooltip = null; 28294 this.clearDomElements(); 28295 } 28296 }, { 28297 key: "killSVG", 28298 value: function killSVG(draw) { 28299 return new Promise$1(function (resolve, reject) { 28300 draw.each(function (i, children) { 28301 this.removeClass('*'); 28302 this.off(); 28303 this.stop(); 28304 }, true); 28305 draw.ungroup(); 28306 draw.clear(); 28307 resolve('done'); 28308 }); 28309 } 28310 }, { 28311 key: "clearDomElements", 28312 value: function clearDomElements() { 28313 var domEls = this.w.globals.dom; 28314 28315 if (this.el !== null) { 28316 // remove all child elements - resetting the whole chart 28317 while (this.el.firstChild) { 28318 this.el.removeChild(this.el.firstChild); 28319 } 28320 } 28321 28322 this.killSVG(domEls.Paper); 28323 domEls.Paper.remove(); 28324 domEls.elWrap = null; 28325 domEls.elGraphical = null; 28326 domEls.elLegendWrap = null; 28327 domEls.baseEl = null; 28328 domEls.elGridRect = null; 28329 domEls.elGridRectMask = null; 28330 domEls.elGridRectMarkerMask = null; 28331 domEls.elDefs = null; 28332 } 28333 /** 28334 * Destroy the chart instance by removing all elements which also clean up event listeners on those elements. 28335 */ 28336 28337 }, {
28338 key: "destroy", 28339 value: function destroy() { 28340 this.clear(); // remove the chart's instance from the global Apex._chartInstances 28341 28342 var chartID = this.w.config.chart.id; 28343 28344 if (chartID) { 28345 Apex._chartInstances.forEach(function (c, i) { 28346 if (c.id === chartID) { 28347 Apex._chartInstances.splice(i, 1); 28348 } 28349 }); 28350 } 28351 28352 window.removeEventListener('resize', this.windowResizeHandler); 28353 window.removeResizeListener(this.el.parentNode, this.parentResizeCallback.bind(this)); 28354 } 28355 /** 28356 * Allows the user to provide data attrs in the element and the chart will render automatically when this method is called by searching for the elements containing 'data-apexcharts' attribute 28357 */ 28358 28359 }, { 28360 key: "toggleSeries", 28361 value: function toggleSeries(seriesName) { 28362 var targetElement = this.series.getSeriesByName(seriesName); 28363 var seriesCnt = parseInt(targetElement.getAttribute('data:realIndex')); 28364 var isHidden = targetElement.classList.contains('apexcharts-series-collapsed'); 28365 this.legend.toggleDataSeries(seriesCnt, isHidden); 28366 } 28367 }, { 28368 key: "resetToggleSeries", 28369 value: function resetToggleSeries() { 28370 this.legend.resetToggleDataSeries(); 28371 } 28372 }, { 28373 key: "setupEventHandlers", 28374 value: function setupEventHandlers() { 28375 var w = this.w; 28376 var me = this; 28377 var clickableArea = w.globals.dom.baseEl.querySelector(w.globals.chartClass); 28378 var eventList = ['mousedown', 'mousemove', 'touchstart', 'touchmove', 'mouseup', 'touchend']; 28379 eventList.forEach(function (event) { 28380 clickableArea.addEventListener(event, function (e) { 28381 if (e.type === 'mousedown' && e.which === 1) ; else if (e.type === 'mouseup' && e.which === 1 || e.type === 'touchend') { 28382 if (typeof w.config.chart.events.click === 'function') { 28383 w.config.chart.events.click(e, me, w); 28384 } 28385 28386 me.fireEvent('click', [e, me, w]); 28387 } 28388 }, { 28389 capture: false, 28390 passive: true 28391 }); 28392 }); 28393 eventList.forEach(function (event) { 28394 document.addEventListener(event, function (e) { 28395 w.globals.clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX; 28396 w.globals.clientY = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY; 28397 }); 28398 }); 28399 this.core.setupBrushHandler(); 28400 } 28401 }, { 28402 key: "addXaxisAnnotation", 28403 value: function addXaxisAnnotation(opts) { 28404 var pushToMemory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28405 var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 28406 var me = this; 28407 28408 if (context) { 28409 me = context; 28410 } 28411 28412 me.annotations.addXaxisAnnotationExternal(opts, pushToMemory, me); 28413 } 28414 }, { 28415 key: "addYaxisAnnotation", 28416 value: function addYaxisAnnotation(opts) { 28417 var pushToMemory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28418 var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 28419 var me = this; 28420 28421 if (context) { 28422 me = context; 28423 } 28424 28425 me.annotations.addYaxisAnnotationExternal(opts, pushToMemory, me); 28426 } 28427 }, { 28428 key: "addPointAnnotation", 28429 value: function addPointAnnotation(opts) { 28430 var pushToMemory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28431 var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 28432 var me = this; 28433 28434 if (context) { 28435 me = context; 28436 } 28437 28438 me.annotations.addPointAnnotationExternal(opts, pushToMemory, me); 28439 } 28440 }, { 28441 key: "clearAnnotations", 28442 value: function clearAnnotations() { 28443 var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; 28444 var me = this; 28445 28446 if (context) { 28447 me = context; 28448 } 28449 28450 me.annotations.clearAnnotations(me); 28451 } // This method is never used internally and will be only called externally on the chart instance. 28452 // Hence, we need to keep all these elements in memory when the chart gets updated and redraw again 28453 28454 }, { 28455 key: "addText", 28456 value: function addText(options$$1) { 28457 var pushToMemory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 28458 var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 28459 var me = this; 28460 28461 if (context) { 28462 me = context; 28463 } 28464 28465 me.annotations.addText(options$$1, pushToMemory, me); 28466 } 28467 }, { 28468 key: "getChartArea", 28469 value: function getChartArea() { 28470 var el = this.w.globals.dom.baseEl.querySelector('.apexcharts-inner'); 28471 return el; 28472 } 28473 }, { 28474 key: "getSeriesTotalXRange", 28475 value: function getSeriesTotalXRange(minX, maxX) { 28476 return this.coreUtils.getSeriesTotalsXRange(minX, maxX); 28477 } 28478 }, { 28479 key: "getHighestValueInSeries", 28480 value: function getHighestValueInSeries() { 28481 var seriesIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 28482 var range = new Range$1(this.ctx); 28483 var minYmaxY = range.getMinYMaxY(seriesIndex); 28484 return minYmaxY.highestY; 28485 } 28486 }, { 28487 key: "getLowestValueInSeries", 28488 value: function getLowestValueInSeries() { 28489 var seriesIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 28490 var range = new Range$1(this.ctx); 28491 var minYmaxY = range.getMinYMaxY(seriesIndex); 28492 return minYmaxY.lowestY; 28493 } 28494 }, { 28495 key: "getSeriesTotal", 28496 value: function getSeriesTotal() { 28497 return this.w.globals.seriesTotals; 28498 } 28499 }, { 28500 key: "setLocale", 28501 value: function setLocale(localeName) { 28502 this.setCurrentLocaleValues(localeName); 28503 } 28504 }, { 28505 key: "setCurrentLocaleValues", 28506 value: function setCurrentLocaleValues(localeName) { 28507 var locales = this.w.config.chart.locales; // check if user has specified locales in global Apex variable
28508 // if yes - then extend those with local chart's locale 28509 28510 if (window.Apex.chart && window.Apex.chart.locales && window.Apex.chart.locales.length > 0) { 28511 locales = this.w.config.chart.locales.concat(window.Apex.chart.locales); 28512 } // find the locale from the array of locales which user has set (either by chart.defaultLocale or by calling setLocale() method.) 28513 28514 28515 var selectedLocale = locales.filter(function (c) { 28516 return c.name === localeName; 28517 })[0]; 28518 28519 if (selectedLocale) { 28520 // create a complete locale object by extending defaults so you don't get undefined errors. 28521 var ret = Utils.extend(en, selectedLocale); // store these locale options in global var for ease access 28522 28523 this.w.globals.locale = ret.options; 28524 } else { 28525 throw new Error('Wrong locale name provided. Please make sure you set the correct locale name in options'); 28526 } 28527 } 28528 }, { 28529 key: "dataURI", 28530 value: function dataURI() { 28531 var exp = new Exports(this.ctx); 28532 return exp.dataURI(); 28533 } 28534 }, { 28535 key: "paper", 28536 value: function paper() { 28537 return this.w.globals.dom.Paper; 28538 } 28539 }, { 28540 key: "parentResizeCallback", 28541 value: function parentResizeCallback() { 28542 if (this.w.globals.animationEnded) { 28543 this.windowResize(); 28544 } 28545 } 28546 /** 28547 * Handle window resize and re-draw the whole chart. 28548 */ 28549 28550 }, { 28551 key: "windowResize", 28552 value: function windowResize() { 28553 var _this4 = this; 28554 28555 clearTimeout(this.w.globals.resizeTimer); 28556 this.w.globals.resizeTimer = window.setTimeout(function () { 28557 _this4.w.globals.resized = true; 28558 _this4.w.globals.dataChanged = false; // we need to redraw the whole chart on window resize (with a small delay). 28559 28560 _this4.update(); 28561 }, 150); 28562 } 28563 }], [{ 28564 key: "initOnLoad", 28565 value: function initOnLoad() { 28566 var els = document.querySelectorAll('[data-apexcharts]'); 28567 28568 for (var i = 0; i < els.length; i++) { 28569 var el = els[i]; 28570 var options$$1 = JSON.parse(els[i].getAttribute('data-options')); 28571 var apexChart = new ApexCharts(el, options$$1); 28572 apexChart.render(); 28573 } 28574 } 28575 /** 28576 * This static method allows users to call chart methods without necessarily from the 28577 * instance of the chart in case user has assigned chartID to the targetted chart. 28578 * The chartID is used for mapping the instance stored in Apex._chartInstances global variable 28579 * 28580 * This is helpful in cases when you don't have reference of the chart instance 28581 * easily and need to call the method from anywhere. 28582 * For eg, in React/Vue applications when you have many parent/child components, 28583 * and need easy reference to other charts for performing dynamic operations 28584 * 28585 * @param {string} chartID - The unique identifier which will be used to call methods 28586 * on that chart instance 28587 * @param {function} fn - The method name to call 28588 * @param {object} opts - The parameters which are accepted in the original method will be passed here in the same order. 28589 */ 28590 28591 }, { 28592 key: "exec", 28593 value: function exec(chartID, fn) { 28594 var chart = this.getChartByID(chartID); 28595 if (!chart) return; 28596 28597 for (var _len = arguments.length, opts = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 28598 opts[_key - 2] = arguments[_key]; 28599 } 28600 28601 switch (fn) { 28602 case 'updateOptions': 28603 { 28604 return chart.updateOptions.apply(chart, opts); 28605 } 28606 28607 case 'updateSeries': 28608 { 28609 return chart.updateSeries.apply(chart, opts); 28610 } 28611 28612 case 'appendData': 28613 { 28614 return chart.appendData.apply(chart, opts); 28615 } 28616 28617 case 'appendSeries': 28618 { 28619 return chart.appendSeries.apply(chart, opts); 28620 } 28621 28622 case 'toggleSeries': 28623 { 28624 return chart.toggleSeries.apply(chart, opts); 28625 } 28626 28627 case 'dataURI': 28628 { 28629 return chart.dataURI.apply(chart, opts); 28630 } 28631 28632 case 'addXaxisAnnotation': 28633 { 28634 return chart.addXaxisAnnotation.apply(chart, opts); 28635 } 28636 28637 case 'addYaxisAnnotation': 28638 { 28639 return chart.addYaxisAnnotation.apply(chart, opts); 28640 } 28641 28642 case 'addPointAnnotation': 28643 { 28644 return chart.addPointAnnotation.apply(chart, opts); 28645 } 28646 28647 case 'addText': 28648 { 28649 return chart.addText.apply(chart, opts); 28650 } 28651 28652 case 'clearAnnotations': 28653 { 28654 return chart.clearAnnotations.apply(chart, opts); 28655 } 28656 28657 case 'paper': 28658 { 28659 return chart.paper.apply(chart, opts); 28660 } 28661 28662 case 'destroy': 28663 { 28664 return chart.destroy(); 28665 } 28666 } 28667 } 28668 }, { 28669 key: "merge", 28670 value: function merge(target, source) { 28671 return Utils.extend(target, source); 28672 } 28673 }, { 28674 key: "getChartByID", 28675 value: function getChartByID(chartID) { 28676 var c = Apex._chartInstances.filter(function (ch) { 28677 return ch.id === chartID; 28678 })[0]; 28679 28680 return c.chart; 28681 } 28682 }]); 28683 28684 return ApexCharts; 28685 }(); 28686 28687 return ApexCharts$1; 28688 28689})); 28690 28691 28692try { if (typeof charts_onReady == 'function') { console.log('Charts are ready to render...'); charts_onReady(); } } catch (ex) { console.log(ex.message); }
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.