UNPKG

@blueking/bkcharts

Version:

```sh npm install @blueking/bkcharts ```

2,130 lines (1,790 loc) 986 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory()); })(this, (function () { 'use strict'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); } function _arrayLikeToArray$j(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray$j(arr); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _unsupportedIterableToArray$j(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$j(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$j(o, minLen); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray$j(arr) || _nonIterableSpread(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray$j(arr, i) || _nonIterableRest(); } var requestAnimFrame = function () { if (typeof window === 'undefined') { return function (callback) { return callback(); }; } return window.requestAnimationFrame; }(); function throttled(fn, thisArg, updateFn) { var updateArgs = updateFn || function (args) { return Array.prototype.slice.call(args); }; var ticking = false; var args = []; return function () { for (var _len = arguments.length, rest = new Array(_len), _key = 0; _key < _len; _key++) { rest[_key] = arguments[_key]; } args = updateArgs(rest); if (!ticking) { ticking = true; requestAnimFrame.call(window, function () { ticking = false; fn.apply(thisArg, args); }); } }; } function debounce(fn, delay) { var timeout; return function () { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (delay) { clearTimeout(timeout); timeout = setTimeout(fn, delay, args); } else { fn.apply(this, args); } return delay; }; } var _toLeftRightCenter = function _toLeftRightCenter(align) { return align === 'start' ? 'left' : align === 'end' ? 'right' : 'center'; }; var _alignStartEnd = function _alignStartEnd(align, start, end) { return align === 'start' ? start : align === 'end' ? end : (start + end) / 2; }; var _textX = function _textX(align, left, right, rtl) { var check = rtl ? 'left' : 'right'; return align === check ? right : align === 'center' ? (left + right) / 2 : left; }; var Animator = /*#__PURE__*/function () { function Animator() { _classCallCheck(this, Animator); this._request = null; this._charts = new Map(); this._running = false; this._lastDate = undefined; } _createClass(Animator, [{ key: "_notify", value: function _notify(chart, anims, date, type) { var callbacks = anims.listeners[type]; var numSteps = anims.duration; callbacks.forEach(function (fn) { return fn({ chart: chart, initial: anims.initial, numSteps: numSteps, currentStep: Math.min(date - anims.start, numSteps) }); }); } }, { key: "_refresh", value: function _refresh() { var _this = this; if (this._request) { return; } this._running = true; this._request = requestAnimFrame.call(window, function () { _this._update(); _this._request = null; if (_this._running) { _this._refresh(); } }); } }, { key: "_update", value: function _update() { var _this2 = this; var date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Date.now(); var remaining = 0; this._charts.forEach(function (anims, chart) { if (!anims.running || !anims.items.length) { return; } var items = anims.items; var i = items.length - 1; var draw = false; var item; for (; i >= 0; --i) { item = items[i]; if (item._active) { if (item._total > anims.duration) { anims.duration = item._total; } item.tick(date); draw = true; } else { items[i] = items[items.length - 1]; items.pop(); } } if (draw) { chart.draw(); _this2._notify(chart, anims, date, 'progress'); } if (!items.length) { anims.running = false; _this2._notify(chart, anims, date, 'complete'); anims.initial = false; } remaining += items.length; }); this._lastDate = date; if (remaining === 0) { this._running = false; } } }, { key: "_getAnims", value: function _getAnims(chart) { var charts = this._charts; var anims = charts.get(chart); if (!anims) { anims = { running: false, initial: true, items: [], listeners: { complete: [], progress: [] } }; charts.set(chart, anims); } return anims; } }, { key: "listen", value: function listen(chart, event, cb) { this._getAnims(chart).listeners[event].push(cb); } }, { key: "add", value: function add(chart, items) { var _this$_getAnims$items; if (!items || !items.length) { return; } (_this$_getAnims$items = this._getAnims(chart).items).push.apply(_this$_getAnims$items, _toConsumableArray(items)); } }, { key: "has", value: function has(chart) { return this._getAnims(chart).items.length > 0; } }, { key: "start", value: function start(chart) { var anims = this._charts.get(chart); if (!anims) { return; } anims.running = true; anims.start = Date.now(); anims.duration = anims.items.reduce(function (acc, cur) { return Math.max(acc, cur._duration); }, 0); this._refresh(); } }, { key: "running", value: function running(chart) { if (!this._running) { return false; } var anims = this._charts.get(chart); if (!anims || !anims.running || !anims.items.length) { return false; } return true; } }, { key: "stop", value: function stop(chart) { var anims = this._charts.get(chart); if (!anims || !anims.items.length) { return; } var items = anims.items; var i = items.length - 1; for (; i >= 0; --i) { items[i].cancel(); } anims.items = []; this._notify(chart, anims, Date.now(), 'complete'); } }, { key: "remove", value: function remove(chart) { return this._charts["delete"](chart); } }]); return Animator; }(); var animator = new Animator(); function _createForOfIteratorHelper$i(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$i(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$i(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$i(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$i(o, minLen); } function _arrayLikeToArray$i(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function noop$1() {} var uid = function () { var id = 0; return function () { return id++; }; }(); function isNullOrUndef(value) { return value === null || typeof value === 'undefined'; } function isArray$1(value) { if (Array.isArray && Array.isArray(value)) { return true; } var type = Object.prototype.toString.call(value); if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') { return true; } return false; } function isObject(value) { return value !== null && Object.prototype.toString.call(value) === '[object Object]'; } var isNumberFinite = function isNumberFinite(value) { return (typeof value === 'number' || value instanceof Number) && isFinite(+value); }; function finiteOrDefault(value, defaultValue) { return isNumberFinite(value) ? value : defaultValue; } function valueOrDefault(value, defaultValue) { return typeof value === 'undefined' ? defaultValue : value; } var toPercentage = function toPercentage(value, dimension) { return typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 : value / dimension; }; var toDimension = function toDimension(value, dimension) { return typeof value === 'string' && value.endsWith('%') ? parseFloat(value) / 100 * dimension : +value; }; function callback(fn, args, thisArg) { if (fn && typeof fn.call === 'function') { return fn.apply(thisArg, args); } } function each(loopable, fn, thisArg, reverse) { var i, len, keys; if (isArray$1(loopable)) { len = loopable.length; if (reverse) { for (i = len - 1; i >= 0; i--) { fn.call(thisArg, loopable[i], i); } } else { for (i = 0; i < len; i++) { fn.call(thisArg, loopable[i], i); } } } else if (isObject(loopable)) { keys = Object.keys(loopable); len = keys.length; for (i = 0; i < len; i++) { fn.call(thisArg, loopable[keys[i]], keys[i]); } } } function _elementsEqual(a0, a1) { var i, ilen, v0, v1; if (!a0 || !a1 || a0.length !== a1.length) { return false; } for (i = 0, ilen = a0.length; i < ilen; ++i) { v0 = a0[i]; v1 = a1[i]; if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) { return false; } } return true; } function clone$3(source) { if (isArray$1(source)) { return source.map(clone$3); } if (isObject(source)) { var target = Object.create(null); var keys = Object.keys(source); var klen = keys.length; var k = 0; for (; k < klen; ++k) { target[keys[k]] = clone$3(source[keys[k]]); } return target; } return source; } function isValidKey(key) { return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1; } function _merger(key, target, source, options) { if (!isValidKey(key)) { return; } var tval = target[key]; var sval = source[key]; if (isObject(tval) && isObject(sval)) { merge(tval, sval, options); } else { target[key] = clone$3(sval); } } function merge(target, source, options) { var sources = isArray$1(source) ? source : [source]; var ilen = sources.length; if (!isObject(target)) { return target; } options = options || {}; var merger = options.merger || _merger; for (var i = 0; i < ilen; ++i) { source = sources[i]; if (!isObject(source)) { continue; } var keys = Object.keys(source); for (var k = 0, klen = keys.length; k < klen; ++k) { merger(keys[k], target, source, options); } } return target; } function mergeIf(target, source) { return merge(target, source, { merger: _mergerIf }); } function _mergerIf(key, target, source) { if (!isValidKey(key)) { return; } var tval = target[key]; var sval = source[key]; if (isObject(tval) && isObject(sval)) { mergeIf(tval, sval); } else if (!Object.prototype.hasOwnProperty.call(target, key)) { target[key] = clone$3(sval); } } var emptyString = ''; var dot = '.'; function indexOfDotOrLength(key, start) { var idx = key.indexOf(dot, start); return idx === -1 ? key.length : idx; } function resolveObjectKey(obj, key) { if (key === emptyString) { return obj; } var pos = 0; var idx = indexOfDotOrLength(key, pos); while (obj && idx > pos) { obj = obj[key.substr(pos, idx - pos)]; pos = idx + 1; idx = indexOfDotOrLength(key, pos); } return obj; } function _capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } var defined = function defined(value) { return typeof value !== 'undefined'; }; var isFunction = function isFunction(value) { return typeof value === 'function'; }; var setsEqual = function setsEqual(a, b) { if (a.size !== b.size) { return false; } var _iterator = _createForOfIteratorHelper$i(a), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; if (!b.has(item)) { return false; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return true; }; function _isClickEvent(e) { return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu'; } var PI = Math.PI; var TAU = 2 * PI; var PITAU = TAU + PI; var INFINITY = Number.POSITIVE_INFINITY; var RAD_PER_DEG = PI / 180; var HALF_PI = PI / 2; var QUARTER_PI = PI / 4; var TWO_THIRDS_PI = PI * 2 / 3; var log10 = Math.log10; var sign = Math.sign; function niceNum(range) { var roundedRange = Math.round(range); range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range; var niceRange = Math.pow(10, Math.floor(log10(range))); var fraction = range / niceRange; var niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10; return niceFraction * niceRange; } function _factorize(value) { var result = []; var sqrt = Math.sqrt(value); var i; for (i = 1; i < sqrt; i++) { if (value % i === 0) { result.push(i); result.push(value / i); } } if (sqrt === (sqrt | 0)) { result.push(sqrt); } result.sort(function (a, b) { return a - b; }).pop(); return result; } function isNumber$1(n) { return !isNaN(parseFloat(n)) && isFinite(n); } function almostEquals(x, y, epsilon) { return Math.abs(x - y) < epsilon; } function almostWhole(x, epsilon) { var rounded = Math.round(x); return rounded - epsilon <= x && rounded + epsilon >= x; } function _setMinAndMaxByKey(array, target, property) { var i, ilen, value; for (i = 0, ilen = array.length; i < ilen; i++) { value = array[i][property]; if (!isNaN(value)) { target.min = Math.min(target.min, value); target.max = Math.max(target.max, value); } } } function toRadians(degrees) { return degrees * (PI / 180); } function toDegrees(radians) { return radians * (180 / PI); } function _decimalPlaces(x) { if (!isNumberFinite(x)) { return; } var e = 1; var p = 0; while (Math.round(x * e) / e !== x) { e *= 10; p++; } return p; } function getAngleFromPoint(centrePoint, anglePoint) { var distanceFromXCenter = anglePoint.x - centrePoint.x; var distanceFromYCenter = anglePoint.y - centrePoint.y; var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); if (angle < -0.5 * PI) { angle += TAU; } return { angle: angle, distance: radialDistanceFromCenter }; } function distanceBetweenPoints(pt1, pt2) { return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); } function _angleDiff(a, b) { return (a - b + PITAU) % TAU - PI; } function _normalizeAngle(a) { return (a % TAU + TAU) % TAU; } function _angleBetween(angle, start, end, sameAngleIsFullCircle) { var a = _normalizeAngle(angle); var s = _normalizeAngle(start); var e = _normalizeAngle(end); var angleToStart = _normalizeAngle(s - a); var angleToEnd = _normalizeAngle(e - a); var startToAngle = _normalizeAngle(a - s); var endToAngle = _normalizeAngle(a - e); return a === s || a === e || sameAngleIsFullCircle && s === e || angleToStart > angleToEnd && startToAngle < endToAngle; } function _limitValue(value, min, max) { return Math.max(min, Math.min(max, value)); } function _int16Range(value) { return _limitValue(value, -32768, 32767); } function _isBetween(value, start, end) { var epsilon = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1e-6; return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon; } var atEdge = function atEdge(t) { return t === 0 || t === 1; }; var elasticIn = function elasticIn(t, s, p) { return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p)); }; var elasticOut = function elasticOut(t, s, p) { return Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1; }; var effects = { linear: function linear(t) { return t; }, easeInQuad: function easeInQuad(t) { return t * t; }, easeOutQuad: function easeOutQuad(t) { return -t * (t - 2); }, easeInOutQuad: function easeInOutQuad(t) { return (t /= 0.5) < 1 ? 0.5 * t * t : -0.5 * (--t * (t - 2) - 1); }, easeInCubic: function easeInCubic(t) { return t * t * t; }, easeOutCubic: function easeOutCubic(t) { return (t -= 1) * t * t + 1; }, easeInOutCubic: function easeInOutCubic(t) { return (t /= 0.5) < 1 ? 0.5 * t * t * t : 0.5 * ((t -= 2) * t * t + 2); }, easeInQuart: function easeInQuart(t) { return t * t * t * t; }, easeOutQuart: function easeOutQuart(t) { return -((t -= 1) * t * t * t - 1); }, easeInOutQuart: function easeInOutQuart(t) { return (t /= 0.5) < 1 ? 0.5 * t * t * t * t : -0.5 * ((t -= 2) * t * t * t - 2); }, easeInQuint: function easeInQuint(t) { return t * t * t * t * t; }, easeOutQuint: function easeOutQuint(t) { return (t -= 1) * t * t * t * t + 1; }, easeInOutQuint: function easeInOutQuint(t) { return (t /= 0.5) < 1 ? 0.5 * t * t * t * t * t : 0.5 * ((t -= 2) * t * t * t * t + 2); }, easeInSine: function easeInSine(t) { return -Math.cos(t * HALF_PI) + 1; }, easeOutSine: function easeOutSine(t) { return Math.sin(t * HALF_PI); }, easeInOutSine: function easeInOutSine(t) { return -0.5 * (Math.cos(PI * t) - 1); }, easeInExpo: function easeInExpo(t) { return t === 0 ? 0 : Math.pow(2, 10 * (t - 1)); }, easeOutExpo: function easeOutExpo(t) { return t === 1 ? 1 : -Math.pow(2, -10 * t) + 1; }, easeInOutExpo: function easeInOutExpo(t) { return atEdge(t) ? t : t < 0.5 ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2); }, easeInCirc: function easeInCirc(t) { return t >= 1 ? t : -(Math.sqrt(1 - t * t) - 1); }, easeOutCirc: function easeOutCirc(t) { return Math.sqrt(1 - (t -= 1) * t); }, easeInOutCirc: function easeInOutCirc(t) { return (t /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); }, easeInElastic: function easeInElastic(t) { return atEdge(t) ? t : elasticIn(t, 0.075, 0.3); }, easeOutElastic: function easeOutElastic(t) { return atEdge(t) ? t : elasticOut(t, 0.075, 0.3); }, easeInOutElastic: function easeInOutElastic(t) { var s = 0.1125; var p = 0.45; return atEdge(t) ? t : t < 0.5 ? 0.5 * elasticIn(t * 2, s, p) : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p); }, easeInBack: function easeInBack(t) { var s = 1.70158; return t * t * ((s + 1) * t - s); }, easeOutBack: function easeOutBack(t) { var s = 1.70158; return (t -= 1) * t * ((s + 1) * t + s) + 1; }, easeInOutBack: function easeInOutBack(t) { var s = 1.70158; if ((t /= 0.5) < 1) { return 0.5 * (t * t * (((s *= 1.525) + 1) * t - s)); } return 0.5 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2); }, easeInBounce: function easeInBounce(t) { return 1 - effects.easeOutBounce(1 - t); }, easeOutBounce: function easeOutBounce(t) { var m = 7.5625; var d = 2.75; if (t < 1 / d) { return m * t * t; } if (t < 2 / d) { return m * (t -= 1.5 / d) * t + 0.75; } if (t < 2.5 / d) { return m * (t -= 2.25 / d) * t + 0.9375; } return m * (t -= 2.625 / d) * t + 0.984375; }, easeInOutBounce: function easeInOutBounce(t) { return t < 0.5 ? effects.easeInBounce(t * 2) * 0.5 : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; } }; /*! * @kurkle/color v0.1.9 * https://github.com/kurkle/color#readme * (c) 2020 Jukka Kurkela * Released under the MIT License */ var map = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 }; var hex = '0123456789ABCDEF'; var h1 = function h1(b) { return hex[b & 0xF]; }; var h2 = function h2(b) { return hex[(b & 0xF0) >> 4] + hex[b & 0xF]; }; var eq = function eq(b) { return (b & 0xF0) >> 4 === (b & 0xF); }; function isShort(v) { return eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a); } function hexParse(str) { var len = str.length; var ret; if (str[0] === '#') { if (len === 4 || len === 5) { ret = { r: 255 & map[str[1]] * 17, g: 255 & map[str[2]] * 17, b: 255 & map[str[3]] * 17, a: len === 5 ? map[str[4]] * 17 : 255 }; } else if (len === 7 || len === 9) { ret = { r: map[str[1]] << 4 | map[str[2]], g: map[str[3]] << 4 | map[str[4]], b: map[str[5]] << 4 | map[str[6]], a: len === 9 ? map[str[7]] << 4 | map[str[8]] : 255 }; } } return ret; } function _hexString(v) { var f = isShort(v) ? h1 : h2; return v ? '#' + f(v.r) + f(v.g) + f(v.b) + (v.a < 255 ? f(v.a) : '') : v; } function round(v) { return v + 0.5 | 0; } var lim = function lim(v, l, h) { return Math.max(Math.min(v, h), l); }; function p2b(v) { return lim(round(v * 2.55), 0, 255); } function n2b(v) { return lim(round(v * 255), 0, 255); } function b2n(v) { return lim(round(v / 2.55) / 100, 0, 1); } function n2p(v) { return lim(round(v * 100), 0, 100); } var RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/; function rgbParse(str) { var m = RGB_RE.exec(str); var a = 255; var r, g, b; if (!m) { return; } if (m[7] !== r) { var v = +m[7]; a = 255 & (m[8] ? p2b(v) : v * 255); } r = +m[1]; g = +m[3]; b = +m[5]; r = 255 & (m[2] ? p2b(r) : r); g = 255 & (m[4] ? p2b(g) : g); b = 255 & (m[6] ? p2b(b) : b); return { r: r, g: g, b: b, a: a }; } function _rgbString(v) { return v && (v.a < 255 ? "rgba(".concat(v.r, ", ").concat(v.g, ", ").concat(v.b, ", ").concat(b2n(v.a), ")") : "rgb(".concat(v.r, ", ").concat(v.g, ", ").concat(v.b, ")")); } var HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/; function hsl2rgbn(h, s, l) { var a = s * Math.min(l, 1 - l); var f = function f(n) { var k = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (n + h / 30) % 12; return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); }; return [f(0), f(8), f(4)]; } function hsv2rgbn(h, s, v) { var f = function f(n) { var k = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (n + h / 60) % 6; return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0); }; return [f(5), f(3), f(1)]; } function hwb2rgbn(h, w, b) { var rgb = hsl2rgbn(h, 1, 0.5); var i; if (w + b > 1) { i = 1 / (w + b); w *= i; b *= i; } for (i = 0; i < 3; i++) { rgb[i] *= 1 - w - b; rgb[i] += w; } return rgb; } function rgb2hsl(v) { var range = 255; var r = v.r / range; var g = v.g / range; var b = v.b / range; var max = Math.max(r, g, b); var min = Math.min(r, g, b); var l = (max + min) / 2; var h, s, d; if (max !== min) { d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; h = h * 60 + 0.5; } return [h | 0, s || 0, l]; } function calln(f, a, b, c) { return (Array.isArray(a) ? f(a[0], a[1], a[2]) : f(a, b, c)).map(n2b); } function hsl2rgb(h, s, l) { return calln(hsl2rgbn, h, s, l); } function hwb2rgb(h, w, b) { return calln(hwb2rgbn, h, w, b); } function hsv2rgb(h, s, v) { return calln(hsv2rgbn, h, s, v); } function hue(h) { return (h % 360 + 360) % 360; } function hueParse(str) { var m = HUE_RE.exec(str); var a = 255; var v; if (!m) { return; } if (m[5] !== v) { a = m[6] ? p2b(+m[5]) : n2b(+m[5]); } var h = hue(+m[2]); var p1 = +m[3] / 100; var p2 = +m[4] / 100; if (m[1] === 'hwb') { v = hwb2rgb(h, p1, p2); } else if (m[1] === 'hsv') { v = hsv2rgb(h, p1, p2); } else { v = hsl2rgb(h, p1, p2); } return { r: v[0], g: v[1], b: v[2], a: a }; } function _rotate(v, deg) { var h = rgb2hsl(v); h[0] = hue(h[0] + deg); h = hsl2rgb(h); v.r = h[0]; v.g = h[1]; v.b = h[2]; } function _hslString(v) { if (!v) { return; } var a = rgb2hsl(v); var h = a[0]; var s = n2p(a[1]); var l = n2p(a[2]); return v.a < 255 ? "hsla(".concat(h, ", ").concat(s, "%, ").concat(l, "%, ").concat(b2n(v.a), ")") : "hsl(".concat(h, ", ").concat(s, "%, ").concat(l, "%)"); } var map$1 = { x: 'dark', Z: 'light', Y: 're', X: 'blu', W: 'gr', V: 'medium', U: 'slate', A: 'ee', T: 'ol', S: 'or', B: 'ra', C: 'lateg', D: 'ights', R: 'in', Q: 'turquois', E: 'hi', P: 'ro', O: 'al', N: 'le', M: 'de', L: 'yello', F: 'en', K: 'ch', G: 'arks', H: 'ea', I: 'ightg', J: 'wh' }; var names = { OiceXe: 'f0f8ff', antiquewEte: 'faebd7', aqua: 'ffff', aquamarRe: '7fffd4', azuY: 'f0ffff', beige: 'f5f5dc', bisque: 'ffe4c4', black: '0', blanKedOmond: 'ffebcd', Xe: 'ff', XeviTet: '8a2be2', bPwn: 'a52a2a', burlywood: 'deb887', caMtXe: '5f9ea0', KartYuse: '7fff00', KocTate: 'd2691e', cSO: 'ff7f50', cSnflowerXe: '6495ed', cSnsilk: 'fff8dc', crimson: 'dc143c', cyan: 'ffff', xXe: '8b', xcyan: '8b8b', xgTMnPd: 'b8860b', xWay: 'a9a9a9', xgYF: '6400', xgYy: 'a9a9a9', xkhaki: 'bdb76b', xmagFta: '8b008b', xTivegYF: '556b2f', xSange: 'ff8c00', xScEd: '9932cc', xYd: '8b0000', xsOmon: 'e9967a', xsHgYF: '8fbc8f', xUXe: '483d8b', xUWay: '2f4f4f', xUgYy: '2f4f4f', xQe: 'ced1', xviTet: '9400d3', dAppRk: 'ff1493', dApskyXe: 'bfff', dimWay: '696969', dimgYy: '696969', dodgerXe: '1e90ff', fiYbrick: 'b22222', flSOwEte: 'fffaf0', foYstWAn: '228b22', fuKsia: 'ff00ff', gaRsbSo: 'dcdcdc', ghostwEte: 'f8f8ff', gTd: 'ffd700', gTMnPd: 'daa520', Way: '808080', gYF: '8000', gYFLw: 'adff2f', gYy: '808080', honeyMw: 'f0fff0', hotpRk: 'ff69b4', RdianYd: 'cd5c5c', Rdigo: '4b0082', ivSy: 'fffff0', khaki: 'f0e68c', lavFMr: 'e6e6fa', lavFMrXsh: 'fff0f5', lawngYF: '7cfc00', NmoncEffon: 'fffacd', ZXe: 'add8e6', ZcSO: 'f08080', Zcyan: 'e0ffff', ZgTMnPdLw: 'fafad2', ZWay: 'd3d3d3', ZgYF: '90ee90', ZgYy: 'd3d3d3', ZpRk: 'ffb6c1', ZsOmon: 'ffa07a', ZsHgYF: '20b2aa', ZskyXe: '87cefa', ZUWay: '778899', ZUgYy: '778899', ZstAlXe: 'b0c4de', ZLw: 'ffffe0', lime: 'ff00', limegYF: '32cd32', lRF: 'faf0e6', magFta: 'ff00ff', maPon: '800000', VaquamarRe: '66cdaa', VXe: 'cd', VScEd: 'ba55d3', VpurpN: '9370db', VsHgYF: '3cb371', VUXe: '7b68ee', VsprRggYF: 'fa9a', VQe: '48d1cc', VviTetYd: 'c71585', midnightXe: '191970', mRtcYam: 'f5fffa', mistyPse: 'ffe4e1', moccasR: 'ffe4b5', navajowEte: 'ffdead', navy: '80', Tdlace: 'fdf5e6', Tive: '808000', TivedBb: '6b8e23', Sange: 'ffa500', SangeYd: 'ff4500', ScEd: 'da70d6', pOegTMnPd: 'eee8aa', pOegYF: '98fb98', pOeQe: 'afeeee', pOeviTetYd: 'db7093', papayawEp: 'ffefd5', pHKpuff: 'ffdab9', peru: 'cd853f', pRk: 'ffc0cb', plum: 'dda0dd', powMrXe: 'b0e0e6', purpN: '800080', YbeccapurpN: '663399', Yd: 'ff0000', Psybrown: 'bc8f8f', PyOXe: '4169e1', saddNbPwn: '8b4513', sOmon: 'fa8072', sandybPwn: 'f4a460', sHgYF: '2e8b57', sHshell: 'fff5ee', siFna: 'a0522d', silver: 'c0c0c0', skyXe: '87ceeb', UXe: '6a5acd', UWay: '708090', UgYy: '708090', snow: 'fffafa', sprRggYF: 'ff7f', stAlXe: '4682b4', tan: 'd2b48c', teO: '8080', tEstN: 'd8bfd8', tomato: 'ff6347', Qe: '40e0d0', viTet: 'ee82ee', JHt: 'f5deb3', wEte: 'ffffff', wEtesmoke: 'f5f5f5', Lw: 'ffff00', LwgYF: '9acd32' }; function unpack() { var unpacked = {}; var keys = Object.keys(names); var tkeys = Object.keys(map$1); var i, j, k, ok, nk; for (i = 0; i < keys.length; i++) { ok = nk = keys[i]; for (j = 0; j < tkeys.length; j++) { k = tkeys[j]; nk = nk.replace(k, map$1[k]); } k = parseInt(names[ok], 16); unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF]; } return unpacked; } var names$1; function nameParse(str) { if (!names$1) { names$1 = unpack(); names$1.transparent = [0, 0, 0, 0]; } var a = names$1[str.toLowerCase()]; return a && { r: a[0], g: a[1], b: a[2], a: a.length === 4 ? a[3] : 255 }; } function modHSL(v, i, ratio) { if (v) { var tmp = rgb2hsl(v); tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1)); tmp = hsl2rgb(tmp); v.r = tmp[0]; v.g = tmp[1]; v.b = tmp[2]; } } function clone$2(v, proto) { return v ? Object.assign(proto || {}, v) : v; } function fromObject(input) { var v = { r: 0, g: 0, b: 0, a: 255 }; if (Array.isArray(input)) { if (input.length >= 3) { v = { r: input[0], g: input[1], b: input[2], a: 255 }; if (input.length > 3) { v.a = n2b(input[3]); } } } else { v = clone$2(input, { r: 0, g: 0, b: 0, a: 1 }); v.a = n2b(v.a); } return v; } function functionParse(str) { if (str.charAt(0) === 'r') { return rgbParse(str); } return hueParse(str); } var Color = /*#__PURE__*/function () { function Color(input) { _classCallCheck(this, Color); if (input instanceof Color) { return input; } var type = _typeof(input); var v; if (type === 'object') { v = fromObject(input); } else if (type === 'string') { v = hexParse(input) || nameParse(input) || functionParse(input); } this._rgb = v; this._valid = !!v; } _createClass(Color, [{ key: "valid", get: function get() { return this._valid; } }, { key: "rgb", get: function get() { var v = clone$2(this._rgb); if (v) { v.a = b2n(v.a); } return v; }, set: function set(obj) { this._rgb = fromObject(obj); } }, { key: "rgbString", value: function rgbString() { return this._valid ? _rgbString(this._rgb) : this._rgb; } }, { key: "hexString", value: function hexString() { return this._valid ? _hexString(this._rgb) : this._rgb; } }, { key: "hslString", value: function hslString() { return this._valid ? _hslString(this._rgb) : this._rgb; } }, { key: "mix", value: function mix(color, weight) { var me = this; if (color) { var c1 = me.rgb; var c2 = color.rgb; var w2; var p = weight === w2 ? 0.5 : weight; var w = 2 * p - 1; var a = c1.a - c2.a; var w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0; w2 = 1 - w1; c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5; c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5; c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5; c1.a = p * c1.a + (1 - p) * c2.a; me.rgb = c1; } return me; } }, { key: "clone", value: function clone() { return new Color(this.rgb); } }, { key: "alpha", value: function alpha(a) { this._rgb.a = n2b(a); return this; } }, { key: "clearer", value: function clearer(ratio) { var rgb = this._rgb; rgb.a *= 1 - ratio; return this; } }, { key: "greyscale", value: function greyscale() { var rgb = this._rgb; var val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11); rgb.r = rgb.g = rgb.b = val; return this; } }, { key: "opaquer", value: function opaquer(ratio) { var rgb = this._rgb; rgb.a *= 1 + ratio; return this; } }, { key: "negate", value: function negate() { var v = this._rgb; v.r = 255 - v.r; v.g = 255 - v.g; v.b = 255 - v.b; return this; } }, { key: "lighten", value: function lighten(ratio) { modHSL(this._rgb, 2, ratio); return this; } }, { key: "darken", value: function darken(ratio) { modHSL(this._rgb, 2, -ratio); return this; } }, { key: "saturate", value: function saturate(ratio) { modHSL(this._rgb, 1, ratio); return this; } }, { key: "desaturate", value: function desaturate(ratio) { modHSL(this._rgb, 1, -ratio); return this; } }, { key: "rotate", value: function rotate(deg) { _rotate(this._rgb, deg); return this; } }]); return Color; }(); function index_esm(input) { return new Color(input); } var isPatternOrGradient = function isPatternOrGradient(value) { return value instanceof CanvasGradient || value instanceof CanvasPattern; }; function color(value) { return isPatternOrGradient(value) ? value : index_esm(value); } function getHoverColor(value) { return isPatternOrGradient(value) ? value : index_esm(value).saturate(0.5).darken(0.1).hexString(); } var overrides = Object.create(null); var descriptors = Object.create(null); function getScope$1(node, key) { if (!key) { return node; } var keys = key.split('.'); for (var i = 0, n = keys.length; i < n; ++i) { var k = keys[i]; node = node[k] || (node[k] = Object.create(null)); } return node; } function _set(root, scope, values) { if (typeof scope === 'string') { return merge(getScope$1(root, scope), values); } return merge(getScope$1(root, ''), scope); } var Defaults = /*#__PURE__*/function () { function Defaults(_descriptors) { _classCallCheck(this, Defaults); this.animation = undefined; this.backgroundColor = 'rgba(0,0,0,0.1)'; this.borderColor = 'rgba(0,0,0,0.1)'; this.color = '#666'; this.datasets = {}; this.devicePixelRatio = function (context) { return context.chart.platform.getDevicePixelRatio(); }; this.elements = {}; this.events = ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove']; this.font = { family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", size: 12, style: 'normal', lineHeight: 1.2, weight: null }; this.hover = {}; this.hoverBackgroundColor = function (ctx, options) { return getHoverColor(options.backgroundColor); }; this.hoverBorderColor = function (ctx, options) { return getHoverColor(options.borderColor); }; this.hoverColor = function (ctx, options) { return getHoverColor(options.color); }; this.indexAxis = 'x'; this.interaction = { mode: 'nearest', intersect: true }; this.maintainAspectRatio = true; this.onHover = null; this.onClick = null; this.parsing = true; this.plugins = {}; this.responsive = true; this.scale = undefined; this.scales = {}; this.showLine = true; this.drawActiveElementsOnTop = true; this.describe(_descriptors); } _createClass(Defaults, [{ key: "set", value: function set(scope, values) { return _set(this, scope, values); } }, { key: "get", value: function get(scope) { return getScope$1(this, scope); } }, { key: "describe", value: function describe(scope, values) { return _set(descriptors, scope, values); } }, { key: "override", value: function override(scope, values) { return _set(overrides, scope, values); } }, { key: "route", value: function route(scope, name, targetScope, targetName) { var _Object$definePropert; var scopeObject = getScope$1(this, scope); var targetScopeObject = getScope$1(this, targetScope); var privateName = '_' + name; Object.defineProperties(scopeObject, (_Object$definePropert = {}, _defineProperty(_Object$definePropert, privateName, { value: scopeObject[name], writable: true }), _defineProperty(_Object$definePropert, name, { enumerable: true, get: function get() { var local = this[privateName]; var target = targetScopeObject[targetName]; if (isObject(local)) { return Object.assign({}, target, local); } return valueOrDefault(local, target); }, set: function set(value) { this[privateName] = value; } }), _Object$definePropert)); } }]); return Defaults; }(); var defaults$1 = new Defaults({ _scriptable: function _scriptable(name) { return !name.startsWith('on'); }, _indexable: function _indexable(name) { return name !== 'events'; }, hover: { _fallback: 'interaction' }, interaction: { _scriptable: false, _indexable: false } }); function toFontString(font) { if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { return null; } return (font.style ? font.style + ' ' : '') + (font.weight ? font.weight + ' ' : '') + font.size + 'px ' + font.family; } function _measureText(ctx, data, gc, longest, string) { var textWidth = data[string]; if (!textWidth) { textWidth = data[string] = ctx.measureText(string).width; gc.push(string); } if (textWidth > longest) { longest = textWidth; } return longest; } function _longestText(ctx, font, arrayOfThings, cache) { cache = cache || {}; var data = cache.data = cache.data || {}; var gc = cache.garbageCollect = cache.garbageCollect || []; if (cache.font !== font) { data = cache.data = {}; gc = cache.garbageCollect = []; cache.font = font; } ctx.save(); ctx.font = font; var longest = 0; var ilen = arrayOfThings.length; var i, j, jlen, thing, nestedThing; for (i = 0; i < ilen; i++) { thing = arrayOfThings[i]; if (thing !== undefined && thing !== null && isArray$1(thing) !== true) { longest = _measureText(ctx, data, gc, longest, thing); } else if (isArray$1(thing)) { for (j = 0, jlen = thing.length; j < jlen; j++) { nestedThing = thing[j]; if (nestedThing !== undefined && nestedThing !== null && !isArray$1(nestedThing)) { longest = _measureText(ctx, data, gc, longest, nestedThing); } } } } ctx.restore(); var gcLen = gc.length / 2; if (gcLen > arrayOfThings.length) { for (i = 0; i < gcLen; i++) { delete data[gc[i]]; } gc.splice(0, gcLen); } return longest; } function _alignPixel(chart, pixel, width) { var devicePixelRatio = chart.currentDevicePixelRatio; var halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; } function clearCanvas(canvas, ctx) { ctx = ctx || canvas.getContext('2d'); ctx.save(); ctx.resetTransform(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.restore(); } function drawPoint(ctx, options, x, y) { var type, xOffset, yOffset, size, cornerRadius; var style = options.pointStyle; var rotation = options.rotation; var radius = options.radius; var rad = (rotation || 0) * RAD_PER_DEG; if (style && _typeof(style) === 'object') { type = style.toString(); if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { ctx.save(); ctx.translate(x, y); ctx.rotate(rad); ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); ctx.restore(); return; } } if (isNaN(radius) || radius <= 0) { return; } ctx.beginPath(); switch (style) { default: ctx.arc(x, y, radius, 0, TAU); ctx.closePath(); break; case 'triangle': ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); rad += TWO_THIRDS_PI; ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); rad += TWO_THIRDS_PI; ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); ctx.closePath(); break; case 'rectRounded': cornerRadius = radius * 0.516; size = radius - cornerRadius; xOffset = Math.cos(rad + QUARTER_PI) * size; yOffset = Math.sin(rad + QUARTER_PI) * size; ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad); ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI); ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); ctx.closePath(); break; case 'rect': if (!rotation) { size = Math.SQRT1_2 * radius; ctx.rect(x - size, y - size, 2 * size, 2 * size); break; } rad += QUARTER_PI; case 'rectRot': xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x - xOffset, y - yOffset); ctx.lineTo(x + yOffset, y - xOffset); ctx.lineTo(x + xOffset, y + yOffset); ctx.lineTo(x - yOffset, y + xOffset); ctx.closePath(); break; case 'crossRot': rad += QUARTER_PI; case 'cross': xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x - xOffset, y - yOffset); ctx.lineTo(x + xOffset, y + yOffset); ctx.moveTo(x + yOffset, y - xOffset); ctx.lineTo(x - yOffset, y + xOffset); break; case 'star': xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x - xOffset, y - yOffset); ctx.lineTo(x + xOffset, y + yOffset); ctx.moveTo(x + yOffset, y - xOffset); ctx.lineTo(x - yOffset, y + xOffset); rad += QUARTER_PI; xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x - xOffset, y - yOffset); ctx.lineTo(x + xOffset, y + yOffset); ctx.moveTo(x + yOffset, y - xOffset); ctx.lineTo(x - yOffset, y + xOffset); break; case 'line': xOffset = Math.cos(rad) * radius; yOffset = Math.sin(rad) * radius; ctx.moveTo(x - xOffset, y - yOffset); ctx.lineTo(x + xOffset, y + yOffset); break; case 'dash': ctx.moveTo(x, y); ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius); break; } ctx.fill(); if (options.borderWidth > 0) { ctx.stroke(); } } function _isPointInArea(point, area, margin) { margin = margin || 0.5; return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin; } function clipArea(ctx, area) { ctx.save(); ctx.beginPath(); ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); ctx.clip(); } function unclipArea(ctx) { ctx.restore(); } function _steppedLineTo(ctx, previous, target, flip, mode) { if (!previous) { return ctx.lineTo(target.x, target.y); } if (mode === 'middle') { var midpoint = (previous.x + target.x) / 2.0; ctx.lineTo(midpoint, previous.y); ctx.lineTo(midpoint, target.y); } else if (mode === 'after'