UNPKG

@progress/kendo-charts

Version:

Kendo UI platform-independent Charts library

1,884 lines (1,526 loc) 7.81 MB
'use strict'; var kendoDrawing = require('@progress/kendo-drawing'); var ARC = "arc"; var ARROW_UP = "ArrowUp"; var ARROW_DOWN = "ArrowDown"; var ARROW_LEFT = "ArrowLeft"; var ARROW_RIGHT = "ArrowRight"; var TAB = "Tab"; var ARIA_ACTIVE_DESCENDANT = "aria-activedescendant"; var AXIS_LABEL_CLICK = "axisLabelClick"; var BLACK$1 = "#000"; var BOTTOM = "bottom"; var CENTER = "center"; var CIRCLE = "circle"; var COORD_PRECISION = 3; var CROSS = "cross"; var DATE = "date"; var DEFAULT_FONT = "12px sans-serif"; var DEFAULT_HEIGHT$1 = 400; var DEFAULT_PRECISION = 10; var DEFAULT_WIDTH$1 = 600; var END$1 = "end"; var ENTER = "Enter"; var ESCAPE = "Escape"; var FORMAT_REGEX = /\{\d+:?/; var HEIGHT = "height"; var HIGHLIGHT_ZINDEX = 100; var INSIDE$2 = "inside"; var INHERIT = "inherit"; var LEFT = "left"; var MAX_VALUE = Number.MAX_VALUE; var MIN_VALUE = -Number.MAX_VALUE; var NONE = "none"; var NOTE_CLICK = "noteClick"; var NOTE_HOVER = "noteHover"; var NOTE_LEAVE = "noteLeave"; var OBJECT$1 = "object"; var OUTSIDE$1 = "outside"; var RIGHT = "right"; var ROUNDED_RECT = "roundedRect"; var START$1 = "start"; var STRING$1 = "string"; var TOP = "top"; var TRIANGLE = "triangle"; var SQUARE = "square"; var RECT = "rect"; var VALUE = "value"; var WHITE$1 = "#fff"; var WIDTH = "width"; var X = "x"; var Y = "y"; var DEFAULT_SERIES_OPACITY = 1; var POINTER = "pointer"; var HORIZONTAL = "horizontal"; var VERTICAL = "vertical"; function isArray(value) { return Array.isArray(value); } function addClass(element, classes) { var classArray = isArray(classes) ? classes : [ classes ]; for (var idx = 0; idx < classArray.length; idx++) { var className = classArray[idx]; if (element.className.indexOf(className) === -1) { element.className += " " + className; } } } var SPACE_REGEX = /\s+/g; function removeClass(element, className) { if (element && element.className) { element.className = element.className.replace(className, "").replace(SPACE_REGEX, " "); } } function alignPathToPixel(path) { var offset = 0.5; if (path.options.stroke && kendoDrawing.drawing.util.defined(path.options.stroke.width)) { if (path.options.stroke.width % 2 === 0) { offset = 0; } } for (var i = 0; i < path.segments.length; i++) { path.segments[i].anchor().round(0).translate(offset, offset); } return path; } function clockwise(angle1, angle2) { // True if angle2 is clockwise of angle1 // assuming angles grow in clock-wise direction // (as in the pie and radar charts) return -angle1.x * angle2.y + angle1.y * angle2.x < 0; } function isNumber(value) { return typeof value === "number" && !isNaN(value); } function isString$1(value) { return typeof value === STRING$1; } function convertableToNumber(value) { return isNumber(value) || (isString$1(value) && isFinite(value)); } function cycleUp(index, count) { return (index + 1) % count; } function cycleDown(index, count) { var result = index - 1; return result < 0 ? count - 1 : result; } function cycleIndex(index, length) { if (length === 1 || (index % length) === 0) { return 0; } if (index < 0) { return length + (index % length); } else if (index >= length) { return index % length; } return index; } function isFunction(fn) { return typeof fn === "function"; } var OBJECT = "object"; var UNDEFINED = "undefined"; function deepExtendOne(destination, source) { for (var property in source) { if (property === '__proto__' || property === 'constructor') { continue; } var propValue = source[property]; var propType = typeof propValue; var propInit = (void 0); if (propType === OBJECT && propValue !== null) { propInit = propValue.constructor; } else { propInit = null; } if (propInit && propInit !== Array) { if (propValue instanceof Date) { destination[property] = new Date(propValue.getTime()); } else if (isFunction(propValue.clone)) { destination[property] = propValue.clone(); } else { var destProp = destination[property]; if (typeof (destProp) === OBJECT) { destination[property] = destProp || {}; } else { destination[property] = {}; } deepExtendOne(destination[property], propValue); } } else if (propType !== UNDEFINED) { destination[property] = propValue; } } return destination; } function deepExtend(destination) { var arguments$1 = arguments; var length = arguments.length; for (var i = 1; i < length; i++) { deepExtendOne(destination, arguments$1[i]); } return destination; } function isObject(value) { return typeof value === "object"; } function styleValue(value) { if (isNumber(value)) { return value + "px"; } return value; } var SIZE_STYLES_REGEX = /width|height|top|left|bottom|right/i; function isSizeField(field) { return SIZE_STYLES_REGEX.test(field); } function elementStyles$1(element, styles) { var stylesArray = isString$1(styles) ? [ styles ] : styles; if (isArray(stylesArray)) { var result = {}; var style = window.getComputedStyle(element); for (var idx = 0; idx < stylesArray.length; idx++) { var field = stylesArray[idx]; result[field] = isSizeField(field) ? parseFloat(style[field]) : style[field]; } return result; } else if (isObject(styles)) { for (var field$1 in styles) { element.style[field$1] = styleValue(styles[field$1]); } } } function getSpacing(value, defaultSpacing) { if ( defaultSpacing === void 0 ) defaultSpacing = 0; var spacing = { top: 0, right: 0, bottom: 0, left: 0 }; if (typeof(value) === "number") { spacing[TOP] = spacing[RIGHT] = spacing[BOTTOM] = spacing[LEFT] = value; } else { spacing[TOP] = value[TOP] || defaultSpacing; spacing[RIGHT] = value[RIGHT] || defaultSpacing; spacing[BOTTOM] = value[BOTTOM] || defaultSpacing; spacing[LEFT] = value[LEFT] || defaultSpacing; } return spacing; } var current$2 = { compile: function(template) { return template; } }; var TemplateService = function TemplateService () {}; TemplateService.register = function register (userImplementation) { current$2 = userImplementation; }; TemplateService.compile = function compile (template, options) { return current$2.compile(template, options); }; function getTemplate$1(options) { if ( options === void 0 ) options = {}; var template; if (options.template) { options.template = template = TemplateService.compile(options.template); } else if (isFunction(options.content)) { template = options.content; } return template; } function getTemplate(options) { if ( options === void 0 ) options = {}; var ariaTemplate; if (options.ariaTemplate) { options.ariaTemplate = ariaTemplate = TemplateService.compile(options.ariaTemplate); } else if (isFunction(options.ariaContent)) { ariaTemplate = options.ariaContent; } return ariaTemplate; } var FIELD_REGEX = /\[(?:(\d+)|['"](.*?)['"])\]|((?:(?!\[.*?\]|\.).)+)/g; var getterCache = {}; getterCache['undefined'] = function(obj) { return obj; }; function getter(field) { if (getterCache[field]) { return getterCache[field]; } var fields = []; field.replace(FIELD_REGEX, function(match, index, indexAccessor, field) { fields.push(index !== undefined ? index : (indexAccessor || field)); }); getterCache[field] = function(obj) { var result = obj; for (var idx = 0; idx < fields.length && result; idx++) { result = result[fields[idx]]; } return result; }; return getterCache[field]; } var grep = function (array, callback) { return array.filter(callback); }; function hasClasses(element, classNames) { if (element.className) { var names = classNames.split(" "); for (var idx = 0; idx < names.length; idx++) { if (element.className.indexOf && element.className.indexOf(names[idx]) !== -1) { return true; } } } } // TODO: Remove and replace with Map/WeakMap. var HashMap = function HashMap() { this._map = new Map(); }; HashMap.prototype.get = function get (key) { return this._map.get(key); }; HashMap.prototype.set = function set (key, value) { this._map.set(key, value); }; function inArray(value, array) { if (array) { return array.includes(value); } } function interpolateValue(start, end, progress) { return kendoDrawing.drawing.util.round(start + (end - start) * progress, COORD_PRECISION); } var TRIGGER = 'trigger'; var InstanceObserver = function InstanceObserver(observer, handlers) { this.observer = observer; this.handlerMap = deepExtend({}, this.handlerMap, handlers); }; InstanceObserver.prototype.trigger = function trigger (name, args) { var ref = this; var observer = ref.observer; var handlerMap = ref.handlerMap; var isDefaultPrevented; if (handlerMap[name]) { isDefaultPrevented = this.callObserver(handlerMap[name], args); } else if (observer[TRIGGER]) { isDefaultPrevented = this.callObserver(TRIGGER, name, args); } return isDefaultPrevented; }; InstanceObserver.prototype.callObserver = function callObserver (fnName) { var args = [], len = arguments.length - 1; while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; return this.observer[fnName].apply(this.observer, args); }; InstanceObserver.prototype.requiresHandlers = function requiresHandlers (names) { if (this.observer.requiresHandlers) { return this.observer.requiresHandlers(names); } for (var idx = 0; idx < names.length; idx++) { if (this.handlerMap[names[idx]]) { return true; } } }; function isPlainObject(value) { return Object.prototype.toString.call(value) === "[object Object]"; } function map(array, callback) { var length = array.length; var result = []; for (var idx = 0; idx < length; idx++) { var value = callback(array[idx]); if (kendoDrawing.drawing.util.defined(value)) { result.push(value); } } return result; } var browser$1 = kendoDrawing.support.browser || {}; function mousewheelDelta(e) { var delta = 0; if (e.wheelDelta) { delta = -e.wheelDelta / 120; if (browser$1.webkit) { // Webkit browsers scale the delta by twice the device resolution. // Possibly related to https://bugs.webkit.org/show_bug.cgi?id=196339 // // Low device resolutions (e.g. zoom-out to 30%) also behave strangely. delta = delta / (2 * Math.max(window.devicePixelRatio, 0.625)); } } else if (e.detail) { delta = e.detail / 3; } delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta); return delta; } var ref = kendoDrawing.drawing.util; var append = ref.append; var bindEvents = ref.bindEvents; var defined = ref.defined; var deg = ref.deg; var elementOffset = ref.elementOffset; var elementSize = ref.elementSize; var eventCoordinates = ref.eventCoordinates; var eventElement = ref.eventElement; var hashKey = ref.hashKey; var last = ref.last; var limitValue = ref.limitValue; var objectKey = ref.objectKey; var rad = ref.rad; var round$1 = ref.round; var unbindEvents = ref.unbindEvents; var valueOrDefault = ref.valueOrDefault; var FontLoader = function FontLoader () {}; FontLoader.fetchFonts = function fetchFonts (options, fonts, state) { if ( state === void 0 ) state = { depth: 0 }; var MAX_DEPTH = 5; if (!options || state.depth > MAX_DEPTH || !document.fonts) { return; } Object.keys(options).forEach(function(key) { var value = options[key]; if (key === "dataSource" || key[0] === "$" || !value) { return; } if (key === "font") { fonts.push(value); } else if (typeof value === "object") { state.depth++; FontLoader.fetchFonts(value, fonts, state); state.depth--; } }); }; FontLoader.loadFonts = function loadFonts (fonts, callback) { var promises = []; if (fonts.length > 0 && document.fonts) { try { promises = fonts.map(function(font) { return document.fonts.load(font); }); } catch (e) { // Silence font-loading errors kendoDrawing.logToConsole(e); } Promise.all(promises).then(callback, callback); } else { callback(); } }; FontLoader.preloadFonts = function preloadFonts (options, callback) { var fonts = []; FontLoader.fetchFonts(options, fonts); FontLoader.loadFonts(fonts, callback); }; function setDefaultOptions(type, options) { var proto = type.prototype; if (proto.options) { proto.options = deepExtend({}, proto.options, options); } else { proto.options = options; } } var KICON = 'k-icon'; var KI_PREFFIX = 'k-i-'; var KFONTICON = 'k-font-icon'; var KSVGICON = 'k-svg-icon'; var KSVG_PREFFIX = 'k-svg-i-'; var HTMLBaseIcon = function HTMLBaseIcon(element, options) { this.element = element; this.options = deepExtend({}, this.options, options); this.wrapper(); }; HTMLBaseIcon.prototype.wrapper = function wrapper () { this.addClasses(); }; HTMLBaseIcon.prototype.addClasses = function addClasses () { }; HTMLBaseIcon.prototype.html = function html () { return this.element.outerHTML; }; setDefaultOptions(HTMLBaseIcon, { name: '', size: 'none', themeColor: 'none', flip: 'default', iconClass: '', stylingOptions: [ 'size', 'themeColor', 'fill' ] }); var HTMLFontIcon = /*@__PURE__*/(function (HTMLBaseIcon) { function HTMLFontIcon(element, options) { HTMLBaseIcon.call(this, element, options); } if ( HTMLBaseIcon ) HTMLFontIcon.__proto__ = HTMLBaseIcon; HTMLFontIcon.prototype = Object.create( HTMLBaseIcon && HTMLBaseIcon.prototype ); HTMLFontIcon.prototype.constructor = HTMLFontIcon; HTMLFontIcon.prototype.wrapper = function wrapper () { // Find if there is an existing k-i- class appended to the element. var currentIconClass = this.element.className.split(" ").find(function (x) { return x.startsWith(KI_PREFFIX); }); var className = this.options.icon ? ("" + (this.options.icon.startsWith(KI_PREFFIX) ? "" : KI_PREFFIX) + (this.options.icon)) : ""; this._className = className; addClass(this.element, KICON); addClass(this.element, KFONTICON); removeClass(this.element, currentIconClass); // Remove any existing icons. addClass(this.element, className); addClass(this.element, this.options.iconClass || ''); HTMLBaseIcon.prototype.wrapper.call(this); }; return HTMLFontIcon; }(HTMLBaseIcon)); setDefaultOptions(HTMLFontIcon, { name: 'HTMLFontIcon', icon: null }); var HTMLSvgIcon = /*@__PURE__*/(function (HTMLBaseIcon) { function HTMLSvgIcon(element, options) { // Ensure that the inner contents of the wrapping span element are always removed for re-rendering purposes. element.innerHTML = ""; HTMLBaseIcon.call(this, element, options); } if ( HTMLBaseIcon ) HTMLSvgIcon.__proto__ = HTMLBaseIcon; HTMLSvgIcon.prototype = Object.create( HTMLBaseIcon && HTMLBaseIcon.prototype ); HTMLSvgIcon.prototype.constructor = HTMLSvgIcon; HTMLSvgIcon.prototype.wrapper = function wrapper () { var icon = this.options.icon; var iconClass = this.options.iconClass; var currentIconClass = this.element.className.split(" ").find(function (x) { return x.startsWith(KSVG_PREFFIX); }); if (!icon && iconClass) { // match k-i-(some-icon-name) var regex = /k-i-(\w+(?:-\w+)*)/; var iconNameMatch = iconClass.match(regex); if (iconNameMatch) { icon = iconNameMatch[1]; iconClass = iconClass.replace(iconNameMatch[0], ""); } } if (isString$1(icon)) { icon = icon.replace("k-i-", "").replace(/-./g, function (x) { return x[1].toUpperCase(); }); icon = this.options.svgIcons[icon] || this.options.svgIcons[(icon + "Icon")]; } var className = icon && icon.name ? ("" + KSVG_PREFFIX + (icon.name)) : ""; this._className = className; addClass(this.element, KSVGICON); removeClass(this.element, currentIconClass); addClass(this.element, className); addClass(this.element, iconClass || ""); this.element.setAttribute("aria-hidden", "true"); if (icon && isPlainObject(icon)) { var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svgElement.setAttribute("viewBox", icon.viewBox || ""); svgElement.setAttribute("focusable", "false"); svgElement.innerHTML = icon.content || ""; this.element.appendChild(svgElement); } HTMLBaseIcon.prototype.wrapper.call(this); }; return HTMLSvgIcon; }(HTMLBaseIcon)); setDefaultOptions(HTMLSvgIcon, { name: 'HTMLSvgIcon', icon: null, svgIcons: {} }); var ICON_TYPES = { 'svg': HTMLSvgIcon, 'font': HTMLFontIcon }; function renderIcon(iconElement, iconOptions) { var element = iconElement; var options = iconOptions; if (!element || (isObject(element) && !(element instanceof HTMLElement)) || isString$1(element)) { options = element; element = document.createElement("span"); } if (isString$1(options)) { options = { icon: options }; } if (!options.type) { options.type = 'svg'; } if (!ICON_TYPES[options.type]) { return null; } return (new ICON_TYPES[options.type](element, options).html()); } function sparseArrayLimits(arr) { var min = MAX_VALUE; var max = MIN_VALUE; for (var idx = 0, length = arr.length; idx < length; idx++) { var value = arr[idx]; if (value !== null && isFinite(value)) { min = Math.min(min, value); max = Math.max(max, value); } } return { min: min === MAX_VALUE ? undefined : min, max: max === MIN_VALUE ? undefined : max }; } function find(array, predicate) { for (var i = 0; i < array.length; i++) { var item = array[i]; if (predicate(item, i, array)) { return item; } } } var Matrix$1 = kendoDrawing.geometry.Matrix; var matrixRegexp = /matrix\((.*)\)/; function parseMatrix(matrixString) { var match = matrixString.match(matrixRegexp); if (match === null || match.length !== 2) { return Matrix$1.unit(); } var members = match[1].split(',').map(function (x) { return parseFloat(x); }); return new (Function.prototype.bind.apply( Matrix$1, [ null ].concat( members) )); } function transformMatrix(element) { var transform = getComputedStyle(element).transform; if (transform === 'none') { return Matrix$1.unit(); } return parseMatrix(transform); } function elementScale(element) { if (!element) { return Matrix$1.unit(); } var matrix = transformMatrix(element); var parent = element.parentElement; while (parent) { var parentMatrix = transformMatrix(parent); matrix = matrix.multiplyCopy(parentMatrix); parent = parent.parentElement; } matrix.b = matrix.c = matrix.e = matrix.f = 0; return matrix; } function autoTextColor(color) { var isDark = new kendoDrawing.Color(color).isDark(); if (isDark) { return WHITE$1; } return BLACK$1; } var DELETED = {}; var LegacySet = function LegacySet(values) { this._index = {}; this._values = values ? values.slice(0) : []; for (var i = 0; i < this._values.length; i++) { this._index[this._values[i]] = i; } }; var prototypeAccessors$3 = { size: { configurable: true } }; LegacySet.prototype.values = function values () { return this._values.filter(function (item) { return item !== DELETED; }); }; LegacySet.prototype.has = function has (value) { return this._index[value] !== undefined; }; LegacySet.prototype.add = function add (value) { if (!this.has(value)) { this._index[value] = this._values.length; this._values.push(value); } }; LegacySet.prototype.delete = function delete$1 (value) { var index = this._index[value]; if (index !== undefined) { this._values[index] = DELETED; delete this._index[value]; } }; LegacySet.prototype.clear = function clear () { this._index = {}; this._values = []; }; prototypeAccessors$3.size.get = function () { return this._values.length; }; Object.defineProperties( LegacySet.prototype, prototypeAccessors$3 ); var SetWrapper = function SetWrapper(values) { this._set = new Set(values); }; var prototypeAccessors$1$1 = { size: { configurable: true } }; SetWrapper.prototype.values = function values () { return Array.from(this._set); }; SetWrapper.prototype.has = function has (value) { return this._set.has(value); }; SetWrapper.prototype.add = function add (value) { this._set.add(value); }; SetWrapper.prototype.delete = function delete$2 (value) { this._set.delete(value); }; SetWrapper.prototype.clear = function clear () { this._set.clear(); }; prototypeAccessors$1$1.size.get = function () { return this._set.size; }; Object.defineProperties( SetWrapper.prototype, prototypeAccessors$1$1 ); // TODO: Drop LegacySet when removing support for IE10 var supportsSet = function () { var supported = false; if (typeof Set === 'function') { var set = new Set([1]); supported = set.has(1); } return supported; }; function createHashSet(values) { if (supportsSet()) { return new SetWrapper(values); } return new LegacySet(values); } function defaultErrorHandler(error) { throw error; } var keys = { INSERT: 45, DELETE: 46, BACKSPACE: 8, TAB: 9, ENTER: 13, ESC: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, END: 35, HOME: 36, SPACEBAR: 32, PAGEUP: 33, PAGEDOWN: 34, F2: 113, F10: 121, F12: 123, NUMPAD_PLUS: 107, NUMPAD_MINUS: 109, NUMPAD_DOT: 110 }; function hasOwnProperty(obj, property) { return Object.prototype.hasOwnProperty.call(obj, property); } // Based on the implementation from kendo-spreadsheet-common/src/calc.js var Matrix = function Matrix() { this.height = 0; this.width = 0; this.data = []; }; Matrix.prototype.clone = function clone () { var m = new Matrix(); m.height = this.height; m.width = this.width; m.data = this.data.map(function (row) { return row.slice(); }); return m; }; Matrix.prototype.get = function get (row, col) { var line = this.data[row]; var val = line ? line[col] : null; return val; }; Matrix.prototype.set = function set (row, col, data) { var line = this.data[row]; if (line == null) { line = this.data[row] = []; } line[col] = data; if (row >= this.height) { this.height = row + 1; } if (col >= this.width) { this.width = col + 1; } }; Matrix.prototype.each = function each (f, includeEmpty) { for (var row = 0; row < this.height; ++row) { for (var col = 0; col < this.width; ++col) { var val = this.get(row, col); if (includeEmpty || val != null) { val = f(val, row, col); if (val !== undefined) { return val; } } } } }; Matrix.prototype.map = function map (f, includeEmpty) { var m = new Matrix(); this.each(function(el, row, col) { m.set(row, col, f(el, row, col)); }, includeEmpty); return m; }; Matrix.prototype.transpose = function transpose () { var m = new Matrix(); this.each(function(el, row, col) { m.set(col, row, el); }); return m; }; Matrix.prototype.unit = function unit (n) { this.width = this.height = n; var a = this.data = new Array(n); for (var i = n; --i >= 0;) { var row = a[i] = new Array(n); for (var j = n; --j >= 0;) { row[j] = i === j ? 1 : 0; } } return this; }; Matrix.prototype.multiply = function multiply (b) { var a = this; var m = new Matrix(); for (var row = 0; row < a.height; ++row) { for (var col = 0; col < b.width; ++col) { var s = 0; for (var i = 0; i < a.width; ++i) { var va = a.get(row, i); var vb = b.get(i, col); if (typeof va === "number" && typeof vb === "number") { s += va * vb; } } m.set(row, col, s); } } return m; }; Matrix.prototype.inverse = function inverse () { var n = this.width; var m = this.augment(new Matrix().unit(n)); var a = m.data; // Gaussian elimination // https://en.wikipedia.org/wiki/Gaussian_elimination#Finding_the_inverse_of_a_matrix // 1. Get zeros below main diagonal var loop = function ( k ) { var imax = argmax(k, n, function(i) { return a[i][k]; }); if (!a[imax][k]) { return { v: null }; // singular matrix } if (k !== imax) { var tmp = a[k]; a[k] = a[imax]; a[imax] = tmp; } for (var i = k + 1; i < n; ++i) { for (var j = k + 1; j < 2 * n; ++j) { a[i][j] -= a[k][j] * a[i][k] / a[k][k]; } a[i][k] = 0; } }; for (var k = 0; k < n; ++k) { var returned = loop( k ); if ( returned ) return returned.v; } // 2. Get 1-s on main diagonal, dividing by pivot for (var i$1 = 0; i$1 < n; ++i$1) { for (var f = a[i$1][i$1], j$1 = 0; j$1 < 2 * n; ++j$1) { a[i$1][j$1] /= f; } } // 3. Get zeros above main diagonal. Actually, we only care to compute the right side // here (that will be the inverse), so in the inner loop below we go while j >= n, // instead of j >= k. for (var k$1 = n; --k$1 >= 0;) { for (var i$2 = k$1; --i$2 >= 0;) { if (a[i$2][k$1]) { for (var j$2 = 2 * n; --j$2 >= n;) { a[i$2][j$2] -= a[k$1][j$2] * a[i$2][k$1]; } } } } return m.slice(0, n, n, n); }; Matrix.prototype.augment = function augment (m) { var ret = this.clone(); var n = ret.width; m.each(function(val, row, col) { ret.set(row, col + n, val); }); return ret; }; Matrix.prototype.slice = function slice (row, col, height, width) { var m = new Matrix(); for (var i = 0; i < height; ++i) { for (var j = 0; j < width; ++j) { m.set(i, j, this.get(row + i, col + j)); } } return m; }; function argmax(start, end, f) { var max = f(start), pos = start; for (var i = start + 1; i < end; i++) { var v = f(start); if (v > max) { max = v; pos = start; } } return pos; } var eventMap = { down: "pointerdown", move: "pointermove", up: "pointerup", cancel: "pointercancel pointerleave" }; function queryEventMap(e) { return eventMap[e] || e; } var applyEventMap = function (events) { var eventRegEx = /([^ ]+)/g; var appliedEvents = events.replace(eventRegEx, queryEventMap); return appliedEvents; }; var elId = 1; function elementId() { return "kchart" + elId++; } function guid() { return elementId(); } var elementEventHandlers = new WeakMap(); var ID$1 = Symbol('id'); function on(element, events, filter, handler, useCapture) { addEventListeners(element, events, filter, handler, useCapture); } function off(element, events, filter, handler, useCapture) { removeEventListeners(element, events, filter, handler); } function isString(value) { return typeof(value) === "string"; } function addEventListeners(element, events, filter, handler, useCapture) { var eventNames = isArray(events) ? events : (events || "").split(" "); eventNames.forEach(function(eventName) { addEventListener(element, eventName, filter, handler, useCapture); }); } function addEventListener(element, event, filter, handler, useCapture) { var eventHandler = handler; var eventFilter; if (filter && isFunction(filter) && !handler) { eventHandler = filter; } else if (filter && isString(filter) && isFunction(eventHandler)) { eventFilter = filter; } var attachedHandler = function(e) { var closestMatchingTarget = e.target ? e.target.closest(eventFilter) : null; if (!eventFilter || (eventFilter && e.target && closestMatchingTarget)) { var currentTarget = eventFilter ? closestMatchingTarget : e.currentTarget; // reassign the property as it is a getters only Object.defineProperty(e, "currentTarget", { value: currentTarget }); // keep a reference to the top-level target Object.defineProperty(e, "delegateTarget", { value: element }); eventHandler(e); } }; if (!eventHandler[ID$1]) { eventHandler[ID$1] = guid(); } var eventHandlers = elementEventHandlers.get(element); if (!eventHandlers) { eventHandlers = new Map(); elementEventHandlers.set(element, eventHandlers); } eventHandlers.set(event + eventHandler[ID$1], attachedHandler); element.addEventListener(event, attachedHandler, Boolean(useCapture)); } function removeEventListeners(element, events, handler, useCapture) { var eventNames = isArray(events) ? events : (events || "").split(" "); eventNames.forEach(function(eventName) { removeEventListener(element, eventName, handler, useCapture); }); } function removeEventListener(element, event, handler, useCapture) { var eventHandlers = elementEventHandlers.get(element); if (eventHandlers && handler && handler[ID$1]) { var handlerId = event + handler[ID$1]; var attachedHandler = eventHandlers.get(handlerId); eventHandlers.delete(handlerId); if (attachedHandler) { element.removeEventListener(event, attachedHandler, Boolean(useCapture)); } } } function getSupportedFeatures() { var os = detectOS(navigator.userAgent); var support = {}; support.mobileOS = os; return support; } function detectOS(ua) { var os = false; var agentRxs = { wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/, fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/, android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.?(\d+(\.\d+)?)?/, iphone: /(iPhone|iPod).*OS\s+(\d+)[._]([\d._]+)/, ipad: /(iPad).*OS\s+(\d+)[._]([\d_]+)/, playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/, windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/, tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i, sailfish: /(sailfish).*rv:(\d+)\.(\d+(\.\d+)?).*firefox/i }, osRxs = { ios: /^i(phone|pad|pod)$/i, android: /^android|fire$/i, windows: /windows/, wp: /wp/, flat: /sailfish|ffos|tizen/i }; for (var agent in agentRxs) { var match = ua.match(agentRxs[agent]); if (match) { if (agent === "windows" && "plugins" in navigator) { return false; } // Break if not Metro/Mobile Windows os = {}; os.device = agent; os.name = testRegex(agent, osRxs); os[os.name] = true; break; } } return os; } function testRegex(agent, regexes, dflt) { for (var regex in regexes) { if (regexes[regex].test(agent)) { return regex; } } return dflt !== undefined ? dflt : agent; } function noop() {} function now() { return new Date().getTime(); } var STRING = "string"; var FUNCTION = "function"; var preventDefault$2 = function() { this._defaultPrevented = true; }; var isDefaultPrevented = function() { return this._defaultPrevented === true; }; var Observable = function Observable() { this._events = {}; }; Observable.prototype.destroy = function destroy () { this.unbind(); }; Observable.prototype.bind = function bind (event, handlers, one) { var that = this, idx, eventNames = typeof event === STRING ? [event] : event || [], length, original, handler, handlersIsFunction = typeof handlers === FUNCTION, events; if (handlers === undefined) { for (idx in event) { that.bind(idx, event[idx]); } return that; } /* eslint-disable no-loop-func */ var loop = function ( ) { var eventName = eventNames[idx]; handler = handlersIsFunction ? handlers : handlers[eventName]; if (handler) { if (one) { original = handler; handler = function() { that.unbind(eventName, handler); original.apply(that, arguments); }; handler.original = original; } events = that._events[eventName] = that._events[eventName] || []; events.push(handler); } }; for (idx = 0, length = eventNames.length; idx < length; idx++) loop( ); /* eslint-enable no-loop-func */ return that; }; Observable.prototype.one = function one (eventNames, handlers) { return this.bind(eventNames, handlers, true); }; Observable.prototype.first = function first (eventName, handlers) { var that = this, idx, eventNames = typeof eventName === STRING ? [eventName] : eventName, length, handler, handlersIsFunction = typeof handlers === FUNCTION, events; for (idx = 0, length = eventNames.length; idx < length; idx++) { var eventName$1 = eventNames[idx]; handler = handlersIsFunction ? handlers : handlers[eventName$1]; if (handler) { events = that._events[eventName$1] = that._events[eventName$1] || []; events.unshift(handler); } } return that; }; Observable.prototype.trigger = function trigger (eventName, eventArgs) { var that = this, events = that._events[eventName], idx, length; if (events) { var e = eventArgs || {}; e.sender = that; e._defaultPrevented = false; e.preventDefault = preventDefault$2; e.isDefaultPrevented = isDefaultPrevented; events = events.slice(); for (idx = 0, length = events.length; idx < length; idx++) { events[idx].call(that, e); } return e._defaultPrevented === true; } return false; }; Observable.prototype.unbind = function unbind (eventName, handler) { var that = this, events = that._events[eventName], idx; if (eventName === undefined) { that._events = {}; } else if (events) { if (handler) { for (idx = events.length - 1; idx >= 0; idx--) { if (events[idx] === handler || events[idx].original === handler) { events.splice(idx, 1); } } } else { that._events[eventName] = []; } } return that; }; Observable.prototype._setEvents = function _setEvents (options) { var length = (this.events || []).length; for (var idx = 0; idx < length; idx ++) { var e = this.events[idx]; if (this.options[e] && options[e]) { this.unbind(e, this.options[e]); if (this._events && this._events[e]) { delete this._events[e]; } } } this.bind(this.events, options); }; var extend$d = Object.assign; var preventDefault$1 = function (e) { e.preventDefault(); }; var DEFAULT_MIN_HOLD = 800, CLICK_DELAY = 300, DEFAULT_THRESHOLD = 0, PRESS = 'press', HOLD = 'hold', SELECT$1 = 'select', START = 'start', MOVE = 'move', END = 'end', CANCEL = 'cancel', TAP = 'tap', DOUBLETAP = 'doubleTap', RELEASE = 'release', GESTURESTART = 'gesturestart', GESTURECHANGE = 'gesturechange', GESTUREEND = 'gestureend', GESTURETAP = 'gesturetap'; var THRESHOLD = { 'api': 0, 'touch': 0, 'mouse': 9, 'pointer': 9 }; function touchDelta(touch1, touch2) { var x1 = touch1.x.location, y1 = touch1.y.location, x2 = touch2.x.location, y2 = touch2.y.location, dx = x1 - x2, dy = y1 - y2; return { center: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 }, distance: Math.sqrt(dx * dx + dy * dy) }; } function getTouches(e) { var touches = [], originalEvent = e.originalEvent || e, currentTarget = e.currentTarget; if (e.api) { touches.push({ id: 2, // hardcoded ID for API call event: e, target: e.target, currentTarget: e.target, location: e, type: 'api' }); } else { touches.push({ location: originalEvent, event: e, target: e.target, currentTarget: currentTarget, id: originalEvent.pointerId, type: 'pointer' }); } return touches; } var TouchAxis = function TouchAxis(axis, location) { var that = this; that.support = getSupportedFeatures(); that.invalidZeroEvents = this.support.mobileOS && this.support.mobileOS.android; that.axis = axis; that._updateLocationData(location); that.startLocation = that.location; that.velocity = that.delta = 0; that.timeStamp = now(); }; TouchAxis.prototype.move = function move (location) { var that = this, offset = location['page' + that.axis], timeStamp = now(), timeDelta = timeStamp - that.timeStamp || 1; if (!offset && this.invalidZeroEvents) { return; } that.delta = offset - that.location; that._updateLocationData(location); that.initialDelta = offset - that.startLocation; that.velocity = that.delta / timeDelta; that.timeStamp = timeStamp; }; TouchAxis.prototype._updateLocationData = function _updateLocationData (location) { var that = this, axis = that.axis; that.location = location['page' + axis]; that.client = location['client' + axis]; that.screen = location['screen' + axis]; }; var Touch = function Touch(userEvents, target, touchInfo) { extend$d(this, { x: new TouchAxis('X', touchInfo.location), y: new TouchAxis('Y', touchInfo.location), type: touchInfo.type, threshold: userEvents.threshold || THRESHOLD[touchInfo.type], userEvents: userEvents, target: target, currentTarget: touchInfo.currentTarget, initialTouch: touchInfo.target, id: touchInfo.id, pressEvent: touchInfo, _clicks: userEvents._clicks, supportDoubleTap: userEvents.supportDoubleTap, _moved: false, _finished: false }); }; Touch.prototype.press = function press () { var this$1$1 = this; this._holdTimeout = setTimeout(function () { return this$1$1._hold(); }, this.userEvents.minHold); this._trigger(PRESS, this.pressEvent); }; Touch.prototype._tap = function _tap (touchInfo) { var that = this; that.userEvents._clicks++; if (that.userEvents._clicks === 1) { that._clickTimeout = setTimeout(function() { if (that.userEvents._clicks === 1) { that._trigger(TAP, touchInfo); } else { that._trigger(DOUBLETAP, touchInfo); } that.userEvents._clicks = 0; }, CLICK_DELAY); } }; Touch.prototype._hold = function _hold () { this._trigger(HOLD, this.pressEvent); }; /* eslint-disable consistent-return */ Touch.prototype.move = function move (touchInfo) { var that = this; var preventMove = touchInfo.type !== 'api' && that.userEvents._shouldNotMove; if (that._finished || preventMove) { return; } that.x.move(touchInfo.location); that.y.move(touchInfo.location); if (!that._moved) { if (that._withinIgnoreThreshold()) { return; } if (!UserEvents.current || UserEvents.current === that.userEvents) { that._start(touchInfo); } else { return that.dispose(); } } if (!that._finished) { that._trigger(MOVE, touchInfo); } }; /* eslint-enable consistent-return */ Touch.prototype.end = function end (touchInfo) { this.endTime = now(); if (this._finished) { return; } this._finished = true; this._trigger(RELEASE, touchInfo); if (this._moved) { this._trigger(END, touchInfo); } else { if (this.supportDoubleTap) { this._tap(touchInfo); } else { this._trigger(TAP, touchInfo); } } clearTimeout(this._holdTimeout); this.dispose(); }; Touch.prototype.dispose = function dispose () { var userEvents = this.userEvents, activeTouches = userEvents.touches || []; this._finished = true; this.pressEvent = null; clearTimeout(this._holdTimeout); // activeTouches.splice($.inArray(this, activeTouches), 1); var activeTouchIndex = activeTouches.indexOf(this); activeTouches.splice(activeTouchIndex, 1); }; Touch.prototype.skip = function skip () { this.dispose(); }; Touch.prototype.cancel = function cancel () { this.dispose(); }; Touch.prototype.isMoved = function isMoved () { return this._moved; }; Touch.prototype._start = function _start (touchInfo) { clearTimeout(this._holdTimeout); this.startTime = now(); this._moved = true; this._trigger(START, touchInfo); }; Touch.prototype._trigger = function _trigger (name, touchInfo) { var e = touchInfo.event; var data = { touch: this, x: this.x, y: this.y, target: this.target, event: e }; if (this.userEvents.notify(name, data)) { e.preventDefault(); } }; Touch.prototype._withinIgnoreThreshold = function _withinIgnoreThreshold () { var xDelta = this.x.initialDelta, yDelta = this.y.initialDelta; return Math.sqrt(xDelta * xDelta + yDelta * yDelta) <= this.threshold; }; function withEachUpEvent(callback) { var downEvents = eventMap.up.split(' '), idx = 0, length = downEvents.length; for (; idx < length; idx++) { callback(downEvents[idx]); } } var UserEvents = /*@__PURE__*/(function (Observable) { function UserEvents(element, options) { Observable.call(this); var that = this; var filter; var support = getSupportedFeatures(); this.support = support; /* eslint-disable no-param-reassign */ options = options || {}; /* eslint-enable no-param-reassign */ this.options = options; filter = that.filter = options.filter; that.threshold = options.threshold || DEFAULT_THRESHOLD; that.minHold = options.minHold || DEFAULT_MIN_HOLD; that.touches = []; that._maxTouches = options.multiTouch ? 2 : 1; that.allowSelection = options.allowSelection; that.captureUpIfMoved = options.captureUpIfMoved; that._clicks = 0; that.supportDoubleTap = options.supportDoubleTap; extend$d(that, { element: element, surface: options.surface || element, stopPropagation: options.stopPropagation, pressed: false }); this._surfaceMoveHandler = this._move.bind(this); on(that.surface, applyEventMap('move'), this._surfaceMoveHandler); this._surfaceEndHandler = this._end.bind(this); on(that.surface, applyEventMap('up cancel'), this._surfaceEndHandler); this._elementStartHandler = this._start.bind(this); on(element, applyEventMap('down'), filter, this._elementStartHandler); element.style['touch-action'] = options.touchAction || 'none'; if (options.preventDragEvent) { this._elementDragStartHandler = preventDefault$1; on(element, applyEventMap('dragstart'), this._elementDragStartHandler); } // element.on(kendo.applyEventMap('mousedown'), filter, { // root: element // } '_select'); // todo: use root this._elementSelectHandler = this._select.bind(this); on(element, applyEventMap('mousedown'), filter, this._elementSelectHandler); if (that.captureUpIfMoved) { var surfaceElement = that.surface; that._preventIfMovingProxy = that.preventIfMoving.bind(that); withEachUpEvent(function(eventName) { surfaceElement.addEventListener(eventName, that._preventIfMovingProxy, true); }); } that.bind([ PRESS, HOLD, TAP, DOUBLETAP, START, MOVE, END, RELEASE, CANCEL, GESTURESTART, GESTURECHANGE, GESTUREEND, GESTURETAP, SELECT$1 ], options); } if ( Observable ) UserEvents.__proto__ = Observable; UserEvents.prototype = Object.create( Observable && Observable.prototype ); UserEvents.prototype.constructor = UserEvents; UserEvents.prototype.preventIfMoving = function preventIfMoving (e) { if (this._isMoved()) { e.preventDefault(); } }; UserEvents.prototype.destroy = function destroy () { var that = this; var options = this.options; var element = this.element; if (that._destroyed) { return; } that._destroyed = true; if (that.captureUpIfMoved) { var surfaceElement = that.surface; withEachUpEvent(function(eventName) { surfaceElement.removeEventListener(eventName, that._preventIfMovingProxy, true); }); } off(that.surface, applyEventMap('move'), this._surfaceMoveHandler); off(that.surface, applyEventMap('up cancel'), this._surfaceEndHandler); off(element, applyEventMap('down'), this._elementStartHandler); if (options.preventDragEvent) { off(element, applyEventMap('dragstart'), this._elementDragStartHandler); } off(element, applyEventMap('mousedown'), this._elementSelectHandler); that._disposeAll(); that.unbind(); delete that.surface; delete that.element; delete that.currentTarget; }; UserEvents.prototype.capture = function capture () { UserEvents.current = this; }; UserEvents.prototype.cancel = function cancel () { this._disposeAll(); this.trigger(CANCEL); }; UserEvents.prototype.notify = function notify (event, data) { var that = this, touches = that.touches; var eventName = event; if (this._isMultiTouch()) { switch (eventName) { case MOVE: eventName = GESTURECHANGE; break; case END: eventName = GESTUREEND; break; case TAP: eventName = GESTURETAP; break; } extend$d(data, { touches: touches }, touchDelta(touches[0], touches[1])); } return this.trigger(eventName, extend$d(data, { type: eventName })); }; UserEvents.prototype.press = function press (x, y, target) { this._apiCall('_start', x, y, target); }; UserEvents.prototype.move = function move (x, y) { this._apiCall('_move', x, y); }; UserEvents.prototype.end = function end (x, y) { this._apiCall('_end', x, y); }; UserEvents.prototype._isMultiTouch = function _isMultiTouch () { return this.touches.length > 1; }; UserEvents.prototype._maxTouchesReached = function _maxTouchesReached () { return this.touches.length >= this._maxTouches; }; UserEvents.prototype._disposeAll = function _disposeAll () { var touches = this.touches; while (touches.length > 0) { touches.pop().dispose(); } }; UserEvents.prototype._isMoved = function _isMoved () { return grep(this.touches, function(touch) { return touch.isMoved(); }).length; }; UserEvents.prototype._select = function _select (e) { if (!this.allowSe