/*! * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license * * billboard.js, JavaScript chart library * https://naver.github.io/billboard.js/ * * @version 3.10.3 */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("d3-axis"), require("d3-brush"), require("d3-drag"), require("d3-dsv"), require("d3-ease"), require("d3-hierarchy"), require("d3-interpolate"), require("d3-scale"), require("d3-selection"), require("d3-shape"), require("d3-time-format"), require("d3-transition"), require("d3-zoom")); else if(typeof define === 'function' && define.amd) define(["d3-axis", "d3-brush", "d3-drag", "d3-dsv", "d3-ease", "d3-hierarchy", "d3-interpolate", "d3-scale", "d3-selection", "d3-shape", "d3-time-format", "d3-transition", "d3-zoom"], factory); else { var a = typeof exports === 'object' ? factory(require("d3-axis"), require("d3-brush"), require("d3-drag"), require("d3-dsv"), require("d3-ease"), require("d3-hierarchy"), require("d3-interpolate"), require("d3-scale"), require("d3-selection"), require("d3-shape"), require("d3-time-format"), require("d3-transition"), require("d3-zoom")) : factory(root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"]); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } })(this, function(__WEBPACK_EXTERNAL_MODULE__10__, __WEBPACK_EXTERNAL_MODULE__3__, __WEBPACK_EXTERNAL_MODULE__7__, __WEBPACK_EXTERNAL_MODULE__5__, __WEBPACK_EXTERNAL_MODULE__11__, __WEBPACK_EXTERNAL_MODULE__13__, __WEBPACK_EXTERNAL_MODULE__12__, __WEBPACK_EXTERNAL_MODULE__6__, __WEBPACK_EXTERNAL_MODULE__2__, __WEBPACK_EXTERNAL_MODULE__9__, __WEBPACK_EXTERNAL_MODULE__4__, __WEBPACK_EXTERNAL_MODULE__8__, __WEBPACK_EXTERNAL_MODULE__14__) { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ /* 0 */, /* 1 */, /* 2 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__2__; /***/ }), /* 3 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__3__; /***/ }), /* 4 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__4__; /***/ }), /* 5 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__5__; /***/ }), /* 6 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__6__; /***/ }), /* 7 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__7__; /***/ }), /* 8 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__8__; /***/ }), /* 9 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__9__; /***/ }), /* 10 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__10__; /***/ }), /* 11 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__11__; /***/ }), /* 12 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__12__; /***/ }), /* 13 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__13__; /***/ }), /* 14 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__14__; /***/ }) /******/ ]); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ !function() { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = function(exports, definition) { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ !function() { /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } /******/ }(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ !function() { /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ }(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other entry modules. !function() { // extracted by mini-css-extract-plugin }(); // This entry need to be wrapped in an IIFE because it need to be isolated against other entry modules. !function() { // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { bb: function() { return /* reexport */ bb; }, "default": function() { return /* reexport */ bb; } }); // NAMESPACE OBJECT: ./src/config/resolver/shape.ts var resolver_shape_namespaceObject = {}; __webpack_require__.r(resolver_shape_namespaceObject); __webpack_require__.d(resolver_shape_namespaceObject, { area: function() { return _area; }, areaLineRange: function() { return areaLineRange; }, areaSpline: function() { return areaSpline; }, areaSplineRange: function() { return areaSplineRange; }, areaStep: function() { return areaStep; }, bar: function() { return resolver_shape_bar; }, bubble: function() { return resolver_shape_bubble; }, candlestick: function() { return resolver_shape_candlestick; }, donut: function() { return shape_donut; }, gauge: function() { return resolver_shape_gauge; }, line: function() { return resolver_shape_line; }, pie: function() { return shape_pie; }, polar: function() { return resolver_shape_polar; }, radar: function() { return resolver_shape_radar; }, scatter: function() { return shape_scatter; }, spline: function() { return shape_spline; }, step: function() { return step; }, treemap: function() { return resolver_shape_treemap; } }); // NAMESPACE OBJECT: ./src/config/resolver/interaction.ts var resolver_interaction_namespaceObject = {}; __webpack_require__.r(resolver_interaction_namespaceObject); __webpack_require__.d(resolver_interaction_namespaceObject, { selection: function() { return _selectionModule; }, subchart: function() { return subchartModule; }, zoom: function() { return zoomModule; } }); ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/newArrowCheck.js function _newArrowCheck(innerThis, boundThis) { if (innerThis !== boundThis) { throw new TypeError("Cannot instantiate an arrow function"); } } // EXTERNAL MODULE: external {"commonjs":"d3-time-format","commonjs2":"d3-time-format","amd":"d3-time-format","root":"d3"} var external_commonjs_d3_time_format_commonjs2_d3_time_format_amd_d3_time_format_root_d3_ = __webpack_require__(4); // EXTERNAL MODULE: external {"commonjs":"d3-selection","commonjs2":"d3-selection","amd":"d3-selection","root":"d3"} var external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_ = __webpack_require__(2); ;// CONCATENATED MODULE: ./src/module/browser.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Window object * @private */ /* eslint-disable no-new-func, no-undef */ /** * Get global object * @returns {object} window object * @private */ function getGlobal() { return typeof globalThis === "object" && globalThis !== null && globalThis.Object === Object && globalThis || typeof global === "object" && global !== null && global.Object === Object && global || typeof self === "object" && self !== null && self.Object === Object && self || Function("return this")(); } /** * Get fallback object * @param {object} w global object * @returns {Array} fallback object array * @private */ function getFallback(w) { var _this = this; const hasRAF = typeof (w == null ? void 0 : w.requestAnimationFrame) === "function" && typeof (w == null ? void 0 : w.cancelAnimationFrame) === "function", hasRIC = typeof (w == null ? void 0 : w.requestIdleCallback) === "function" && typeof (w == null ? void 0 : w.cancelIdleCallback) === "function", request = function (cb) { _newArrowCheck(this, _this); return setTimeout(cb, 1); }.bind(this), cancel = function (id) { _newArrowCheck(this, _this); return clearTimeout(id); }.bind(this); return [hasRAF ? w.requestAnimationFrame : request, hasRAF ? w.cancelAnimationFrame : cancel, hasRIC ? w.requestIdleCallback : request, hasRIC ? w.cancelIdleCallback : cancel]; } const win = getGlobal(), browser_doc = win == null ? void 0 : win.document, _getFallback = getFallback(win), requestAnimationFrame = _getFallback[0], cancelAnimationFrame = _getFallback[1], requestIdleCallback = _getFallback[2], cancelIdleCallback = _getFallback[3]; ;// CONCATENATED MODULE: ./src/config/const.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Chart type constant * @private */ const TYPE = { AREA: "area", AREA_LINE_RANGE: "area-line-range", AREA_SPLINE: "area-spline", AREA_SPLINE_RANGE: "area-spline-range", AREA_STEP: "area-step", BAR: "bar", BUBBLE: "bubble", CANDLESTICK: "candlestick", DONUT: "donut", GAUGE: "gauge", LINE: "line", PIE: "pie", POLAR: "polar", RADAR: "radar", SCATTER: "scatter", SPLINE: "spline", STEP: "step", TREEMAP: "treemap" }; /** * Chart type module and its method from ChartInternal class, needed to be initialized. * @private */ const TYPE_METHOD_NEEDED = { AREA: "initArea", AREA_LINE_RANGE: "initArea", AREA_SPLINE: "initArea", AREA_SPLINE_RANGE: "initArea", AREA_STEP: "initArea", BAR: "initBar", BUBBLE: "initCircle", CANDLESTICK: "initCandlestick", DONUT: "initArc", GAUGE: "initArc", LINE: "initLine", PIE: "initArc", POLAR: "initPolar", RADAR: "initCircle", SCATTER: "initCircle", SPLINE: "initLine", STEP: "initLine", TREEMAP: "initTreemap" }; /** * chart types by category * @private */ const TYPE_BY_CATEGORY = { Area: [TYPE.AREA, TYPE.AREA_SPLINE, TYPE.AREA_SPLINE_RANGE, TYPE.AREA_LINE_RANGE, TYPE.AREA_STEP], AreaRange: [TYPE.AREA_SPLINE_RANGE, TYPE.AREA_LINE_RANGE], Arc: [TYPE.PIE, TYPE.DONUT, TYPE.GAUGE, TYPE.POLAR, TYPE.RADAR], Line: [TYPE.LINE, TYPE.SPLINE, TYPE.AREA, TYPE.AREA_SPLINE, TYPE.AREA_SPLINE_RANGE, TYPE.AREA_LINE_RANGE, TYPE.STEP, TYPE.AREA_STEP], Step: [TYPE.STEP, TYPE.AREA_STEP], Spline: [TYPE.SPLINE, TYPE.AREA_SPLINE, TYPE.AREA_SPLINE_RANGE] }; ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPrimitive.js function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPropertyKey.js function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // EXTERNAL MODULE: external {"commonjs":"d3-brush","commonjs2":"d3-brush","amd":"d3-brush","root":"d3"} var external_commonjs_d3_brush_commonjs2_d3_brush_amd_d3_brush_root_d3_ = __webpack_require__(3); ;// CONCATENATED MODULE: ./src/module/util.ts var _this = undefined; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1, t; r < arguments.length; r++) { t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license * @ignore */ const isValue = function (v) { _newArrowCheck(this, _this); return v || v === 0; }.bind(undefined), isFunction = function (v) { _newArrowCheck(this, _this); return typeof v === "function"; }.bind(undefined), isString = function (v) { _newArrowCheck(this, _this); return typeof v === "string"; }.bind(undefined), isNumber = function (v) { _newArrowCheck(this, _this); return typeof v === "number"; }.bind(undefined), isUndefined = function (v) { _newArrowCheck(this, _this); return typeof v === "undefined"; }.bind(undefined), isDefined = function (v) { _newArrowCheck(this, _this); return typeof v !== "undefined"; }.bind(undefined), isboolean = function (v) { _newArrowCheck(this, _this); return typeof v === "boolean"; }.bind(undefined), ceil10 = function (v) { _newArrowCheck(this, _this); return Math.ceil(v / 10) * 10; }.bind(undefined), asHalfPixel = function (n) { _newArrowCheck(this, _this); return Math.ceil(n) + .5; }.bind(undefined), diffDomain = function (d) { _newArrowCheck(this, _this); return d[1] - d[0]; }.bind(undefined), isObjectType = function (v) { _newArrowCheck(this, _this); return typeof v === "object"; }.bind(undefined), isEmpty = function (o) { _newArrowCheck(this, _this); return isUndefined(o) || o === null || isString(o) && o.length === 0 || isObjectType(o) && !(o instanceof Date) && Object.keys(o).length === 0 || isNumber(o) && isNaN(o); }.bind(undefined), notEmpty = function (o) { _newArrowCheck(this, _this); return !isEmpty(o); }.bind(undefined), isArray = function (arr) { _newArrowCheck(this, _this); return Array.isArray(arr); }.bind(undefined), isObject = function (obj) { _newArrowCheck(this, _this); return obj && !(obj != null && obj.nodeType) && isObjectType(obj) && !isArray(obj); }.bind(undefined); /** * Check if is array * @param {Array} arr Data to be checked * @returns {boolean} * @private */ /** * Check if is object * @param {object} obj Data to be checked * @returns {boolean} * @private */ /** * Get specified key value from object * If default value is given, will return if given key value not found * @param {object} options Source object * @param {string} key Key value * @param {*} defaultValue Default value * @returns {*} * @private */ function getOption(options, key, defaultValue) { return isDefined(options[key]) ? options[key] : defaultValue; } /** * Check if value exist in the given object * @param {object} dict Target object to be checked * @param {*} value Value to be checked * @returns {boolean} * @private */ function hasValue(dict, value) { var _this2 = this; let found = !1; Object.keys(dict).forEach(function (key) { _newArrowCheck(this, _this2); return dict[key] === value && (found = !0); }.bind(this)); return found; } /** * Call function with arguments * @param {Function} fn Function to be called * @param {*} thisArg "this" value for fn * @param {*} args Arguments for fn * @returns {boolean} true: fn is function, false: fn is not function * @private */ function callFn(fn, thisArg) { const isFn = isFunction(fn); for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } isFn && fn.call.apply(fn, [thisArg].concat(args)); return isFn; } /** * Call function after all transitions ends * @param {d3.transition} transition Transition * @param {Fucntion} cb Callback function * @private */ function endall(transition, cb) { var _this3 = this; let n = 0; const end = function () { for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } --n || cb.apply.apply(cb, [this].concat(args)); }; // if is transition selection if ("duration" in transition) { transition.each(function () { _newArrowCheck(this, _this3); return ++n; }.bind(this)).on("end", end); } else { ++n; transition.call(end); } } /** * Replace tag sign to html entity * @param {string} str Target string value * @returns {string} * @private */ function sanitize(str) { return isString(str) ? str.replace(/<(script|img)?/ig, "<").replace(/(script)?>/ig, ">") : str; } /** * Set text value. If there's multiline add nodes. * @param {d3Selection} node Text node * @param {string} text Text value string * @param {Array} dy dy value for multilined text * @param {boolean} toMiddle To be alingned vertically middle * @private */ function setTextValue(node, text, dy, toMiddle) { var _this4 = this; if (dy === void 0) { dy = [-1, 1]; } if (toMiddle === void 0) { toMiddle = !1; } if (!node || !isString(text)) { return; } if (text.indexOf("\n") === -1) { node.text(text); } else { const diff = [node.text(), text].map(function (v) { _newArrowCheck(this, _this4); return v.replace(/[\s\n]/g, ""); }.bind(this)); if (diff[0] !== diff[1]) { const multiline = text.split("\n"), len = toMiddle ? multiline.length - 1 : 1; // reset possible text node.html(""); multiline.forEach(function (v, i) { _newArrowCheck(this, _this4); node.append("tspan").attr("x", 0).attr("dy", (i === 0 ? dy[0] * len : dy[1]) + "em").text(v); }.bind(this)); } } } /** * Substitution of SVGPathSeg API polyfill * @param {SVGGraphicsElement} path Target svg element * @returns {Array} * @private */ function getRectSegList(path) { /* * seg1 ---------- seg2 * | | * | | * | | * seg0 ---------- seg3 * */ const _path$getBBox = path.getBBox(), x = _path$getBBox.x, y = _path$getBBox.y, width = _path$getBBox.width, height = _path$getBBox.height; return [{ x: x, y: y + height }, // seg0 { x: x, y: y }, // seg1 { x: x + width, y: y }, // seg2 { x: x + width, y: y + height } // seg3 ]; } /** * Get svg bounding path box dimension * @param {SVGGraphicsElement} path Target svg element * @returns {object} * @private */ function getPathBox(path) { const _path$getBoundingClie = path.getBoundingClientRect(), width = _path$getBoundingClie.width, height = _path$getBoundingClie.height, items = getRectSegList(path), x = items[0].x, y = Math.min(items[0].y, items[1].y); return { x: x, y: y, width: width, height: height }; } /** * Get event's current position coordinates * @param {object} event Event object * @param {SVGElement|HTMLElement} element Target element * @returns {Array} [x, y] Coordinates x, y array * @private */ function getPointer(event, element) { var _ref, _this5 = this; const touches = event && ((_ref = event.touches || event.sourceEvent && event.sourceEvent.touches) == null ? void 0 : _ref[0]); let pointer = [0, 0]; try { pointer = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.pointer)(touches || event, element); } catch (e) {} return pointer.map(function (v) { _newArrowCheck(this, _this5); return isNaN(v) ? 0 : v; }.bind(this)); } /** * Return brush selection array * @param {object} ctx Current instance * @returns {d3.brushSelection} * @private */ function getBrushSelection(ctx) { const event = ctx.event, $el = ctx.$el, main = $el.subchart.main || $el.main; let selection; // check from event if (event && event.type === "brush") { selection = event.selection; // check from brush area selection } else if (main && (selection = main.select(".bb-brush").node())) { selection = (0,external_commonjs_d3_brush_commonjs2_d3_brush_amd_d3_brush_root_d3_.brushSelection)(selection); } return selection; } /** * Get boundingClientRect. * Cache the evaluated value once it was called. * @param {HTMLElement} node Target element * @returns {object} * @private */ function getBoundingRect(node) { const needEvaluate = !("rect" in node) || "rect" in node && node.hasAttribute("width") && node.rect.width !== +node.getAttribute("width"); return needEvaluate ? node.rect = node.getBoundingClientRect() : node.rect; } /** * Retrun random number * @param {boolean} asStr Convert returned value as string * @param {number} min Minimum value * @param {number} max Maximum value * @returns {number|string} * @private */ function getRandom(asStr, min, max) { if (asStr === void 0) { asStr = !0; } if (min === void 0) { min = 0; } if (max === void 0) { max = 1e4; } const crpt = win.crypto || win.msCrypto, rand = crpt ? min + crpt.getRandomValues(new Uint32Array(1))[0] % (max - min + 1) : Math.floor(Math.random() * (max - min) + min); return asStr ? rand + "" : rand; } /** * Find index based on binary search * @param {Array} arr Data array * @param {number} v Target number to find * @param {number} start Start index of data array * @param {number} end End index of data arr * @param {boolean} isRotated Weather is roted axis * @returns {number} Index number * @private */ function findIndex(arr, v, start, end, isRotated) { if (start > end) { return -1; } const mid = Math.floor((start + end) / 2); let _arr$mid = arr[mid], x = _arr$mid.x, _arr$mid$w = _arr$mid.w, w = _arr$mid$w === void 0 ? 0 : _arr$mid$w; if (isRotated) { x = arr[mid].y; w = arr[mid].h; } if (v >= x && v <= x + w) { return mid; } return v < x ? findIndex(arr, v, start, mid - 1, isRotated) : findIndex(arr, v, mid + 1, end, isRotated); } /** * Check if brush is empty * @param {object} ctx Bursh context * @returns {boolean} * @private */ function brushEmpty(ctx) { const selection = getBrushSelection(ctx); if (selection) { // brush selected area // two-dimensional: [[x0, y0], [x1, y1]] // one-dimensional: [x0, x1] or [y0, y1] return selection[0] === selection[1]; } return !0; } /** * Deep copy object * @param {object} objectN Source object * @returns {object} Cloned object * @private */ function deepClone() { var _this6 = this; const _clone = function clone(v) { _newArrowCheck(this, _this6); if (isObject(v) && v.constructor) { const r = new v.constructor(); for (const k in v) { r[k] = _clone(v[k]); } return r; } return v; }.bind(this); for (var _len3 = arguments.length, objectN = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { objectN[_key3] = arguments[_key3]; } return objectN.map(function (v) { _newArrowCheck(this, _this6); return _clone(v); }.bind(this)).reduce(function (a, c) { _newArrowCheck(this, _this6); return _objectSpread(_objectSpread({}, a), c); }.bind(this)); } /** * Extend target from source object * @param {object} target Target object * @param {object|Array} source Source object * @returns {object} * @private */ function extend(target, source) { var _this7 = this; if (target === void 0) { target = {}; } if (isArray(source)) { source.forEach(function (v) { _newArrowCheck(this, _this7); return extend(target, v); }.bind(this)); } // exclude name with only numbers for (const p in source) { if (/^\d+$/.test(p) || p in target) { continue; } target[p] = source[p]; } return target; } /** * Return first letter capitalized * @param {string} str Target string * @returns {string} capitalized string * @private */ const capitalize = function (str) { _newArrowCheck(this, _this); return str.charAt(0).toUpperCase() + str.slice(1); }.bind(undefined); /** * Camelize from kebob style string * @param {string} str Target string * @param {string} separator Separator string * @returns {string} camelized string * @private */ function camelize(str, separator) { var _this8 = this; if (separator === void 0) { separator = "-"; } return str.split(separator).map(function (v, i) { _newArrowCheck(this, _this8); return i ? v.charAt(0).toUpperCase() + v.slice(1).toLowerCase() : v.toLowerCase(); }.bind(this)).join(""); } /** * Convert to array * @param {object} v Target to be converted * @returns {Array} * @private */ const toArray = function (v) { _newArrowCheck(this, _this); return [].slice.call(v); }.bind(undefined); /** * Add CSS rules * @param {object} style Style object * @param {string} selector Selector string * @param {Array} prop Prps arrary * @returns {number} Newely added rule index * @private */ function addCssRules(style, selector, prop) { var _this9 = this; const rootSelctor = style.rootSelctor, sheet = style.sheet, getSelector = function (s) { _newArrowCheck(this, _this9); return s.replace(/\s?(bb-)/g, ".$1").replace(/\.+/g, "."); }.bind(this), rule = rootSelctor + " " + getSelector(selector) + " {" + prop.join(";") + "}"; return sheet[sheet.insertRule ? "insertRule" : "addRule"](rule, sheet.cssRules.length); } /** * Get css rules for specified stylesheets * @param {Array} styleSheets The stylesheets to get the rules from * @returns {Array} * @private */ function getCssRules(styleSheets) { var _this10 = this; let rules = []; styleSheets.forEach(function (sheet) { _newArrowCheck(this, _this10); try { if (sheet.cssRules && sheet.cssRules.length) { rules = rules.concat(toArray(sheet.cssRules)); } } catch (e) { var _window$console; (_window$console = win.console) == null || _window$console.warn("Error while reading rules from " + sheet.href + ": " + e.toString()); } }.bind(this)); return rules; } /** * Gets the SVGMatrix of an SVGGElement * @param {SVGElement} node Node element * @returns {SVGMatrix} matrix * @private */ function getTranslation(node) { const transform = node ? node.transform : null, baseVal = transform && transform.baseVal; return baseVal && baseVal.numberOfItems ? baseVal.getItem(0).matrix : { a: 0, b: 0, c: 0, d: 0, e: 0, f: 0 }; } /** * Get unique value from array * @param {Array} data Source data * @returns {Array} Unique array value * @private */ function getUnique(data) { var _this11 = this; const isDate = data[0] instanceof Date, d = (isDate ? data.map(Number) : data).filter(function (v, i, self) { _newArrowCheck(this, _this11); return self.indexOf(v) === i; }.bind(this)); return isDate ? d.map(function (v) { _newArrowCheck(this, _this11); return new Date(v); }.bind(this)) : d; } /** * Merge array * @param {Array} arr Source array * @returns {Array} * @private */ function mergeArray(arr) { var _this12 = this; return arr && arr.length ? arr.reduce(function (p, c) { _newArrowCheck(this, _this12); return p.concat(c); }.bind(this)) : []; } /** * Merge object returning new object * @param {object} target Target object * @param {object} objectN Source object * @returns {object} merged target object * @private */ function mergeObj(target) { for (var _this13 = this, _len4 = arguments.length, objectN = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { objectN[_key4 - 1] = arguments[_key4]; } if (!objectN.length || objectN.length === 1 && !objectN[0]) { return target; } const source = objectN.shift(); if (isObject(target) && isObject(source)) { Object.keys(source).forEach(function (key) { _newArrowCheck(this, _this13); const value = source[key]; if (isObject(value)) { target[key] || (target[key] = {}); target[key] = mergeObj(target[key], value); } else { target[key] = isArray(value) ? value.concat() : value; } }.bind(this)); } return mergeObj.apply(void 0, [target].concat(objectN)); } /** * Sort value * @param {Array} data value to be sorted * @param {boolean} isAsc true: asc, false: desc * @returns {number|string|Date} sorted date * @private */ function sortValue(data, isAsc) { var _this14 = this; if (isAsc === void 0) { isAsc = !0; } let fn; if (data[0] instanceof Date) { fn = isAsc ? function (a, b) { _newArrowCheck(this, _this14); return a - b; }.bind(this) : function (a, b) { _newArrowCheck(this, _this14); return b - a; }.bind(this); } else { if (isAsc && !data.every(isNaN)) { fn = function (a, b) { _newArrowCheck(this, _this14); return a - b; }.bind(this); } else if (!isAsc) { fn = function (a, b) { _newArrowCheck(this, _this14); return a > b && -1 || a < b && 1 || a === b && 0; }.bind(this); } } return data.concat().sort(fn); } /** * Get min/max value * @param {string} type 'min' or 'max' * @param {Array} data Array data value * @returns {number|Date|undefined} * @private */ function getMinMax(type, data) { var _this15 = this; let res = data.filter(function (v) { _newArrowCheck(this, _this15); return notEmpty(v); }.bind(this)); if (res.length) { if (isNumber(res[0])) { res = Math[type].apply(Math, res); } else if (res[0] instanceof Date) { res = sortValue(res, type === "min")[0]; } } else { res = undefined; } return res; } /** * Get range * @param {number} start Start number * @param {number} end End number * @param {number} step Step number * @returns {Array} * @private */ const getRange = function (start, end, step) { if (step === void 0) { step = 1; } _newArrowCheck(this, _this); const res = [], n = Math.max(0, Math.ceil((end - start) / step)) | 0; for (let i = start; i < n; i++) { res.push(start + i * step); } return res; }.bind(undefined), emulateEvent = { mouse: function () { var _this16 = this; _newArrowCheck(this, _this); const getParams = function () { _newArrowCheck(this, _this16); return { bubbles: !1, cancelable: !1, screenX: 0, screenY: 0, clientX: 0, clientY: 0 }; }.bind(this); try { // eslint-disable-next-line no-new new MouseEvent("t"); return function (el, eventType, params) { if (params === void 0) { params = getParams(); } _newArrowCheck(this, _this16); el.dispatchEvent(new MouseEvent(eventType, params)); }.bind(this); } catch (e) { // Polyfills DOM4 MouseEvent return function (el, eventType, params) { if (params === void 0) { params = getParams(); } _newArrowCheck(this, _this16); const mouseEvent = browser_doc.createEvent("MouseEvent"); // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent mouseEvent.initMouseEvent(eventType, params.bubbles, params.cancelable, win, 0, // the event's mouse click count params.screenX, params.screenY, params.clientX, params.clientY, !1, !1, !1, !1, 0, null); el.dispatchEvent(mouseEvent); }.bind(this); } }.bind(undefined)(), touch: function touch(el, eventType, params) { _newArrowCheck(this, _this); const touchObj = new Touch(mergeObj({ identifier: Date.now(), target: el, radiusX: 2.5, radiusY: 2.5, rotationAngle: 10, force: .5 }, params)); el.dispatchEvent(new TouchEvent(eventType, { cancelable: !0, bubbles: !0, shiftKey: !0, touches: [touchObj], targetTouches: [], changedTouches: [touchObj] })); }.bind(undefined) }; // emulate event /** * Process the template & return bound string * @param {string} tpl Template string * @param {object} data Data value to be replaced * @returns {string} * @private */ function tplProcess(tpl, data) { let res = tpl; for (const x in data) { res = res.replace(new RegExp("{=" + x + "}", "g"), data[x]); } return res; } /** * Get parsed date value * (It must be called in 'ChartInternal' context) * @param {Date|string|number} date Value of date to be parsed * @returns {Date} * @private */ function parseDate(date) { let parsedDate; if (date instanceof Date) { parsedDate = date; } else if (isString(date)) { var _format$dataTime; const config = this.config, format = this.format; // if fails to parse, try by new Date() // https://github.com/naver/billboard.js/issues/1714 parsedDate = (_format$dataTime = format.dataTime(config.data_xFormat)(date)) != null ? _format$dataTime : new Date(date); } else if (isNumber(date) && !isNaN(date)) { parsedDate = new Date(+date); } if (!parsedDate || isNaN(+parsedDate)) { console && console.error && console.error("Failed to parse x '" + date + "' to Date object"); } return parsedDate; } /** * Return if the current doc is visible or not * @returns {boolean} * @private */ function isTabVisible() { return (browser_doc == null ? void 0 : browser_doc.hidden) === !1 || (browser_doc == null ? void 0 : browser_doc.visibilityState) === "visible"; } /** * Get the current input type * @param {boolean} mouse Config value: interaction.inputType.mouse * @param {boolean} touch Config value: interaction.inputType.touch * @returns {string} "mouse" | "touch" | null * @private */ function convertInputType(mouse, touch) { var _this17 = this; const DocumentTouch = win.DocumentTouch, matchMedia = win.matchMedia, navigator = win.navigator; let hasTouch = !1; if (touch) { // Some Edge desktop return true: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/20417074/ if (navigator && "maxTouchPoints" in navigator) { hasTouch = navigator.maxTouchPoints > 0; // Ref: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js // On IE11 with IE9 emulation mode, ('ontouchstart' in window) is returning true } else if ("ontouchmove" in win || DocumentTouch && browser_doc instanceof DocumentTouch) { hasTouch = !0; } else { // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#avoiding_user_agent_detection if (matchMedia != null && matchMedia("(pointer:coarse)").matches) { hasTouch = !0; } else { // Only as a last resort, fall back to user agent sniffing const UA = navigator.userAgent; hasTouch = /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) || /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA); } } } // Check if agent has mouse using any-hover, touch devices (e.g iPad) with external mouse will return true as long as mouse is connected // https://css-tricks.com/interaction-media-features-and-their-potential-for-incorrect-assumptions/#aa-testing-the-capabilities-of-all-inputs // Demo: https://patrickhlauke.github.io/touch/pointer-hover-any-pointer-any-hover/ const hasMouse = mouse && ["any-hover:hover", "any-pointer:fine"].some(function (v) { _newArrowCheck(this, _this17); return matchMedia == null ? void 0 : matchMedia("(" + v + ")").matches; }.bind(this)); // fallback to 'mouse' if no input type is detected. return hasMouse && "mouse" || hasTouch && "touch" || "mouse"; } /** * Run function until given condition function return true * @param {Function} fn Function to be executed when condition is true * @param {Function} conditionFn Condition function to check if condition is true * @private */ function runUntil(fn, conditionFn) { var _this18 = this; if (conditionFn() === !1) { requestAnimationFrame(function () { _newArrowCheck(this, _this18); return runUntil(fn, conditionFn); }.bind(this)); } else { fn(); } } ;// CONCATENATED MODULE: ./src/module/error.ts /** * Copyright (c) 2021 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* eslint no-console: "off" */ /** * Check chart type module imports. * @param {ChartInternal} ctx Context * @private */ function checkModuleImport(ctx) { const $$ = ctx, config = $$.config; let type = ""; if (isEmpty(config.data_type || config.data_types) && !$$[TYPE_METHOD_NEEDED.LINE]) { type = "line"; } else { for (const x in TYPE_METHOD_NEEDED) { const t = TYPE[x]; if ($$.hasType(t) && !$$[TYPE_METHOD_NEEDED[x]]) { type = t; break; } } } type && logError("Please, make sure if %c" + camelize(type), "module has been imported and specified correctly."); } /** * Log error and throw error * @param {string} head Message header * @param {string} tail Message tail * @private */ function logError(head, tail) { var _window$console; const hasConsole = (_window$console = win.console) == null ? void 0 : _window$console.error; if (hasConsole) { console.error("\u274C [billboard.js] " + head, "background:red;color:white;display:block;font-size:15px", tail); console.info("%cℹ️", "font-size:15px", "https://github.com/naver/billboard.js/wiki/CHANGELOG-v2#modularization-by-its-functionality"); } throw Error("[billboard.js] " + head.replace(/\%c([a-z-]+)/i, "'$1' ") + " " + tail); } ;// CONCATENATED MODULE: ./src/config/classes.ts function classes_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function classes_objectSpread(e) { for (var r = 1, t; r < arguments.length; r++) { t = null != arguments[r] ? arguments[r] : {}; r % 2 ? classes_ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : classes_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * CSS class names definition * @private */ const $COMMON = { button: "bb-button", chart: "bb-chart", empty: "bb-empty", main: "bb-main", target: "bb-target", EXPANDED: "_expanded_" }; const $ARC = { arc: "bb-arc", arcLabelLine: "bb-arc-label-line", arcs: "bb-arcs", chartArc: "bb-chart-arc", chartArcs: "bb-chart-arcs", chartArcsBackground: "bb-chart-arcs-background", chartArcsTitle: "bb-chart-arcs-title", needle: "bb-needle" }; const $AREA = { area: "bb-area", areas: "bb-areas" }; const $AXIS = { axis: "bb-axis", axisX: "bb-axis-x", axisXLabel: "bb-axis-x-label", axisY: "bb-axis-y", axisY2: "bb-axis-y2", axisY2Label: "bb-axis-y2-label", axisYLabel: "bb-axis-y-label" }; const $BAR = { bar: "bb-bar", bars: "bb-bars", chartBar: "bb-chart-bar", chartBars: "bb-chart-bars" }; const $CANDLESTICK = { candlestick: "bb-candlestick", candlesticks: "bb-candlesticks", chartCandlestick: "bb-chart-candlestick", chartCandlesticks: "bb-chart-candlesticks", valueDown: "bb-value-down", valueUp: "bb-value-up" }; const $CIRCLE = { chartCircles: "bb-chart-circles", circle: "bb-circle", circles: "bb-circles" }; const $COLOR = { colorPattern: "bb-color-pattern", colorScale: "bb-colorscale" }; const $DRAG = { dragarea: "bb-dragarea", INCLUDED: "_included_" }; const $GAUGE = { chartArcsGaugeMax: "bb-chart-arcs-gauge-max", chartArcsGaugeMin: "bb-chart-arcs-gauge-min", chartArcsGaugeUnit: "bb-chart-arcs-gauge-unit", chartArcsGaugeTitle: "bb-chart-arcs-gauge-title", gaugeValue: "bb-gauge-value" }; const $LEGEND = { legend: "bb-legend", legendBackground: "bb-legend-background", legendItem: "bb-legend-item", legendItemEvent: "bb-legend-item-event", legendItemHidden: "bb-legend-item-hidden", legendItemPoint: "bb-legend-item-point", legendItemTile: "bb-legend-item-tile" }; const $LINE = { chartLine: "bb-chart-line", chartLines: "bb-chart-lines", line: "bb-line", lines: "bb-lines" }; const $EVENT = { eventRect: "bb-event-rect", eventRects: "bb-event-rects", eventRectsMultiple: "bb-event-rects-multiple", eventRectsSingle: "bb-event-rects-single" }; const $FOCUS = { focused: "bb-focused", defocused: "bb-defocused", legendItemFocused: "bb-legend-item-focused", xgridFocus: "bb-xgrid-focus", ygridFocus: "bb-ygrid-focus" }; const $GRID = { grid: "bb-grid", gridLines: "bb-grid-lines", xgrid: "bb-xgrid", xgridLine: "bb-xgrid-line", xgridLines: "bb-xgrid-lines", xgrids: "bb-xgrids", ygrid: "bb-ygrid", ygridLine: "bb-ygrid-line", ygridLines: "bb-ygrid-lines", ygrids: "bb-ygrids" }; const $LEVEL = { level: "bb-level", levels: "bb-levels" }; const $RADAR = { chartRadar: "bb-chart-radar", chartRadars: "bb-chart-radars" }; const $REGION = { region: "bb-region", regions: "bb-regions" }; const $SELECT = { selectedCircle: "bb-selected-circle", selectedCircles: "bb-selected-circles", SELECTED: "_selected_" }; const $SHAPE = { shape: "bb-shape", shapes: "bb-shapes" }; const $SUBCHART = { brush: "bb-brush", subchart: "bb-subchart" }; const $TEXT = { chartText: "bb-chart-text", chartTexts: "bb-chart-texts", text: "bb-text", texts: "bb-texts", title: "bb-title", TextOverlapping: "text-overlapping" }; const $TOOLTIP = { tooltip: "bb-tooltip", tooltipContainer: "bb-tooltip-container", tooltipName: "bb-tooltip-name" }; const $TREEMAP = { treemap: "bb-treemap", chartTreemap: "bb-chart-treemap", chartTreemaps: "bb-chart-treemaps" }; const $ZOOM = { buttonZoomReset: "bb-zoom-reset", zoomBrush: "bb-zoom-brush" }; /* harmony default export */ var classes = (classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread(classes_objectSpread({}, $COMMON), $ARC), $AREA), $AXIS), $BAR), $CANDLESTICK), $CIRCLE), $COLOR), $DRAG), $GAUGE), $LEGEND), $LINE), $EVENT), $FOCUS), $GRID), $RADAR), $REGION), $SELECT), $SHAPE), $SUBCHART), $TEXT), $TOOLTIP), $TREEMAP), $ZOOM)); ;// CONCATENATED MODULE: ./src/config/Store/Element.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Elements class. * @class Elements * @ignore * @private */ let Element = function () { return { chart: null, main: null, svg: null, axis: { // axes x: null, y: null, y2: null, subX: null }, defs: null, tooltip: null, legend: null, title: null, subchart: { main: null, // $$.context bar: null, // $$.contextBar line: null, // $$.contextLine area: null // $$.contextArea }, arcs: null, bar: null, // mainBar, candlestick: null, line: null, // mainLine, area: null, // mainArea, circle: null, // mainCircle, radar: null, text: null, // mainText, grid: { main: null, // grid (also focus) x: null, // xgrid, y: null // ygrid, }, gridLines: { main: null, // gridLines x: null, // xgridLines, y: null // ygridLines }, region: { main: null, // region list: null // mainRegion }, eventRect: null, zoomResetBtn: null // drag zoom reset button }; }; ;// CONCATENATED MODULE: ./src/config/Store/State.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * State class. * @class State * @ignore * @private */ let State = function () { return { // chart drawn area dimension, excluding axes width: 0, width2: 0, height: 0, height2: 0, margin: { top: 0, bottom: 0, left: 0, right: 0 }, margin2: { top: 0, bottom: 0, left: 0, right: 0 }, margin3: { top: 0, bottom: 0, left: 0, right: 0 }, arcWidth: 0, arcHeight: 0, xAxisHeight: 0, hasAxis: !1, hasRadar: !1, hasTreemap: !1, // for data CSS rule index (used when boost.useCssRule is true) cssRule: {}, current: { // current domain value. Assigned when is zoom is called domain: undefined, // chart whole dimension width: 0, height: 0, dataMax: 0, maxTickSize: { x: { width: 0, height: 0, ticks: [], clipPath: 0, domain: "" }, y: { width: 0, height: 0, domain: "" }, y2: { width: 0, height: 0, domain: "" } }, // current used chart type list types: [], needle: undefined // arc needle current value }, // legend isLegendRight: !1, isLegendInset: !1, isLegendTop: !1, isLegendLeft: !1, legendStep: 0, legendItemWidth: 0, legendItemHeight: 0, legendHasRendered: !1, eventReceiver: { currentIdx: -1, // current event interaction index rect: {}, // event rect's clientBoundingRect data: [], // event data bound of previoous eventRect coords: [] // coordination value of previous eventRect }, axis: { x: { padding: { left: 0, right: 0 }, tickCount: 0 } }, rotatedPadding: { left: 30, right: 0, top: 5 }, withoutFadeIn: {}, inputType: "", datetimeId: "", // clip id string clip: { id: "", idXAxis: "", idYAxis: "", idXAxisTickTexts: "", idGrid: "", idSubchart: "", // clipIdForSubchart path: "", pathXAxis: "", pathYAxis: "", pathXAxisTickTexts: "", pathGrid: "" }, // state event: null, // event object dragStart: null, dragging: !1, flowing: !1, cancelClick: !1, mouseover: !1, rendered: !1, transiting: !1, redrawing: !1, // if redraw() is on process resizing: !1, // resize event called toggling: !1, // legend toggle zooming: !1, hasNegativeValue: !1, hasPositiveValue: !0, orgAreaOpacity: "0.2", orgConfig: {}, // user original genration config // ID strings hiddenTargetIds: [], hiddenLegendIds: [], focusedTargetIds: [], defocusedTargetIds: [], // value for Arc radius: 0, innerRadius: 0, outerRadius: undefined, innerRadiusRatio: 0, gaugeArcWidth: 0, radiusExpanded: 0, // xgrid attribute xgridAttr: { x1: null, x2: null, y1: null, y2: null } }; }; ;// CONCATENATED MODULE: ./src/config/Store/Store.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ // mapping const Store_classes = { element: Element, state: State }; /** * Internal store class. * @class Store * @ignore * @private */ let Store = /*#__PURE__*/function () { function Store() { var _this = this; Object.keys(Store_classes).forEach(function (v) { _newArrowCheck(this, _this); this[v] = new Store_classes[v](); }.bind(this)); } var _proto = Store.prototype; _proto.getStore = function getStore(name) { return this[name]; }; return Store; }(); ;// CONCATENATED MODULE: ./src/config/Options/common/main.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * main config options */ /* harmony default export */ var main = ({ /** * Specify the CSS selector or the element which the chart will be set to. D3 selection object can be specified also.
* If other chart is set already, it will be replaced with the new one (only one chart can be set in one element). * - **NOTE:** In case of element doesn't exist or not specified, will add a `
` element to the body. * @name bindto * @memberof Options * @property {string|HTMLElement|d3.selection|object} [bindto="#chart"] Specify the element where chart will be drawn. * @property {string|HTMLElement|d3.selection} bindto.element="#chart" Specify the element where chart will be drawn. * @property {string} [bindto.classname=bb] Specify the class name of bind element.
* **NOTE:** When class name isn't `bb`, then you also need to update the default CSS to be rendered correctly. * @default #chart * @example * bindto: "#myContainer" * * // or HTMLElement * bindto: document.getElementById("myContainer") * * // or D3 selection object * bindto: d3.select("#myContainer") * * // or to change default classname * bindto: { * element: "#chart", * classname: "bill-board" // ex)
* } */ bindto: "#chart", /** * Set chart background. * @name background * @memberof Options * @property {object} background background object * @property {string} background.class Specify the class name for background element. * @property {string} background.color Specify the fill color for background element.
**NOTE:** Will be ignored if `imgUrl` option is set. * @property {string} background.imgUrl Specify the image url string for background. * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.Background) * @example * background: { * class: "myClass", * color: "red", * * // Set image url for background. * // If specified, 'color' option will be ignored. * imgUrl: "https://naver.github.io/billboard.js/img/logo/billboard.js.svg", * } */ background: {}, /** * Set 'clip-path' attribute for chart element * - **NOTE:** * > When is false, chart node element is positioned after the axis node in DOM tree hierarchy. * > Is to make chart element positioned over axis element. * @name clipPath * @memberof Options * @type {boolean} * @default true * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.clipPath) * @example * // don't set 'clip-path' attribute * clipPath: false */ clipPath: !0, /** * Set svg element's class name * @name svg * @memberof Options * @type {object} * @property {object} [svg] svg object * @property {string} [svg.classname] class name for svg element * @example * svg: { * classname: "test_class" * } */ svg_classname: undefined, /** * The desired size of the chart element. * If value is not specified, the width of the chart will be calculated by the size of the parent element it's appended to. * @name size * @memberof Options * @type {object} * @property {object} [size] size object * @property {number} [size.width] width of the chart element * @property {number} [size.height] height of the chart element * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.ChartSize) * @example * size: { * width: 640, * height: 480 * } */ size_width: undefined, size_height: undefined, /** * The padding of the chart element. * - **NOTE:** for more information, see the "[`Understanding padding`](https://github.com/naver/billboard.js/wiki/Understanding-padding)"" wiki documentaion. * @name padding * @memberof Options * @type {object} * @property {object|boolean} [padding=true] Set padding of chart, and accepts object or boolean type. * - `Object`: Specify each side's padding. * - `false`: Remove padding completely and make shape to fully occupy the container element. * - In this case, axes and subchart will be hidden. * - To adjust some padding from this state, use `axis.[x|y].padding` option. * @property {string} [padding.mode] padding mode * - `"fit"`: Reduce padding as much as possible to make chart fit to the container element for chart types w/axis.
When specified, all padding values will be relative from fitted value. * @property {number} [padding.top] padding on the top of chart * @property {number} [padding.right] padding on the right of chart * @property {number} [padding.bottom] padding on the bottom of chart * @property {number} [padding.left] padding on the left of chart * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.Padding) * @see [Demo: Fit padding](https://naver.github.io/billboard.js/demo/#ChartOptions.FitPadding) * @example * // remove padding completely. * padding: false, * * padding: { * // specifying mode value, will reduce padding and make fit to the container element. * mode: "fit" * * // when mode is "fit", all padding values will be relative from fitted value. * // so, 0 will be initial fitted value. * top: 20, * right: 20, * bottom: 20, * left: 20 * } * * // or specify padding value for each side * padding: { * top: 20, * right: 20, * bottom: 20, * left: 20 * } */ padding: !0, padding_mode: undefined, padding_left: undefined, padding_right: undefined, padding_top: undefined, padding_bottom: undefined, /** * Set chart resize options * @name resize * @memberof Options * @type {object} * @property {object} [resize] resize object * @property {boolean} [resize.auto=true] Set chart resize automatically on viewport changes. * @property {boolean|number} [resize.timer=true] Set resize timer option. * - **NOTE:** * - The resize function will be called using: * - true: `setTimeout()` * - false: `requestIdleCallback()` * - Given number(delay in ms) value, resize function will be triggered using `setTimer()` with given delay. * @example * resize: { * auto: false, * * // set resize function will be triggered using `setTimer()` * timer: true, * * // set resize function will be triggered using `requestIdleCallback()` * timer: false, * * // set resize function will be triggered using `setTimer()` with a delay of `100ms`. * timer: 100 * } */ resize_auto: !0, resize_timer: !0, /** * Set a callback to execute when the chart is clicked. * @name onclick * @memberof Options * @type {Function} * @default undefined * @example * onclick: function(event) { * this; // chart instance itself * event; // native event object * ... * } */ onclick: undefined, /** * Set a callback to execute when mouse/touch enters the chart. * @name onover * @memberof Options * @type {Function} * @default undefined * @example * onover: function(event) { * this; // chart instance itself * event; // native event object * ... * } */ onover: undefined, /** * Set a callback to execute when mouse/touch leaves the chart. * @name onout * @memberof Options * @type {Function} * @default undefined * @example * onout: function(event) { * this; // chart instance itself * event; // native event object * ... * } */ onout: undefined, /** * Set a callback to execute when user resizes the screen. * @name onresize * @memberof Options * @type {Function} * @default undefined * @example * onresize: function() { * this; // chart instance itself * ... * } */ onresize: undefined, /** * Set a callback to execute when screen resize finished. * @name onresized * @memberof Options * @type {Function} * @default undefined * @example * onresized: function() { * this; // chart instance itself * ... * } */ onresized: undefined, /** * Set a callback to execute before the chart is initialized * @name onbeforeinit * @memberof Options * @type {Function} * @default undefined * @example * onbeforeinit: function() { * this; // chart instance itself * ... * } */ onbeforeinit: undefined, /** * Set a callback to execute when the chart is initialized. * @name oninit * @memberof Options * @type {Function} * @default undefined * @example * oninit: function() { * this; // chart instance itself * ... * } */ oninit: undefined, /** * Set a callback to execute after the chart is initialized * @name onafterinit * @memberof Options * @type {Function} * @default undefined * @example * onafterinit: function() { * this; // chart instance itself * ... * } */ onafterinit: undefined, /** * Set a callback which is executed when the chart is rendered. Basically, this callback will be called in each time when the chart is redrawed. * @name onrendered * @memberof Options * @type {Function} * @default undefined * @example * onrendered: function() { * this; // chart instance itself * ... * } */ onrendered: undefined, /** * Set duration of transition (in milliseconds) for chart animation.

* - **NOTE:** If `0 `or `null` set, transition will be skipped. So, this makes initial rendering faster especially in case you have a lot of data. * @name transition * @memberof Options * @type {object} * @property {object} [transition] transition object * @property {number} [transition.duration=350] duration in milliseconds * @example * transition: { * duration: 500 * } */ transition_duration: 250, /** * Set plugins * @name plugins * @memberof Options * @type {Array} * @example * plugins: [ * new bb.plugin.stanford({ ... }), * new PluginA(), * ... * ] */ plugins: [], /** * Control the render timing * @name render * @memberof Options * @type {object} * @property {object} [render] render object * @property {boolean} [render.lazy=true] Make to not render at initialization (enabled by default when bind element's visibility is hidden). * @property {boolean} [render.observe=true] Observe bind element's visibility(`display` or `visibility` inline css property or class value) & render when is visible automatically (for IEs, only works IE11+). When set to **false**, call [`.flush()`](./Chart.html#flush) to render. * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.LazyRender) * @example * render: { * lazy: true, * observe: true * } * * @example * // * // (a)
* // (b) * * // render.lazy enabled by default when element is hidden * var chart = bb.generate({ ... }); * * // chart will be rendered automatically when element's visibility changes * // Note: works only for inlined css property or class attribute changes * document.getElementById('chart').classList.remove('hide') // (a) * document.getElementById('chart').style.display = 'block'; // (b) * * @example * // chart won't be rendered and not observing bind element's visibility changes * var chart = bb.generate({ * render: { * lazy: true, * observe: false * } * }); * * // call at any point when you want to render * chart.flush(); */ render: {}, /** * Show rectangles inside the chart.

* This option accepts array including object that has axis, start, end and class. * The keys start, end and class are optional. * axis must be x, y or y2. start and end should be the value where regions start and end. * If not specified, the edge values will be used. * If timeseries x axis, date string, Date object and unixtime integer can be used. * If class is set, the region element will have it as class. * @name regions * @memberof Options * @type {Array} * @default [] * @see [Demo](https://naver.github.io/billboard.js/demo/#Region.RegionLabel) * @example * regions: [ * { * axis: "x", * start: 1, * end: 4, * class: "region-1-4", * label: { * text: "Region Text", * x: 5, // position relative of the initial x coordinate * y: 5, // position relative of the initial y coordinate * color: "red", // color string * rotated: true // make text to show in vertical or horizontal * } * } * ] */ regions: [] }); ;// CONCATENATED MODULE: ./src/config/Options/common/boost.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * boost config options */ /* harmony default export */ var boost = ({ /** * Set boost options * @name boost * @memberof Options * @type {object} * @property {object} boost boost object * @property {boolean} [boost.useCssRule=false] Avoid setting inline styles for each shape elements. * - **NOTE:** * - Will append <style> to the head tag and will add shpes' CSS rules dynamically. * - For now, covers colors related properties (fill, stroke, etc.) only. * @property {boolean} [boost.useWorker=false] Use Web Worker as possible for processing. * - **NOTE:** * - For now, only applies for data conversion at the initial time. * - As of Web Worker's async nature, handling chart instance synchrously is not recommended. * @example * boost: { * useCssRule: true, * useWorker: false * } */ boost_useCssRule: !1, boost_useWorker: !1 }); ;// CONCATENATED MODULE: ./src/config/Options/data/data.ts var data_this = undefined; /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * data config options */ /* harmony default export */ var data = ({ /** * Specify the key of x values in the data.

* We can show the data with non-index x values by this option. This option is required when the type of x axis is timeseries. If this option is set on category axis, the values of the data on the key will be used for category names. * @name data․x * @memberof Options * @type {string} * @default undefined * @example * data: { * x: "date" * } */ data_x: undefined, /** * Converts data id value * @name data․idConverter * @memberof Options * @type {Function} * @default function(id) { return id; } * @example * data: { * idConverter: function(id) { * // when id is 'data1', converts to be 'data2' * // 'data2' should be given as the initial data value * if (id === "data1") { * return "data2"; * } else { * return id; * } * } * } */ data_idConverter: function data_idConverter(id) { _newArrowCheck(this, data_this); return id; }.bind(undefined), /** * Set custom data name. * If a name is set to `null`, the series is omitted from the legend. * @name data․names * @memberof Options * @type {object} * @default {} * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataName) * @example * data: { * names: { * data1: "Data Name 1", * data2: "Data Name 2" * } * } */ data_names: {}, /** * Set custom data class.

* If this option is specified, the element g for the data has an additional class that has the prefix 'bb-target-' (eg. bb-target-additional-data1-class). * @name data․classes * @memberof Options * @type {object} * @default {} * @example * data: { * classes: { * data1: "additional-data1-class", * data2: "additional-data2-class" * } * } */ data_classes: {}, /** * Set chart type at once.

* If this option is specified, the type will be applied to every data. This setting can be overwritten by data.types.

* **Available Values:** * - area * - area-line-range * - area-spline * - area-spline-range * - area-step * - bar * - bubble * - candlestick * - donut * - gauge * - line * - pie * - polar * - radar * - scatter * - spline * - step * - treemap * @name data․type * @memberof Options * @type {string} * @default "line"
NOTE: When importing shapes by ESM, `line()` should be specified for type. * @example * data: { * type: "bar" * } * @example * // Generate chart by importing ESM * // Import types to be used only, where this will make smaller bundle size. * import bb, { * area, * areaLineRange, * areaSpline, * areaSplineRange, * areaStep, * bar, * bubble, * candlestick, * donut, * gauge, * line, * pie, * polar, * radar, * scatter, * spline, * step, * treemap * } * * bb.generate({ * ..., * data: { * type: bar() * } * }); */ data_type: undefined, /** * Set chart type for each data.
* This setting overwrites data.type setting. * - **NOTE:** `radar` and `treemap` type can't be combined with other types. * @name data․types * @memberof Options * @type {object} * @default {} * @example * data: { * types: { * data1: "bar", * data2: "spline" * } * } * @example * // Generate chart by importing ESM * // Import types to be used only, where this will make smaller bundle size. * import bb, { * area, * areaLineRange, * areaSpline, * areaSplineRange, * areaStep, * bar, * bubble, * candlestick, * donut, * gauge, * line, * pie, * polar, * radar, * scatter, * spline, * step, * treemap * } * * bb.generate({ * ..., * data: { * types: { * data1: bar(), * data1: spline() * } * } * }); */ data_types: {}, /** * This option changes the order of stacking data and pieces of pie/donut. * - If `null` specified, it will be the order the data loaded. * - If function specified, it will be used as [Array.sort compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters)

* * **Available Values:** * - `desc`: In descending order * - `asc`: In ascending order * - `null`: It keeps the data load order * - `function(data1, data2) { ... }`: Array.sort compareFunction * * **NOTE**: order function, only works for Axis based types & Arc types, except `Radar` type. * @name data․order * @memberof Options * @type {string|Function|null} * @default desc * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataOrder) * @example * data: { * // in descending order (default) * order: "desc" * * // in ascending order * order: "asc" * * // keeps data input order * order: null * * // specifying sort function * order: function(a, b) { * // param data passed format * // { * // id: "data1", id_org: "data1", values: [ * // {x: 5, value: 250, id: "data1", index: 5, name: "data1"}, * // ... * // ] * // } * * const reducer = (p, c) => p + Math.abs(c.value); * const aSum = a.values.reduce(reducer, 0); * const bSum = b.values.reduce(reducer, 0); * * // ascending order * return aSum - bSum; * * // descending order * // return bSum - aSum; * } * } */ data_order: "desc", /** * Set groups for the data for stacking. * @name data․groups * @memberof Options * @type {Array} * @default [] * @example * data: { * groups: [ * ["data1", "data2"], * ["data3"] * ] * } */ data_groups: [], /** * Set how zero value will be treated on groups.
* Possible values: * - `zero`: 0 will be positioned at absolute axis zero point. * - `positive`: 0 will be positioned at the top of a stack. * - `negative`: 0 will be positioned at the bottom of a stack. * @name data․groupsZeroAs * @memberof Options * @type {string} * @default "positive" * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.Groups) * @example * data: { * groupsZeroAs: "zero" // "positive" or "negative" * } */ data_groupsZeroAs: "positive", /** * Set color converter function.

* This option should a function and the specified function receives color (e.g. '#ff0000') and d that has data parameters like id, value, index, etc. And it must return a string that represents color (e.g. '#00ff00'). * @name data․color * @memberof Options * @type {Function} * @default undefined * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataColor) * @example * data: { * color: function(color, d) { ... } * } */ data_color: undefined, /** * Set color for each data. * @name data․colors * @memberof Options * @type {object} * @default {} * @example * data: { * colors: { * data1: "#ff0000", * data2: function(d) { * return "#000"; * } * ... * } * } */ data_colors: {}, /** * Set labels options * @name data․labels * @memberof Options * @type {object} * @property {object} data Data object * @property {boolean} [data.labels=false] Show or hide labels on each data points * @property {boolean} [data.labels.centered=false] Centerize labels on `bar` shape. (**NOTE:** works only for 'bar' type) * @property {Function} [data.labels.format] Set formatter function for data labels.
* The formatter function receives 4 arguments such as `v, id, i, texts` and it **must return a string** (`\n` character will be used as line break) that will be shown as the label.

* The arguments are:
* - `v` is the value of the data point where the label is shown. * - `id` is the id of the data where the label is shown. * - `i` is the index of the data series point where the label is shown. * - `texts` is the array of whole corresponding data series' text labels.

* Formatter function can be defined for each data by specifying as an object and D3 formatter function can be set (ex. d3.format('$')) * @property {string|object} [data.labels.backgroundColors] Set label text background colors. * @property {string|object|Function} [data.labels.colors] Set label text colors. * @property {object|Function} [data.labels.position] Set each dataset position, relative the original.

* When function is specified, will receives 5 arguments such as `type, v, id, i, texts` and it must return a position number.

* The arguments are:
* - `type` coordinate type string, which will be 'x' or 'y'. * - `v` is the value of the data point where the label is shown. * - `id` is the id of the data where the label is shown. * - `i` is the index of the data series point where the label is shown. * - `texts` is the array of whole corresponding data series' text labels.

* @property {number} [data.labels.position.x=0] x coordinate position, relative the original. * @property {number} [data.labels.position.y=0] y coordinate position, relative the original. * @property {object} [data.labels.rotate] Rotate label text. Specify degree value in a range of `0 ~ 360`. * - **NOTE:** Depend on rotate value, text position need to be adjusted manually(using `data.labels.position` option) to be shown nicely. * @memberof Options * @type {object} * @default {} * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataLabel) * @see [Demo: label colors](https://naver.github.io/billboard.js/demo/#Data.DataLabelColors) * @see [Demo: label format](https://naver.github.io/billboard.js/demo/#Data.DataLabelFormat) * @see [Demo: label multiline](https://naver.github.io/billboard.js/demo/#Data.DataLabelMultiline) * @see [Demo: label overlap](https://naver.github.io/billboard.js/demo/#Data.DataLabelOverlap) * @see [Demo: label position](https://naver.github.io/billboard.js/demo/#Data.DataLabelPosition) * @see [Demo: label rotate](https://naver.github.io/billboard.js/demo/#Data.DataLabelRotate) * @example * data: { * labels: true, * * // or set specific options * labels: { * format: function(v, id, i, texts) { * ... * // to multiline, return with '\n' character * return "Line1\nLine2"; * }, * * // it's possible to set for each data * format: { * data1: function(v, id, i, texts) { ... }, * ... * }, * * // align text to center of the 'bar' shape (works only for 'bar' type) * centered: true, * * // apply backgound color for label texts * backgroundColors: "red", * * // set differenct backround colors per dataset * backgroundColors: { * data1: "green", * data2: "yellow" * } * * // apply for all label texts * colors: "red", * * // set different colors per dataset * // for not specified dataset, will have the default color value * colors: { * data1: "yellow", * data3: "green" * }, * * // call back for label text color * colors: function(color, d) { * // color: the default data label color string * // data: ex) {x: 0, value: 200, id: "data3", index: 0} * .... * return d.value > 200 ? "cyan" : color; * }, * * // return x, y coordinate position * // apt to handle each text position manually * position: function(type, v, id, i, texts) { * ... * return type == "x" ? 10 : 20; * }, * * // set x, y coordinate position * position: { * x: -10, * y: 10 * }, * * // or set x, y coordinate position by each dataset * position: { * data1: {x: 5, y: 5}, * data2: {x: 10, y: -20} * }, * * // rotate degree for label text * rotate: 90 * } * } */ data_labels: {}, data_labels_backgroundColors: undefined, data_labels_colors: undefined, data_labels_position: {}, /** * Hide each data when the chart appears.

* If true specified, all of data will be hidden. If multiple ids specified as an array, those will be hidden. * @name data․hide * @memberof Options * @type {boolean|Array} * @default false * @example * data: { * // all of data will be hidden * hide: true * * // specified data will be hidden * hide: ["data1", ...] * } */ data_hide: !1, /** * Filter values to be shown * The data value is the same as the returned by `.data()`. * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter * @name data․filter * @memberof Options * @type {Function} * @default undefined * @example * data: { * // filter for id value * filter: function(v) { * // v: [{id: "data1", id_org: "data1", values: [ * // {x: 0, value: 130, id: "data2", index: 0}, ...] * // }, ...] * return v.id !== "data1"; * } */ data_filter: undefined, /** * Set a callback for click event on each data point.

* This callback will be called when each data point clicked and will receive `d` and element as the arguments. * - `d` is the data clicked and element is the element clicked. * - `element` is the current interacting svg element. * - In this callback, `this` will be the Chart object. * @name data․onclick * @memberof Options * @type {Function} * @default function() {} * @example * data: { * onclick: function(d, element) { * // d - ex) {x: 4, value: 150, id: "data1", index: 4, name: "data1"} * // element - * ... * } * } */ data_onclick: function data_onclick() { _newArrowCheck(this, data_this); }.bind(undefined), /** * Set a callback for mouse/touch over event on each data point.

* This callback will be called when mouse cursor or via touch moves onto each data point and will receive `d` and `element` as the argument. * - `d` is the data where mouse cursor moves onto. * - `element` is the current interacting svg element. * - In this callback, `this` will be the Chart object. * @name data․onover * @memberof Options * @type {Function} * @default function() {} * @example * data: { * onover: function(d, element) { * // d - ex) {x: 4, value: 150, id: "data1", index: 4} * // element - * ... * } * } */ data_onover: function data_onover() { _newArrowCheck(this, data_this); }.bind(undefined), /** * Set a callback for mouse/touch out event on each data point.

* This callback will be called when mouse cursor or via touch moves out each data point and will receive `d` as the argument. * - `d` is the data where mouse cursor moves out. * - `element` is the current interacting svg element. * - In this callback, `this` will be the Chart object. * @name data․onout * @memberof Options * @type {Function} * @default function() {} * @example * data: { * onout: function(d, element) { * // d - ex) {x: 4, value: 150, id: "data1", index: 4} * // element - * ... * } * } */ data_onout: function data_onout() { _newArrowCheck(this, data_this); }.bind(undefined), /** * Set a callback for when data is shown.
* The callback will receive shown data ids in array. * @name data․onshown * @memberof Options * @type {Function} * @default undefined * @example * data: { * onshown: function(ids) { * // ids - ["data1", "data2", ...] * ... * } * } */ data_onshown: undefined, /** * Set a callback for when data is hidden.
* The callback will receive hidden data ids in array. * @name data․onhidden * @memberof Options * @type {Function} * @default undefined * @example * data: { * onhidden: function(ids) { * // ids - ["data1", "data2", ...] * ... * } * } */ data_onhidden: undefined, /** * Set a callback for minimum data * - **NOTE:** For 'area-line-range' and 'area-spline-range', `mid` data will be taken for the comparison * @name data․onmin * @memberof Options * @type {Function} * @default undefined * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.OnMinMaxCallback) * @example * onmin: function(data) { * // data - ex) [{x: 3, value: 400, id: "data1", index: 3}, ... ] * ... * } */ data_onmin: undefined, /** * Set a callback for maximum data * - **NOTE:** For 'area-line-range' and 'area-spline-range', `mid` data will be taken for the comparison * @name data․onmax * @memberof Options * @type {Function} * @default undefined * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.OnMinMaxCallback) * @example * onmax: function(data) { * // data - ex) [{x: 3, value: 400, id: "data1", index: 3}, ... ] * ... * } */ data_onmax: undefined, /** * Load a CSV or JSON file from a URL. NOTE that this will not work if loading via the "file://" protocol as the most browsers will block XMLHTTPRequests. * @name data․url * @memberof Options * @type {string} * @default undefined * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.LoadData) * @example * data: { * url: "/data/test.csv" * } */ data_url: undefined, /** * XHR header value * - **NOTE:** Should be used with `data.url` option * @name data․headers * @memberof Options * @type {string} * @default undefined * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader * @example * data: { * url: "/data/test.csv", * headers: { * "Content-Type": "text/xml", * ... * } * } */ data_headers: undefined, /** * Parse a JSON object for data. See also data.keys. * @name data․json * @memberof Options * @type {Array} * @default undefined * @see [data․keys](#.data%25E2%2580%25A4keys) * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.JSONData) * @example * data: { * json: [ * {name: "www.site1.com", upload: 200, download: 200, total: 400}, * {name: "www.site2.com", upload: 100, download: 300, total: 400}, * {name: "www.site3.com", upload: 300, download: 200, total: 500}, * {name: "www.site4.com", upload: 400, download: 100, total: 500} * ], * keys: { * // case 1: specify 'x' key for category axis * x: "name", // 'name' key will be used as category x axis values * value: ["upload", "download"] * * // case 2: without 'x' key for non-category axis * value: ["upload", "download"] * } * } */ data_json: undefined, /** * Load data from a multidimensional array, with the first element containing the data names, the following containing related data in that order. * @name data․rows * @memberof Options * @type {Array} * @default undefined * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.RowOrientedData) * @example * data: { * rows: [ * ["A", "B", "C"], * [90, 120, 300], * [40, 160, 240], * [50, 200, 290], * [120, 160, 230], * [80, 130, 300], * [90, 220, 320] * ] * } * * // for 'bar' type, data can contain: * // - an array of [start, end] data following the order * data: { * rows: [ * ["data1", "data2"], * [[100, 150], 120], * [[200, 300], 55], * [[-400, 500], 60] * ], * type: "bar" * } * * // for 'range' types('area-line-range' or 'area-spline-range'), data should contain: * // - an array of [high, mid, low] data following the order * // - or an object with 'high', 'mid' and 'low' key value * data: { * rows: [ * ["data1", "data2"], * [ * // or {high:150, mid: 140, low: 110}, 120 * [150, 140, 110], 120 * ], * [[155, 130, 115], 55], * [[160, 135, 120], 60] * ], * types: { * data1: "area-line-range", * data2: "line" * } * } * * // for 'bubble' type, data can contain dimension value: * // - an array of [y, z] data following the order * // - or an object with 'y' and 'z' key value * // 'y' is for y axis coordination and 'z' is the bubble radius value * data: { * rows: [ * ["data1", "data2"], * [ * // or {y:10, z: 140}, 120 * [10, 140], 120 * ], * [[100, 30], 55], * [[50, 100], 60] * ], * types: { * data1: "bubble", * data2: "line" * } * } * * // for 'canlestick' type, data should contain: * // - an array of [open, high, low, close, volume(optional)] data following the order * // - or an object with 'open', 'high', 'low', 'close' and 'value'(optional) key value * data: { * rows: [ * ["data1", "data2"], * [ * // open, high, low, close, volume (optional) * {open: 1300, high: 1369, low: 1200, close: 1339, volume: 100}, * [1000, 1100, 850, 870] * ], * [ * {open: 1348, high: 1371, low: 1271, close: 1320}, * [870, 1250, 830, 1200, 50] * ] * ], * type: "candlestick" * } */ data_rows: undefined, /** * Load data from a multidimensional array, with each element containing an array consisting of a datum name and associated data values. * @name data․columns * @memberof Options * @type {Array} * @default undefined * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.ColumnOrientedData) * @example * data: { * columns: [ * ["data1", 30, 20, 50, 40, 60, 50], * ["data2", 200, 130, 90, 240, 130, 220], * ["data3", 300, 200, 160, 400, 250, 250] * ] * } * * // for 'bar' type, data can contain: * // - an array of [start, end] data following the order * data: { * columns: [ * ["data1", -100, 50, [100, 200], [200, 300]], * ["data2", -200, 300, [-100, 100], [-50, -30]], * ], * type: "bar" * } * * // for 'range' types('area-line-range' or 'area-spline-range'), data should contain: * // - an array of [high, mid, low] data following the order * // - or an object with 'high', 'mid' and 'low' key value * data: { * columns: [ * ["data1", * [150, 140, 110], // or {high:150, mid: 140, low: 110} * [150, 140, 110], * [150, 140, 110] * ] * ], * type: "area-line-range" * } * * // for 'bubble' type, data can contain dimension value: * // - an array of [y, z] data following the order * // - or an object with 'y' and 'z' key value * // 'y' is for y axis coordination and 'z' is the bubble radius value * data: { * columns: [ * ["data1", * [10, 140], // or {y:10, z: 140} * [100, 30], * [50, 100] * ] * ], * type: "bubble" * } * * // for 'canlestick' type, data should contain: * // - an array of [open, high, low, close, volume(optional)] data following the order * // - or an object with 'open', 'high', 'low', 'close' and 'value'(optional) key value * data: { * columns: [ * ["data1", * [1000, 1100, 850, 870, 100], // or {open:1000, high: 1100, low: 870, volume: 100} * [870, 1250, 830, 1200] // 'volume' can be omitted * ] * ], * type: "candlestick" * } */ data_columns: undefined, /** * Used if loading JSON via data.url. * - **Available Values:** * - json * - csv * - tsv * @name data․mimeType * @memberof Options * @type {string} * @default csv * @example * data: { * mimeType: "json" * } */ data_mimeType: "csv", /** * Choose which JSON object keys correspond to desired data. * - **NOTE:** Only for JSON object given as array. * @name data․keys * @memberof Options * @type {string} * @default undefined * @example * data: { * json: [ * {name: "www.site1.com", upload: 200, download: 200, total: 400}, * {name: "www.site2.com", upload: 100, download: 300, total: 400}, * {name: "www.site3.com", upload: 300, download: 200, total: 500}, * {name: "www.site4.com", upload: 400, download: 100, total: 500} * ], * keys: { * // case 1: specify 'x' key for category axis * x: "name", // 'name' key will be used as category x axis values * value: ["upload", "download"] * * // case 2: without 'x' key for non-category axis * value: ["upload", "download"] * } * } */ data_keys: undefined, /** * Set text label to be displayed when there's no data to show. * - ex. Toggling all visible data to not be shown, unloading all current data, etc. * @name data․empty․label․text * @memberof Options * @type {string} * @default "" * @example * data: { * empty: { * label: { * text: "No Data" * } * } * } */ data_empty_label_text: "" }); ;// CONCATENATED MODULE: ./src/config/Options/common/color.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * color config options */ /* harmony default export */ var color = ({ /** * Set color of the data values * @name color * @memberof Options * @type {object} * @property {object} color color object * @property {string|object|Function} [color.onover] Set the color value for each data point when mouse/touch onover event occurs. * @property {Array|null} [color.pattern=[]] Set custom color pattern. Passing `null` will not set a color for these elements, which requires the usage of custom CSS-based theming to work. * @property {Function} [color.tiles] if defined, allows use svg's patterns to fill data area. It should return an array of [SVGPatternElement](https://developer.mozilla.org/en-US/docs/Web/API/SVGPatternElement). * - **NOTE:** The pattern element's id will be defined as `bb-colorize-pattern-$COLOR-VALUE`.
* ex. When color pattern value is `['red', '#fff']` and defined 2 patterns,then ids for pattern elements are:
* - `bb-colorize-pattern-red` * - `bb-colorize-pattern-fff` * @property {object} [color.threshold] color threshold for gauge and tooltip color * @property {string} [color.threshold.unit] If set to `value`, the threshold will be based on the data value. Otherwise it'll be based on equation of the `threshold.max` option value. * @property {Array} [color.threshold.values] Threshold values for each steps * @property {number} [color.threshold.max=100] The base value to determine threshold step value condition. When the given value is 15 and max 10, then the value for threshold is `15*100/10`. * @example * color: { * pattern: ["#1f77b4", "#aec7e8", ...], * * // Set colors' patterns * // it should return an array of SVGPatternElement * tiles: function() { * var pattern = document.createElementNS("http://www.w3.org/2000/svg", "pattern"); * var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); * var circle1 = document.createElementNS("http://www.w3.org/2000/svg", "circle"); * * pattern.setAttribute("patternUnits", "userSpaceOnUse"); * pattern.setAttribute("width", "32"); * pattern.setAttribute("height", "32"); * * g.style.fill = "#000"; * g.style.opacity = "0.2"; * * circle1.setAttribute("cx", "3"); * circle1.setAttribute("cy", "3"); * circle1.setAttribute("r", "3"); * * g.appendChild(circle1); * pattern.appendChild(g); * * return [pattern]; * }, * * // for threshold usage, pattern values should be set for each steps * pattern: ["grey", "green", "yellow", "orange", "red"], * threshold: { * unit: "value", * * // when value is 20 => 'green', value is 40 => 'orange' will be set. * values: [10, 20, 30, 40, 50], * * // the equation for max: * // - unit == 'value': max => 30 * // - unit != 'value': max => value*100/30 * max: 30 * }, * * // set all data to 'red' * onover: "red", * * // set different color for data * onover: { * data1: "red", * data2: "yellow" * }, * * // will pass data object to the callback * onover: function(d) { * return d.id === "data1" ? "red" : "green"; * } * } */ color_pattern: [], color_tiles: undefined, color_threshold: {}, color_onover: undefined }); ;// CONCATENATED MODULE: ./src/config/Options/interaction/interaction.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * interaction config options */ /* harmony default export */ var interaction = ({ /** * Interaction options * @name interaction * @memberof Options * @type {object} * @property {object} interaction Intersection object * @property {boolean} [interaction.enabled=true] Indicate if the chart should have interactions.
* If `false` is set, all of interactions (showing/hiding tooltip, selection, mouse events, etc) will be disabled. * @property {boolean} [interaction.brighten=true] Make brighter for the selected area (ex. 'pie' type data selected area) * @property {boolean} [interaction.inputType.mouse=true] enable or disable mouse interaction * @property {boolean} [interaction.inputType.touch=true] enable or disable touch interaction * @property {boolean|number} [interaction.inputType.touch.preventDefault=false] enable or disable to call event.preventDefault on touchstart & touchmove event. It's usually used to prevent document scrolling. * @see [Demo: touch.preventDefault](https://naver.github.io/billboard.js/demo/#Interaction.PreventScrollOnTouch) * @example * interaction: { * enabled: false, * brighten: false, * inputType: { * mouse: true, * touch: false * * // or declare preventDefault explicitly. * // In this case touch inputType is enabled by default * touch: { * preventDefault: true * * // or threshold pixel value (pixel moved from touchstart to touchmove) * preventDefault: 5 * } * } * } */ interaction_enabled: !0, interaction_brighten: !0, interaction_inputType_mouse: !0, interaction_inputType_touch: {} }); ;// CONCATENATED MODULE: ./src/config/Options/common/legend.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * legend config options */ /* harmony default export */ var legend = ({ /** * Legend options * @name legend * @memberof Options * @type {object} * @property {object} legend Legend object * @property {boolean} [legend.show=true] Show or hide legend. * @property {boolean} [legend.hide=false] Hide legend * If true given, all legend will be hidden. If string or array given, only the legend that has the id will be hidden. * @property {string|HTMLElement} [legend.contents.bindto=undefined] Set CSS selector or element reference to bind legend items. * - **NOTE:** Should be used along with `legend.contents.template`. * @property {string|Function} [legend.contents.template="{=TITLE}"] Set item's template.
* - If set `string` value, within template the 'color' and 'title' can be replaced using template-like syntax string: * - {=COLOR}: data color value * - {=TITLE}: data title value * - If set `function` value, will pass following arguments to the given function: * - title {string}: data's id value * - color {string}: color string * - data {Array}: data array * @property {string} [legend.position=bottom] Change the position of legend.
* Available values are: `bottom`, `right` and `inset` are supported. * @property {object} [legend.inset={anchor: 'top-left',x: 10,y: 0,step: undefined}] Change inset legend attributes.
* This option accepts object that has the keys `anchor`, `x`, `y` and `step`. * - **anchor** decides the position of the legend: * - top-left * - top-right * - bottom-left * - bottom-right * - **x** and **y**: * - set the position of the legend based on the anchor. * - **step**: * - defines the max step the legend has (e.g. If 2 set and legend has 3 legend item, the legend 2 columns). * @property {boolean} [legend.equally=false] Set to all items have same width size. * @property {number} [legend.padding=0] Set padding value * @property {boolean} [legend.item.interaction=true] Set legend item interaction. * - **NOTE:** * - This setting will not have effect on `.toggle()` method. * - `legend.item.onXXX` listener options will work if set, regardless of this option value. * @property {boolean} [legend.item.interaction.dblclick=false] Set legend item to interact on double click. * - **NOTE:** * - Double clicking will make focused clicked dataseries only, hiding all others. * - for single click case, `click + altKey(Win)/optionKey(Mac OS)` to have same effect. * - To return initial state(which all dataseries are showing), double click current focused legend item again. * - for single click case, `click + altKey(Win)/optionKey(Mac OS)` to have same effect. * - In this case, default `click` interaction will be disabled. * @property {Function} [legend.item.onclick=undefined] Set click event handler to the legend item. * - **NOTE:** * - When set, default `click` interaction will be disabled. * - When `interaction.dblclick=true` is set, will be called on double click. * @property {Function} [legend.item.onover=undefined] Set mouse/touch over event handler to the legend item. * - **NOTE:** When set, default `mouseover` interaction will be disabled. * @property {Function} [legend.item.onout=undefined] Set mouse/touch out event handler to the legend item. * - **NOTE:** When set, default `mouseout` interaction will be disabled. * @property {number} [legend.item.tile.width=10] Set width for 'rectangle' legend item tile element. * @property {number} [legend.item.tile.height=10] Set height for 'rectangle' legend item tile element. * @property {number} [legend.item.tile.r=5] Set the radius for 'circle' legend item tile type. * @property {string} [legend.item.tile.type="rectangle"] Set legend item shape type.
* - **Available Values:** * - circle * - rectangle * @property {boolean} [legend.usePoint=false] Whether to use custom points in legend. * @see [Demo: item.interaction](https://naver.github.io/billboard.js/demo/#Legend.LegendItemInteraction) * @see [Demo: item.tile.type](https://naver.github.io/billboard.js/demo/#Legend.LegendItemTileType) * @see [Demo: position](https://naver.github.io/billboard.js/demo/#Legend.LegendPosition) * @see [Demo: contents.template](https://naver.github.io/billboard.js/demo/#Legend.LegendTemplate1) * @see [Demo: usePoint](https://naver.github.io/billboard.js/demo/#Legend.usePoint) * @example * legend: { * show: true, * hide: true, * //or hide: "data1" * //or hide: ["data1", "data2"] * contents: { * bindto: "#legend", //
    * * // will be as:
  • data1
  • * template: "
  • {=TITLE}
  • " * * // or using function * template: function(id, color, data) { * // if you want omit some legend, return falsy value * if (id !== "data1") { * return "
  • {=TITLE}", legend_equally: !1, legend_hide: !1, legend_inset_anchor: "top-left", legend_inset_x: 10, legend_inset_y: 0, legend_inset_step: undefined, legend_item_interaction: !0, legend_item_dblclick: !1, legend_item_onclick: undefined, legend_item_onover: undefined, legend_item_onout: undefined, legend_item_tile_width: 10, legend_item_tile_height: 10, legend_item_tile_r: 5, legend_item_tile_type: "rectangle", legend_padding: 0, legend_position: "bottom", legend_show: !0, legend_usePoint: !1 }); ;// CONCATENATED MODULE: ./src/config/Options/common/title.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * title config options */ /* harmony default export */ var title = ({ /** * Set title options * @name title * @memberof Options * @type {object} * @property {object} title Title object * @property {string} [title.text] Title text. If contains `\n`, it's used as line break allowing multiline title. * @property {number} [title.padding.top=0] Top padding value. * @property {number} [title.padding.right=0] Right padding value. * @property {number} [title.padding.bottom=0] Bottom padding value. * @property {number} [title.padding.left=0] Left padding value. * @property {string} [title.position=center] Available values are: 'center', 'right' and 'left'. * @see [Demo](https://naver.github.io/billboard.js/demo/#Title.MultilinedTitle) * @example * title: { * text: "Title Text", * * // or Multiline title text * text: "Main title text\nSub title text", * * padding: { * top: 10, * right: 10, * bottom: 10, * left: 10 * }, * position: "center" * } */ title_text: undefined, title_padding: { top: 0, right: 0, bottom: 0, left: 0 }, title_position: "center" }); ;// CONCATENATED MODULE: ./src/config/Options/common/tooltip.ts var tooltip_this = undefined; /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * tooltip config options */ /* harmony default export */ var tooltip = ({ /** * Tooltip options * @name tooltip * @memberof Options * @type {object} * @property {object} tooltip Tooltip object * @property {boolean} [tooltip.show=true] Show or hide tooltip. * @property {boolean} [tooltip.doNotHide=false] Make tooltip keep showing not hiding on interaction. * @property {boolean} [tooltip.grouped=true] Set if tooltip is grouped or not for the data points. * - **NOTE:** The overlapped data points will be displayed as grouped even if set false. * @property {boolean} [tooltip.linked=false] Set if tooltips on all visible charts with like x points are shown together when one is shown. * @property {string} [tooltip.linked.name=""] Groping name for linked tooltip.
    If specified, linked tooltip will be groped interacting to be worked only with the same name. * @property {Function} [tooltip.format.title] Set format for the title of tooltip.
    * Specified function receives x of the data point to show. * @property {Function} [tooltip.format.name] Set format for the name of each data in tooltip.
    * Specified function receives name, ratio, id and index of the data point to show. ratio will be undefined if the chart is not donut/pie/gauge. * @property {Function} [tooltip.format.value] Set format for the value of each data value in tooltip. If undefined returned, the row of that value will be skipped to be called. * - Will pass following arguments to the given function: * - `value {string}`: Value of the data point. If data row contains multiple or ranged(ex. candlestick, area range, etc.) value, formatter will be called as value length. * - `ratio {number}`: Ratio of the data point in the `pie/donut/gauge` and `area/bar` when contains grouped data. Otherwise is `undefined`. * - `id {string}`: id of the data point * - `index {number}`: Index of the data point * @property {Function} [tooltip.position] Set custom position function for the tooltip.
    * This option can be used to modify the tooltip position by returning object that has top and left. * - Will pass following arguments to the given function: * - `data {Array}`: Current selected data array object. * - `width {number}`: Width of tooltip. * - `height {number}`: Height of tooltip. * - `element {SVGElement}`: Tooltip event bound element * - `pos {object}`: Current position of the tooltip. * @property {Function|object} [tooltip.contents] Set custom HTML for the tooltip.
    * If tooltip.grouped is true, data includes multiple data points.

    * Specified function receives `data` array and `defaultTitleFormat`, `defaultValueFormat` and `color` functions of the data point to show. * - **Note:** * - defaultTitleFormat: * - if `axis.x.tick.format` option will be used if set. * - otherwise, will return function based on tick format type(category, timeseries). * - defaultValueFormat: * - for Arc type (except gauge, radar), the function will return value from `(ratio * 100).toFixed(1)`. * - for Axis based types, will be used `axis.[y|y2].tick.format` option value if is set. * - otherwise, will parse value and return as number. * @property {string|HTMLElement} [tooltip.contents.bindto=undefined] Set CSS selector or element reference to bind tooltip. * - **NOTE:** When is specified, will not be updating tooltip's position. * @property {string} [tooltip.contents.template=undefined] Set tooltip's template.

    * Within template, below syntax will be replaced using template-like syntax string: * - **{{ ... }}**: the doubly curly brackets indicate loop block for data rows. * - **{=CLASS_TOOLTIP}**: default tooltip class name `bb-tooltip`. * - **{=CLASS_TOOLTIP_NAME}**: default tooltip data class name (ex. `bb-tooltip-name-data1`) * - **{=TITLE}**: title value. * - **{=COLOR}**: data color. * - **{=VALUE}**: data value. * @property {object} [tooltip.contents.text=undefined] Set additional text content within data loop, using template syntax. * - **NOTE:** It should contain `{ key: Array, ... }` value * - 'key' name is used as substitution within template as '{=KEY}' * - The value array length should match with the data length * @property {boolean} [tooltip.init.show=false] Show tooltip at the initialization. * @property {number} [tooltip.init.x=0] Set x Axis index(or index for Arc(donut, gauge, pie) types) to be shown at the initialization. * @property {object} [tooltip.init.position] Set the position of tooltip at the initialization. * @property {Function} [tooltip.onshow] Set a callback that will be invoked before the tooltip is shown. * @property {Function} [tooltip.onhide] Set a callback that will be invoked before the tooltip is hidden. * @property {Function} [tooltip.onshown] Set a callback that will be invoked after the tooltip is shown * @property {Function} [tooltip.onhidden] Set a callback that will be invoked after the tooltip is hidden. * @property {string|Function|null} [tooltip.order=null] Set tooltip data display order.

    * **Available Values:** * - `desc`: In descending data value order * - `asc`: In ascending data value order * - `null`: It keeps the data display order
    * **NOTE:** When `data.groups` is set, the order will follow as the stacked graph order.
    * If want to order as data bound, set any value rather than asc, desc or null. (ex. empty string "") * - `function(data1, data2) { ... }`: [Array.sort compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) * @see [Demo: Hide Tooltip](https://naver.github.io/billboard.js/demo/#Tooltip.HideTooltip) * @see [Demo: Tooltip Grouping](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipGrouping) * @see [Demo: Tooltip Format](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipFormat) * @see [Demo: Linked Tooltip](https://naver.github.io/billboard.js/demo/#Tooltip.LinkedTooltips) * @see [Demo: Tooltip Position](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipPosition) * @see [Demo: Tooltip Template](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipTemplate) * @example * tooltip: { * show: true, * doNotHide: true, * grouped: false, * format: { * title: function(x) { return "Data " + x; }, * name: function(name, ratio, id, index) { return name; }, * * // If data row contains multiple or ranged(ex. candlestick, area range, etc.) value, * // formatter will be called as value length times. * value: function(value, ratio, id, index) { return ratio; } * }, * position: function(data, width, height, element, pos) { * // data: [{x, index, id, name, value}, ...] * // width: Tooltip width * // height: Tooltip height * // element: Tooltip event bound element * // pos: { * // x: Current mouse event x position, * // y: Current mouse event y position, * // xAxis: Current x Axis position (the value is given for axis based chart type only) * // yAxis: Current y Axis position value or function(the value is given for axis based chart type only) * // } * * // yAxis will work differently per data lengths * // - a) Single data: `yAxis` will return `number` value * // - b) Multiple data: `yAxis` will return a function with property value * * // a) Single data: * // Get y coordinate * pos.yAxis; // y axis coordinate value of current data point * * // b) Multiple data: * // Get y coordinate of value 500, where 'data1' scales(y or y2). * // When 'data.axes' option is used, data can bound to different axes. * // - when "data.axes={data1: 'y'}", wil return y value from y axis scale. * // - when "data.axes={data1: 'y2'}", wil return y value from y2 axis scale. * pos.yAxis(500, "data1"); // will return y coordinate value of data1 * * pos.yAxis(500); // get y coordinate with value of 500, using y axis scale * pos.yAxis(500, null, "y2"); // get y coordinate with value of 500, using y2 axis scale * * return { * top: 0, * left: 0 * } * }, * * contents: function(d, defaultTitleFormat, defaultValueFormat, color) { * return ... // formatted html as you want * }, * * // specify tooltip contents using template * // - example of HTML returned: * //
      * //
    • 250
      data1
    • * //
    • 50
      data2
    • * //
    * contents: { * bindto: "#tooltip", * template: '
      {{' + * '
    • {=VALUE}
      ' + * '{=NAME}
    • ' + * '}}
    ' * } * * // with additional text value * // - example of HTML returned: * //
      * //
    • 250
      comment1data1text1
    • * //
    • 50
      comment2data2text2
    • * //
    * contents: { * bindto: "#tooltip", * text: { * // a) 'key' name is used as substitution within template as '{=KEY}' * // b) the length should match with the data length * VAR1: ["text1", "text2"], * VAR2: ["comment1", "comment2"], * }, * template: '
      {{' + * '
    • {=VALUE}{=VAR2}
      ' + * '{=NAME}{=VAR1}
    • ' + * '}}
    ' * } * * // sort tooltip data value display in ascending order * order: "asc", * * // specifying sort function * order: function(a, b) { * // param data passed format * {x: 5, value: 250, id: "data1", index: 5, name: "data1"} * ... * }, * * // show at the initialization * init: { * show: true, * x: 2, // x Axis index (or index for Arc(donut, gauge, pie) types) * position: { * top: "150px", // specify as number or as string with 'px' unit string * left: 250 // specify as number or as string with 'px' unit string * } * }, * * // fires prior tooltip is shown * onshow: function(selectedData) { * // current dataset selected * // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...] * selectedData; * }, * * // fires prior tooltip is hidden * onhide: function(selectedData) { * // current dataset selected * // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...] * selectedData; * }, * * // fires after tooltip is shown * onshown: function(selectedData) { * // current dataset selected * // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...] * selectedData; * }, * * // fires after tooltip is hidden * onhidden: function(selectedData) { * // current dataset selected * // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...] * selectedData; * }, * * // Link any tooltips when multiple charts are on the screen where same x coordinates are available * // Useful for timeseries correlation * linked: true, * * // Specify name to interact those with the same name only. * linked: { * name: "some-group" * } * } */ tooltip_show: !0, tooltip_doNotHide: !1, tooltip_grouped: !0, tooltip_format_title: undefined, tooltip_format_name: undefined, tooltip_format_value: undefined, tooltip_position: undefined, tooltip_contents: {}, tooltip_init_show: !1, tooltip_init_x: 0, tooltip_init_position: undefined, tooltip_linked: !1, tooltip_linked_name: "", tooltip_onshow: function tooltip_onshow() { _newArrowCheck(this, tooltip_this); }.bind(undefined), tooltip_onhide: function tooltip_onhide() { _newArrowCheck(this, tooltip_this); }.bind(undefined), tooltip_onshown: function tooltip_onshown() { _newArrowCheck(this, tooltip_this); }.bind(undefined), tooltip_onhidden: function tooltip_onhidden() { _newArrowCheck(this, tooltip_this); }.bind(undefined), tooltip_order: null }); ;// CONCATENATED MODULE: ./src/config/Options/Options.ts function Options_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function Options_objectSpread(e) { for (var r = 1, t; r < arguments.length; r++) { t = null != arguments[r] ? arguments[r] : {}; r % 2 ? Options_ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : Options_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ // common /** * Class to set options on generating chart. * - It's instantiated internally, not exposed for public. * @class Options * @see {@link bb.generate} to use these options on generating the chart */ let Options = /*#__PURE__*/function () { Options.setOptions = function setOptions(options) { var _this = this; this.data = options.reduce(function (a, c) { _newArrowCheck(this, _this); return Options_objectSpread(Options_objectSpread({}, a), c); }.bind(this), this.data); }; function Options() { return deepClone(main, boost, data, color, interaction, legend, title, tooltip, Options.data); } return Options; }(); Options.data = {}; ;// CONCATENATED MODULE: ./src/module/Cache.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Constant for cache key * - NOTE: Prefixed with '$', will be resetted when .load() is called * @private */ const KEY = { bubbleBaseLength: "$baseLength", colorPattern: "__colorPattern__", dataMinMax: "$dataMinMax", dataTotalSum: "$dataTotalSum", dataTotalPerIndex: "$totalPerIndex", legendItemTextBox: "legendItemTextBox", radarPoints: "$radarPoints", setOverOut: "setOverOut", callOverOutForTouch: "callOverOutForTouch", textRect: "textRect" }; let Cache = /*#__PURE__*/function () { function Cache() { this.cache = {}; } var _proto = Cache.prototype; /** * Add cache * @param {string} key Cache key * @param {*} value Value to be stored * @param {boolean} isDataType Weather the cache is data typed '{id:'data', id_org: 'data', values: [{x:0, index:0,...}, ...]}' * @returns {*} Added data value * @private */ _proto.add = function add(key, value, isDataType) { if (isDataType === void 0) { isDataType = !1; } this.cache[key] = isDataType ? this.cloneTarget(value) : value; return this.cache[key]; } /** * Remove cache * @param {string|Array} key Cache key * @private */; _proto.remove = function remove(key) { var _this = this; (isString(key) ? [key] : key).forEach(function (v) { _newArrowCheck(this, _this); return delete this.cache[v]; }.bind(this)); } /** * Get cahce * @param {string|Array} key Cache key * @param {boolean} isDataType Weather the cache is data typed '{id:'data', id_org: 'data', values: [{x:0, index:0,...}, ...]}' * @returns {*} * @private */; _proto.get = function get(key, isDataType) { if (isDataType === void 0) { isDataType = !1; } // when is isDataType, key should be string array if (isDataType && Array.isArray(key)) { const targets = []; for (let i = 0, id; id = key[i]; i++) { if (id in this.cache) { targets.push(this.cloneTarget(this.cache[id])); } } return targets; } else { const value = this.cache[key]; return isValue(value) ? value : null; } } /** * Reset cached data * @param {boolean} all true: reset all data, false: reset only '$' prefixed key data * @private */; _proto.reset = function reset(all) { const $$ = this; for (const x in $$.cache) { // reset the prefixed '$' key(which is internal use data) only. if (all || /^\$/.test(x)) { $$.cache[x] = null; } } } /** * Clone data target object * @param {object} target Data object * @returns {object} * @private */ // eslint-disable-next-line camelcase ; _proto.cloneTarget = function cloneTarget(target) { var _this2 = this; return { id: target.id, id_org: target.id_org, values: target.values.map(function (d) { _newArrowCheck(this, _this2); return { x: d.x, value: d.value, id: d.id }; }.bind(this)) }; }; return Cache; }(); ;// CONCATENATED MODULE: ./src/module/generator.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ const generator_setTimeout = win.setTimeout, generator_clearTimeout = win.clearTimeout; /** * Generate resize queue function * @param {boolean|number} option Resize option * @returns {Fucntion} * @private */ function generateResize(option) { var _this4 = this; const fn = []; let timeout; const callResizeFn = function () { var _this = this; // Delay all resize functions call, to prevent unintended excessive call from resize event callResizeFn.clear(); if (option === !1) { requestIdleCallback(function () { var _this2 = this; _newArrowCheck(this, _this); fn.forEach(function (f) { _newArrowCheck(this, _this2); return f(); }.bind(this)); }.bind(this), { timeout: 200 }); } else { timeout = generator_setTimeout(function () { var _this3 = this; _newArrowCheck(this, _this); fn.forEach(function (f) { _newArrowCheck(this, _this3); return f(); }.bind(this)); }.bind(this), isNumber(option) ? option : 200); } }; callResizeFn.clear = function () { _newArrowCheck(this, _this4); if (timeout) { generator_clearTimeout(timeout); timeout = null; } }.bind(this); callResizeFn.add = function (f) { _newArrowCheck(this, _this4); return fn.push(f); }.bind(this); callResizeFn.remove = function (f) { _newArrowCheck(this, _this4); return fn.splice(fn.indexOf(f), 1); }.bind(this); return callResizeFn; } /** * Generate transition queue function * @returns {Function} * @private */ function generateWait() { let transitionsToWait = []; // 'f' is called as selection.call(f, ...); const f = function (selection, callback) { var _this5 = this; /** * Check if transition is complete * @returns {boolean} Whether transition is complete * @private */ function loop() { let done = 0; for (let i = 0, t; t = transitionsToWait[i]; i++) { if (t === !0 || t.empty != null && t.empty()) { done++; continue; } // when tab isn't visible exit loop if (isTabVisible() === !1) { done = transitionsToWait.length; break; } try { t.transition(); } catch (e) { done++; } } return done === transitionsToWait.length; } runUntil(function () { _newArrowCheck(this, _this5); callback == null || callback(); }.bind(this), loop); }; f.add = function (t) { isArray(t) ? transitionsToWait = transitionsToWait.concat(t) : transitionsToWait.push(t); }; return f; } ;// CONCATENATED MODULE: ./src/module/worker.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ // Store blob in memory const blob = {}; /** * Get Object URL * @param {Function} fn Function to be executed in worker * @param {Array} depsFn Dependency functions to run given function(fn). * @returns {string} * @private */ function getObjectURL(fn, depsFn) { const fnString = fn.toString(), key = fnString.replace(/(function|[\s\W\n])/g, "").substring(0, 15); if (!(key in blob)) { var _depsFn$map$join; // Web Worker body blob[key] = new win.Blob([((_depsFn$map$join = depsFn == null ? void 0 : depsFn.map(String).join(";")) != null ? _depsFn$map$join : "") + "\n\n\t\t\tself.onmessage=function({data}) {\n\t\t\t\tconst result = (" + fnString + ").apply(null, data);\n\t\t\t\tself.postMessage(result);\n\t\t\t};"], { type: "text/javascript" }); } return win.URL.createObjectURL(blob[key]); } /** * Get WebWorker instance * @param {string} src URL object as string * @returns {object} WebWorker instance * @private */ function getWorker(src) { const worker = new win.Worker(src); // handle error worker.onerror = function (e) { // eslint-disable-next-line no-console console.error ? console.error(e) : console.log(e); }; return worker; } /** * Create and run on Web Worker * @param {boolean} useWorker Use Web Worker * @param {Function} fn Function to be executed in worker * @param {Function} callback Callback function to receive result from worker * @param {Array} depsFn Dependency functions to run given function(fn). * @returns {object} * @example * const worker = runWorker(function(arg) { * // do some tasks... * console.log("param:", A(arg)); * * return 1234; * }, function(data) { * // callback after worker is done * console.log("result:", data); * }, * [function A(){}] * ); * * worker(11111); * @private */ function runWorker(useWorker, fn, callback, depsFn) { if (useWorker === void 0) { useWorker = !0; } let runFn = function () { const res = fn.apply(void 0, arguments); callback(res); }; if (win.Worker && useWorker) { const src = getObjectURL(fn, depsFn), worker = getWorker(src); runFn = function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } // trigger worker worker.postMessage(args); // listen worker worker.onmessage = function (e) { // release object URL from memory win.URL.revokeObjectURL(src); return callback(e.data); }; // return new Promise((resolve, reject) => { // worker.onmessage = ({data}) => resolve(data); // worker.onerror = reject; // }); }; } return runFn; } // EXTERNAL MODULE: external {"commonjs":"d3-dsv","commonjs2":"d3-dsv","amd":"d3-dsv","root":"d3"} var external_commonjs_d3_dsv_commonjs2_d3_dsv_amd_d3_dsv_root_d3_ = __webpack_require__(5); ;// CONCATENATED MODULE: ./src/ChartInternal/data/convert.helper.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* eslint-disable */ /***** Functions to be executed on Web Worker ***** * NOTE: Don't allowed to use * - arrow function syntax * - Utils functions */ /** * Convert Columns data * @param {object} columns * @returns {Array} * @private */ function columns(columns) { const newRows = []; columns.forEach(function (col, i) { const key = col[0]; col.forEach(function (v, j) { if (j > 0) { if (typeof newRows[j - 1] === "undefined") { newRows[j - 1] = {}; } if (typeof v === "undefined") { throw new Error("Source data is missing a component at (" + i + ", " + j + ")!"); } newRows[j - 1][key] = v; } }); }); return newRows; } /** * Convert Rows data * @param {object} columns * @returns {Array} * @private */ function rows(rows) { const keys = rows[0], newRows = []; rows.forEach(function (row, i) { if (i > 0) { const newRow = {}; row.forEach(function (v, j) { if (typeof v === "undefined") { throw new Error("Source data is missing a component at (" + i + ", " + j + ")!"); } newRow[keys[j]] = v; }); newRows.push(newRow); } }); return newRows; } /** * Convert JSON data * @param {object} columns * @returns {Array} * @private */ function json(json, keysParam) { const newRows = []; let targetKeys, data; if (Array.isArray(json)) { const findValueInJson = function (object, path) { if (object[path] !== undefined) { return object[path]; } const convertedPath = path.replace(/\[(\w+)\]/g, ".$1"), pathArray = convertedPath.replace(/^\./, "").split("."); // convert indexes to properties (replace [] with .) // strip a leading dot let target = object; pathArray.some(function (k) { return !(target = target && k in target ? target[k] : undefined); }); return target; }; if (keysParam.x) { targetKeys = keysParam.value.concat(keysParam.x); } else { targetKeys = keysParam.value; } newRows.push(targetKeys); json.forEach(function (o) { const newRow = targetKeys.map(function (key) { // convert undefined to null because undefined data will be removed in convertDataToTargets() let v = findValueInJson(o, key); if (typeof v === "undefined") { v = null; } return v; }); newRows.push(newRow); }); data = rows(newRows); } else { Object.keys(json).forEach(function (key) { const tmp = json[key].concat(); tmp.unshift == null || tmp.unshift(key); newRows.push(tmp); }); data = columns(newRows); } return data; } /***** Functions can't be executed on Web Worker *****/ /** * Convert URL data * @param {string} url Remote URL * @param {string} mimeType MIME type string: json | csv | tsv * @param {object} headers Header object * @param {object} keys Key object * @param {Function} done Callback function * @private */ function url(url, mimeType, headers, keys, done) { if (mimeType === void 0) { mimeType = "csv"; } const req = new XMLHttpRequest(), converter = { csv: csv, tsv: tsv, json: json }; req.open("GET", url); if (headers) { Object.keys(headers).forEach(function (key) { req.setRequestHeader(key, headers[key]); }); } req.onreadystatechange = function () { if (req.readyState === 4) { if (req.status === 200) { const response = req.responseText; response && done.call(this, converter[mimeType](mimeType === "json" ? JSON.parse(response) : response, keys)); } else { throw new Error(url + ": Something went wrong loading!"); } } }; req.send(); } /** * Convert CSV/TSV data * @param {object} parser Parser object * @param {object} xsv Data * @returns {object} * @private */ function convertCsvTsvToData(parser, xsv) { var _this = this; const rows = parser.rows(xsv); let d; if (rows.length === 1) { d = [{}]; rows[0].forEach(function (id) { _newArrowCheck(this, _this); d[0][id] = null; }.bind(this)); } else { d = parser.parse(xsv); } return d; } function csv(xsv) { return convertCsvTsvToData({ rows: external_commonjs_d3_dsv_commonjs2_d3_dsv_amd_d3_dsv_root_d3_.csvParseRows, parse: external_commonjs_d3_dsv_commonjs2_d3_dsv_amd_d3_dsv_root_d3_.csvParse }, xsv); } function tsv(tsv) { return convertCsvTsvToData({ rows: external_commonjs_d3_dsv_commonjs2_d3_dsv_amd_d3_dsv_root_d3_.tsvParseRows, parse: external_commonjs_d3_dsv_commonjs2_d3_dsv_amd_d3_dsv_root_d3_.tsvParse }, tsv); } ;// CONCATENATED MODULE: ./src/ChartInternal/data/convert.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get data key for JSON * @param {string|object} keysParam Key params * @param {object} config Config object * @returns {string} Data key * @private */ function getDataKeyForJson(keysParam, config) { const keys = keysParam || (config == null ? void 0 : config.data_keys); if (keys != null && keys.x) { config.data_x = keys.x; } return keys; } /** * Data convert * @memberof ChartInternal * @private */ /* harmony default export */ var convert = ({ /** * Convert data according its type * @param {object} args data object * @param {Function} [callback] callback for url(XHR) type loading * @private */ convertData: function convertData(args, callback) { var _this = this; const config = this.config, useWorker = config.boost_useWorker; let data = args; if (args.bindto) { data = {}; ["url", "mimeType", "headers", "keys", "json", "keys", "rows", "columns"].forEach(function (v) { _newArrowCheck(this, _this); const key = "data_" + v; if (key in args) { data[v] = args[key]; } }.bind(this)); } if (data.url && callback) { url(data.url, data.mimeType, data.headers, getDataKeyForJson(data.keys, config), callback); } else if (data.json) { runWorker(useWorker, json, callback, [columns, rows])(data.json, getDataKeyForJson(data.keys, config)); } else if (data.rows) { runWorker(useWorker, rows, callback)(data.rows); } else if (data.columns) { runWorker(useWorker, columns, callback)(data.columns); } else if (args.bindto) { throw Error("url or json or rows or columns is required."); } }, convertDataToTargets: function convertDataToTargets(data, appendXs) { var _this2 = this; const $$ = this, axis = $$.axis, config = $$.config, state = $$.state, chartType = config.data_type; let isCategorized = !1, isTimeSeries = !1, isCustomX = !1; if (axis) { isCategorized = axis.isCategorized(); isTimeSeries = axis.isTimeSeries(); isCustomX = axis.isCustomX(); } const dataKeys = Object.keys(data[0] || {}), ids = dataKeys.length ? dataKeys.filter($$.isNotX, $$) : [], xs = dataKeys.length ? dataKeys.filter($$.isX, $$) : []; let xsData; // save x for update data by load when custom x and bb.x API ids.forEach(function (id) { var _this3 = this; _newArrowCheck(this, _this2); const xKey = this.getXKey(id); if (isCustomX || isTimeSeries) { // if included in input data if (xs.indexOf(xKey) >= 0) { xsData = (appendXs && $$.data.xs[id] || []).concat(data.map(function (d) { _newArrowCheck(this, _this3); return d[xKey]; }.bind(this)).filter(isValue).map(function (rawX, i) { _newArrowCheck(this, _this3); return $$.generateTargetX(rawX, id, i); }.bind(this))); } else if (config.data_x) { // if not included in input data, find from preloaded data of other id's x xsData = this.getOtherTargetXs(); } else if (notEmpty(config.data_xs)) { // if not included in input data, find from preloaded data xsData = $$.getXValuesOfXKey(xKey, $$.data.targets); } // MEMO: if no x included, use same x of current will be used } else { xsData = data.map(function (d, i) { _newArrowCheck(this, _this3); return i; }.bind(this)); } xsData && (this.data.xs[id] = xsData); }.bind(this)); // check x is defined ids.forEach(function (id) { _newArrowCheck(this, _this2); if (!this.data.xs[id]) { throw new Error("x is not defined for id = \"" + id + "\"."); } }.bind(this)); // convert to target const targets = ids.map(function (id, index) { var _this4 = this; _newArrowCheck(this, _this2); const convertedId = config.data_idConverter.bind($$.api)(id), xKey = $$.getXKey(id), isCategory = isCustomX && isCategorized, hasCategory = isCategory && data.map(function (v) { _newArrowCheck(this, _this4); return v.x; }.bind(this)).every(function (v) { _newArrowCheck(this, _this4); return config.axis_x_categories.indexOf(v) > -1; }.bind(this)), isDataAppend = data.__append__, xIndex = xKey === null && isDataAppend ? $$.api.data.values(id).length : 0; // when .load() with 'append' option is used for indexed axis // @ts-ignore return { id: convertedId, id_org: id, values: data.map(function (d, i) { _newArrowCheck(this, _this4); const rawX = d[xKey]; let value = d[id], x; value = value !== null && !isNaN(value) && !isObject(value) ? +value : isArray(value) || isObject(value) ? value : null; // use x as categories if custom x and categorized if ((isCategory || state.hasRadar) && index === 0 && !isUndefined(rawX)) { if (!hasCategory && index === 0 && i === 0 && !isDataAppend) { config.axis_x_categories = []; } x = config.axis_x_categories.indexOf(rawX); if (x === -1) { x = config.axis_x_categories.length; config.axis_x_categories.push(rawX); } } else { x = $$.generateTargetX(rawX, id, xIndex + i); } // mark as x = undefined if value is undefined and filter to remove after mapped if (isUndefined(value) || $$.data.xs[id].length <= i) { x = undefined; } return { x: x, value: value, id: convertedId, index: -1 }; }.bind(this)).filter(function (v) { _newArrowCheck(this, _this4); return isDefined(v.x); }.bind(this)) }; }.bind(this)); // finish targets targets.forEach(function (t) { var _this5 = this, _$$$data$xs$t$id; _newArrowCheck(this, _this2); // sort values by its x if (config.data_xSort) { t.values = t.values.sort(function (v1, v2) { _newArrowCheck(this, _this5); const x1 = v1.x || v1.x === 0 ? v1.x : Infinity, x2 = v2.x || v2.x === 0 ? v2.x : Infinity; return x1 - x2; }.bind(this)); } // indexing each value t.values.forEach(function (v, i) { _newArrowCheck(this, _this5); return v.index = i; }.bind(this)); // this needs to be sorted because its index and value.index is identical (_$$$data$xs$t$id = $$.data.xs[t.id]) == null || _$$$data$xs$t$id.sort(function (v1, v2) { _newArrowCheck(this, _this5); return v1 - v2; }.bind(this)); }.bind(this)); // cache information about values state.hasNegativeValue = $$.hasNegativeValueInTargets(targets); state.hasPositiveValue = $$.hasPositiveValueInTargets(targets); // set target types if (chartType && $$.isValidChartType(chartType)) { const targetIds = $$.mapToIds(targets).filter(function (id) { _newArrowCheck(this, _this2); return !(id in config.data_types) || !$$.isValidChartType(config.data_types[id]); }.bind(this)); $$.setTargetType(targetIds, chartType); } // cache as original id keyed targets.forEach(function (d) { _newArrowCheck(this, _this2); return $$.cache.add(d.id_org, d, !0); }.bind(this)); return targets; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/data/data.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var data_data = ({ isX: function isX(key) { const $$ = this, config = $$.config, dataKey = config.data_x && key === config.data_x, existValue = notEmpty(config.data_xs) && hasValue(config.data_xs, key); return dataKey || existValue; }, isNotX: function isNotX(key) { return !this.isX(key); }, isStackNormalized: function isStackNormalized() { const config = this.config; return !!(config.data_stack_normalize && config.data_groups.length); }, /** * Check if given id is grouped data or has grouped data * @param {string} id Data id value * @returns {boolean} is grouped data or has grouped data * @private */ isGrouped: function isGrouped(id) { var _this = this; const groups = this.config.data_groups; return id ? groups.some(function (v) { _newArrowCheck(this, _this); return v.indexOf(id) >= 0 && v.length > 1; }.bind(this)) : groups.length > 0; }, getXKey: function getXKey(id) { const $$ = this, config = $$.config; return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null; }, getXValuesOfXKey: function getXValuesOfXKey(key, targets) { var _this2 = this; const $$ = this, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []; let xValues; ids.forEach(function (id) { _newArrowCheck(this, _this2); if ($$.getXKey(id) === key) { xValues = $$.data.xs[id]; } }.bind(this)); return xValues; }, /** * Get index number based on given x Axis value * @param {Date|number|string} x x Axis to be compared * @param {Array} basedX x Axis list to be based on * @returns {number} index number * @private */ getIndexByX: function getIndexByX(x, basedX) { const $$ = this; return basedX ? basedX.indexOf(isString(x) ? x : +x) : ($$.filterByX($$.data.targets, x)[0] || { index: null }).index; }, getXValue: function getXValue(id, i) { const $$ = this; return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i; }, getOtherTargetXs: function getOtherTargetXs() { const $$ = this, idsForX = Object.keys($$.data.xs); return idsForX.length ? $$.data.xs[idsForX[0]] : null; }, getOtherTargetX: function getOtherTargetX(index) { const xs = this.getOtherTargetXs(); return xs && index < xs.length ? xs[index] : null; }, addXs: function addXs(xs) { var _this3 = this; const $$ = this, config = $$.config; Object.keys(xs).forEach(function (id) { _newArrowCheck(this, _this3); config.data_xs[id] = xs[id]; }.bind(this)); }, isMultipleX: function isMultipleX() { return notEmpty(this.config.data_xs) || this.hasType("bubble") || this.hasType("scatter"); }, addName: function addName(data) { const $$ = this, config = $$.config; let name; if (data) { name = config.data_names[data.id]; data.name = name !== undefined ? name : data.id; } return data; }, /** * Get all values on given index * @param {number} index Index * @param {boolean} filterNull Filter nullish value * @returns {Array} * @private */ getAllValuesOnIndex: function getAllValuesOnIndex(index, filterNull) { var _this4 = this; if (filterNull === void 0) { filterNull = !1; } const $$ = this; let value = $$.filterTargetsToShow($$.data.targets).map(function (t) { _newArrowCheck(this, _this4); return $$.addName($$.getValueOnIndex(t.values, index)); }.bind(this)); if (filterNull) { value = value.filter(function (v) { _newArrowCheck(this, _this4); return v && "value" in v && isValue(v.value); }.bind(this)); } return value; }, getValueOnIndex: function getValueOnIndex(values, index) { var _this5 = this; const valueOnIndex = values.filter(function (v) { _newArrowCheck(this, _this5); return v.index === index; }.bind(this)); return valueOnIndex.length ? valueOnIndex[0] : null; }, updateTargetX: function updateTargetX(targets, x) { var _this6 = this; const $$ = this; targets.forEach(function (t) { var _this7 = this; _newArrowCheck(this, _this6); t.values.forEach(function (v, i) { _newArrowCheck(this, _this7); v.x = $$.generateTargetX(x[i], t.id, i); }.bind(this)); $$.data.xs[t.id] = x; }.bind(this)); }, updateTargetXs: function updateTargetXs(targets, xs) { var _this8 = this; const $$ = this; targets.forEach(function (t) { _newArrowCheck(this, _this8); xs[t.id] && $$.updateTargetX([t], xs[t.id]); }.bind(this)); }, generateTargetX: function generateTargetX(rawX, id, index) { const $$ = this, axis = $$.axis; let x = axis != null && axis.isCategorized() ? index : rawX || index; if (axis != null && axis.isTimeSeries()) { const fn = parseDate.bind($$); x = rawX ? fn(rawX) : fn($$.getXValue(id, index)); } else if (axis != null && axis.isCustomX() && !(axis != null && axis.isCategorized())) { x = isValue(rawX) ? +rawX : $$.getXValue(id, index); } return x; }, updateXs: function updateXs(values) { var _this9 = this; if (values.length) { this.axis.xs = values.map(function (v) { _newArrowCheck(this, _this9); return v.x; }.bind(this)); } }, getPrevX: function getPrevX(i) { const x = this.axis.xs[i - 1]; return isDefined(x) ? x : null; }, getNextX: function getNextX(i) { const x = this.axis.xs[i + 1]; return isDefined(x) ? x : null; }, /** * Get base value isAreaRangeType * @param {object} data Data object * @returns {number} * @private */ getBaseValue: function getBaseValue(data) { const $$ = this, hasAxis = $$.state.hasAxis; let value = data.value; // In case of area-range, data is given as: [low, mid, high] or {low, mid, high} // will take the 'mid' as the base value if (value && hasAxis) { if ($$.isAreaRangeType(data)) { value = $$.getRangedData(data, "mid"); } else if ($$.isBubbleZType(data)) { value = $$.getBubbleZData(value, "y"); } } return value; }, /** * Get min/max value from the data * @private * @param {Array} data array data to be evaluated * @returns {{min: {number}, max: {number}}} */ getMinMaxValue: function getMinMaxValue(data) { var _this10 = this; const getBaseValue = this.getBaseValue.bind(this); let min, max; (data || this.data.targets.map(function (t) { _newArrowCheck(this, _this10); return t.values; }.bind(this))).forEach(function (v, i) { _newArrowCheck(this, _this10); const value = v.map(getBaseValue).filter(isNumber); min = Math.min.apply(Math, [i ? min : Infinity].concat(value)); max = Math.max.apply(Math, [i ? max : -Infinity].concat(value)); }.bind(this)); return { min: min, max: max }; }, /** * Get the min/max data * @private * @returns {{min: Array, max: Array}} */ getMinMaxData: function getMinMaxData() { var _this11 = this; const $$ = this, cacheKey = KEY.dataMinMax; let minMaxData = $$.cache.get(cacheKey); if (!minMaxData) { const data = $$.data.targets.map(function (t) { _newArrowCheck(this, _this11); return t.values; }.bind(this)), minMax = $$.getMinMaxValue(data); let min = [], max = []; data.forEach(function (v) { _newArrowCheck(this, _this11); const minData = $$.getFilteredDataByValue(v, minMax.min), maxData = $$.getFilteredDataByValue(v, minMax.max); if (minData.length) { min = min.concat(minData); } if (maxData.length) { max = max.concat(maxData); } }.bind(this)); // update the cached data $$.cache.add(cacheKey, minMaxData = { min: min, max: max }); } return minMaxData; }, /** * Get sum of data per index * @private * @returns {Array} */ getTotalPerIndex: function getTotalPerIndex() { var _this12 = this; const $$ = this, cacheKey = KEY.dataTotalPerIndex; let sum = $$.cache.get(cacheKey); if (($$.config.data_groups.length || $$.isStackNormalized()) && !sum) { sum = []; $$.data.targets.forEach(function (row) { var _this13 = this; _newArrowCheck(this, _this12); row.values.forEach(function (v, i) { _newArrowCheck(this, _this13); if (!sum[i]) { sum[i] = 0; } sum[i] += isNumber(v.value) ? v.value : 0; }.bind(this)); }.bind(this)); } return sum; }, /** * Get total data sum * @param {boolean} subtractHidden Subtract hidden data from total * @returns {number} * @private */ getTotalDataSum: function getTotalDataSum(subtractHidden) { var _this14 = this; const $$ = this, cacheKey = KEY.dataTotalSum; let total = $$.cache.get(cacheKey); if (!isNumber(total)) { const sum = mergeArray($$.data.targets.map(function (t) { _newArrowCheck(this, _this14); return t.values; }.bind(this))).map(function (v) { _newArrowCheck(this, _this14); return v.value; }.bind(this)); total = sum.length ? sum.reduce(function (p, c) { _newArrowCheck(this, _this14); return p + c; }.bind(this)) : 0; $$.cache.add(cacheKey, total); } if (subtractHidden) { total -= $$.getHiddenTotalDataSum(); } return total; }, /** * Get total hidden data sum * @returns {number} * @private */ getHiddenTotalDataSum: function getHiddenTotalDataSum() { var _this15 = this; const $$ = this, api = $$.api, hiddenTargetIds = $$.state.hiddenTargetIds; let total = 0; if (hiddenTargetIds.length) { total = api.data.values.bind(api)(hiddenTargetIds).reduce(function (p, c) { _newArrowCheck(this, _this15); return p + c; }.bind(this)); } return total; }, /** * Get filtered data by value * @param {object} data Data * @param {number} value Value to be filtered * @returns {Array} filtered array data * @private */ getFilteredDataByValue: function getFilteredDataByValue(data, value) { var _this16 = this; return data.filter(function (t) { _newArrowCheck(this, _this16); return this.getBaseValue(t) === value; }.bind(this)); }, /** * Return the max length of the data * @returns {number} max data length * @private */ getMaxDataCount: function getMaxDataCount() { var _this17 = this; return Math.max.apply(Math, this.data.targets.map(function (t) { _newArrowCheck(this, _this17); return t.values.length; }.bind(this)).concat([0])); }, getMaxDataCountTarget: function getMaxDataCountTarget() { var _this18 = this; let target = this.filterTargetsToShow() || []; const length = target.length, isInverted = this.config.axis_x_inverted; if (length > 1) { target = target.map(function (t) { _newArrowCheck(this, _this18); return t.values; }.bind(this)).reduce(function (a, b) { _newArrowCheck(this, _this18); return a.concat(b); }.bind(this)).map(function (v) { _newArrowCheck(this, _this18); return v.x; }.bind(this)); target = sortValue(getUnique(target)).map(function (x, index, array) { _newArrowCheck(this, _this18); return { x: x, index: isInverted ? array.length - index - 1 : index }; }.bind(this)); } else if (length) { target = target[0].values.concat(); } return target; }, mapToIds: function mapToIds(targets) { var _this19 = this; return targets.map(function (d) { _newArrowCheck(this, _this19); return d.id; }.bind(this)); }, mapToTargetIds: function mapToTargetIds(ids) { const $$ = this; return ids ? isArray(ids) ? ids.concat() : [ids] : $$.mapToIds($$.data.targets); }, hasTarget: function hasTarget(targets, id) { const ids = this.mapToIds(targets); for (let i = 0, val; val = ids[i]; i++) { if (val === id) { return !0; } } return !1; }, isTargetToShow: function isTargetToShow(targetId) { return this.state.hiddenTargetIds.indexOf(targetId) < 0; }, isLegendToShow: function isLegendToShow(targetId) { return this.state.hiddenLegendIds.indexOf(targetId) < 0; }, filterTargetsToShow: function filterTargetsToShow(targets) { var _this20 = this; const $$ = this; return (targets || $$.data.targets).filter(function (t) { _newArrowCheck(this, _this20); return $$.isTargetToShow(t.id); }.bind(this)); }, mapTargetsToUniqueXs: function mapTargetsToUniqueXs(targets) { var _this21 = this; const $$ = this, axis = $$.axis; let xs = []; if (targets != null && targets.length) { xs = getUnique(mergeArray(targets.map(function (t) { var _this22 = this; _newArrowCheck(this, _this21); return t.values.map(function (v) { _newArrowCheck(this, _this22); return +v.x; }.bind(this)); }.bind(this)))); xs = axis != null && axis.isTimeSeries() ? xs.map(function (x) { _newArrowCheck(this, _this21); return new Date(+x); }.bind(this)) : xs.map(Number); } return sortValue(xs); }, /** * Add to the state target Ids * @param {string} type State's prop name * @param {Array|string} targetIds Target ids array * @private */ addTargetIds: function addTargetIds(type, targetIds) { var _this23 = this; const state = this.state, ids = isArray(targetIds) ? targetIds : [targetIds]; ids.forEach(function (v) { _newArrowCheck(this, _this23); state[type].indexOf(v) < 0 && state[type].push(v); }.bind(this)); }, /** * Remove from the state target Ids * @param {string} type State's prop name * @param {Array|string} targetIds Target ids array * @private */ removeTargetIds: function removeTargetIds(type, targetIds) { var _this24 = this; const state = this.state, ids = isArray(targetIds) ? targetIds : [targetIds]; ids.forEach(function (v) { _newArrowCheck(this, _this24); const index = state[type].indexOf(v); index >= 0 && state[type].splice(index, 1); }.bind(this)); }, addHiddenTargetIds: function addHiddenTargetIds(targetIds) { this.addTargetIds("hiddenTargetIds", targetIds); }, removeHiddenTargetIds: function removeHiddenTargetIds(targetIds) { this.removeTargetIds("hiddenTargetIds", targetIds); }, addHiddenLegendIds: function addHiddenLegendIds(targetIds) { this.addTargetIds("hiddenLegendIds", targetIds); }, removeHiddenLegendIds: function removeHiddenLegendIds(targetIds) { this.removeTargetIds("hiddenLegendIds", targetIds); }, getValuesAsIdKeyed: function getValuesAsIdKeyed(targets) { var _this25 = this; const $$ = this, hasAxis = $$.state.hasAxis, ys = {}, isMultipleX = $$.isMultipleX(), xs = isMultipleX ? $$.mapTargetsToUniqueXs(targets).map(function (v) { _newArrowCheck(this, _this25); return isString(v) ? v : +v; }.bind(this)) : null; targets.forEach(function (t) { var _this26 = this; _newArrowCheck(this, _this25); const data = []; t.values.filter(function (_ref) { let value = _ref.value; _newArrowCheck(this, _this26); return isValue(value) || value === null; }.bind(this)).forEach(function (v) { _newArrowCheck(this, _this26); let value = v.value; // exclude 'volume' value to correct mis domain calculation if (value !== null && $$.isCandlestickType(v)) { value = isArray(value) ? value.slice(0, 4) : [value.open, value.high, value.low, value.close]; } if (isArray(value)) { data.push.apply(data, value); } else if (isObject(value) && "high" in value) { data.push.apply(data, Object.values(value)); } else if ($$.isBubbleZType(v)) { data.push(hasAxis && $$.getBubbleZData(value, "y")); } else { if (isMultipleX) { data[$$.getIndexByX(v.x, xs)] = value; } else { data.push(value); } } }.bind(this)); ys[t.id] = data; }.bind(this)); return ys; }, checkValueInTargets: function checkValueInTargets(targets, checker) { const ids = Object.keys(targets); let values; for (let i = 0; i < ids.length; i++) { values = targets[ids[i]].values; for (let j = 0; j < values.length; j++) { if (checker(values[j].value)) { return !0; } } } return !1; }, hasMultiTargets: function hasMultiTargets() { return this.filterTargetsToShow().length > 1; }, hasNegativeValueInTargets: function hasNegativeValueInTargets(targets) { var _this27 = this; return this.checkValueInTargets(targets, function (v) { _newArrowCheck(this, _this27); return v < 0; }.bind(this)); }, hasPositiveValueInTargets: function hasPositiveValueInTargets(targets) { var _this28 = this; return this.checkValueInTargets(targets, function (v) { _newArrowCheck(this, _this28); return v > 0; }.bind(this)); }, /** * Sort targets data * Note: For stacked bar, will sort from the total sum of data series, not for each stacked bar * @param {Array} targetsValue Target value * @returns {Array} * @private */ orderTargets: function orderTargets(targetsValue) { const $$ = this, targets = [].concat(targetsValue), fn = $$.getSortCompareFn(); fn && targets.sort(fn); return targets; }, /** * Get data.order compare function * @param {boolean} isReversed for Arc & Treemap type sort order needs to be reversed * @returns {Function} compare function * @private */ getSortCompareFn: function getSortCompareFn(isReversed) { var _this29 = this; if (isReversed === void 0) { isReversed = !1; } const $$ = this, config = $$.config, order = config.data_order, orderAsc = /asc/i.test(order), orderDesc = /desc/i.test(order); let fn; if (orderAsc || orderDesc) { const reducer = function (p, c) { _newArrowCheck(this, _this29); return p + Math.abs(c.value); }.bind(this); fn = function (t1, t2) { _newArrowCheck(this, _this29); const t1Sum = "values" in t1 ? t1.values.reduce(reducer, 0) : t1.value, t2Sum = "values" in t2 ? t2.values.reduce(reducer, 0) : t2.value; return isReversed ? orderAsc ? t1Sum - t2Sum : t2Sum - t1Sum : orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum; }.bind(this); } else if (isFunction(order)) { fn = order.bind($$.api); } return fn || null; }, filterByX: function filterByX(targets, x) { var _this30 = this; return mergeArray(targets.map(function (t) { _newArrowCheck(this, _this30); return t.values; }.bind(this))).filter(function (v) { _newArrowCheck(this, _this30); return v.x - x === 0; }.bind(this)); }, filterRemoveNull: function filterRemoveNull(data) { var _this31 = this; return data.filter(function (d) { _newArrowCheck(this, _this31); return isValue(this.getBaseValue(d)); }.bind(this)); }, filterByXDomain: function filterByXDomain(targets, xDomain) { var _this32 = this; return targets.map(function (t) { var _this33 = this; _newArrowCheck(this, _this32); return { id: t.id, id_org: t.id_org, values: t.values.filter(function (v) { _newArrowCheck(this, _this33); return xDomain[0] <= v.x && v.x <= xDomain[1]; }.bind(this)) }; }.bind(this)); }, hasDataLabel: function hasDataLabel() { const dataLabels = this.config.data_labels; return isboolean(dataLabels) && dataLabels || isObjectType(dataLabels) && notEmpty(dataLabels); }, /** * Get data index from the event coodinates * @param {Event} event Event object * @returns {number} */ getDataIndexFromEvent: function getDataIndexFromEvent(event) { const $$ = this, config = $$.config, _$$$state = $$.state, hasRadar = _$$$state.hasRadar, inputType = _$$$state.inputType, _$$$state$eventReceiv = _$$$state.eventReceiver, coords = _$$$state$eventReceiv.coords, rect = _$$$state$eventReceiv.rect; let index; if (hasRadar) { let target = event.target; // in case of multilined axis text if (/tspan/i.test(target.tagName)) { target = target.parentNode; } const d = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(target).datum(); index = d && Object.keys(d).length === 1 ? d.index : undefined; } else { const isRotated = config.axis_rotated, e = inputType === "touch" && event.changedTouches ? event.changedTouches[0] : event; // get data based on the mouse coords index = findIndex(coords, isRotated ? e.clientY - rect.top : e.clientX - rect.left, 0, coords.length - 1, isRotated); } return index; }, getDataLabelLength: function getDataLabelLength(min, max, key) { var _this34 = this; const $$ = this, lengths = [0, 0]; $$.$el.chart.select("svg").selectAll(".dummy").data([min, max]).enter().append("text").text(function (d) { _newArrowCheck(this, _this34); return $$.dataLabelFormat(d.id)(d); }.bind(this)).each(function (d, i) { lengths[i] = this.getBoundingClientRect()[key] * 1.3; }).remove(); return lengths; }, isNoneArc: function isNoneArc(d) { return this.hasTarget(this.data.targets, d.id); }, isArc: function isArc(d) { return "data" in d && this.hasTarget(this.data.targets, d.data.id); }, findSameXOfValues: function findSameXOfValues(values, index) { const targetX = values[index].x, sames = []; let i; for (i = index - 1; i >= 0; i--) { if (targetX !== values[i].x) { break; } sames.push(values[i]); } for (i = index; i < values.length; i++) { if (targetX !== values[i].x) { break; } sames.push(values[i]); } return sames; }, findClosestFromTargets: function findClosestFromTargets(targets, pos) { var _this35 = this; const $$ = this, candidates = targets.map(function (target) { _newArrowCheck(this, _this35); return $$.findClosest(target.values, pos); }.bind(this)); // map to array of closest points of each target // decide closest point and return return $$.findClosest(candidates, pos); }, findClosest: function findClosest(values, pos) { var _this36 = this; const $$ = this, main = $$.$el.main, data = values.filter(function (v) { _newArrowCheck(this, _this36); return v && isValue(v.value); }.bind(this)); let minDist, closest; // find mouseovering bar/candlestick // https://github.com/naver/billboard.js/issues/2434 data.filter(function (v) { _newArrowCheck(this, _this36); return $$.isBarType(v.id) || $$.isCandlestickType(v.id); }.bind(this)).forEach(function (v) { _newArrowCheck(this, _this36); const selector = $$.isBarType(v.id) ? "." + $BAR.chartBar + "." + $COMMON.target + $$.getTargetSelectorSuffix(v.id) + " ." + $BAR.bar + "-" + v.index : "." + $CANDLESTICK.chartCandlestick + "." + $COMMON.target + $$.getTargetSelectorSuffix(v.id) + " ." + $CANDLESTICK.candlestick + "-" + v.index + " path"; if (!closest && $$.isWithinBar(main.select(selector).node())) { closest = v; } }.bind(this)); // find closest point from non-bar/candlestick data.filter(function (v) { _newArrowCheck(this, _this36); return !$$.isBarType(v.id) && !$$.isCandlestickType(v.id); }.bind(this)).forEach(function (v) { _newArrowCheck(this, _this36); const d = $$.dist(v, pos); minDist = $$.getPointSensitivity(v); if (d < minDist) { minDist = d; closest = v; } }.bind(this)); return closest; }, dist: function dist(data, pos) { const $$ = this, isRotated = $$.config.axis_rotated, scale = $$.scale, y = $$.circleY(data, data.index), x = (scale.zoom || scale.x)(data.x); // true: 1, false: 0 // true: 0, false: 1 return Math.sqrt(Math.pow(x - pos[+isRotated], 2) + Math.pow(y - pos[+!isRotated], 2)); }, /** * Convert data for step type * @param {Array} values Object data values * @returns {Array} * @private */ convertValuesToStep: function convertValuesToStep(values) { const $$ = this, axis = $$.axis, config = $$.config, stepType = config.line_step_type, isCategorized = axis ? axis.isCategorized() : !1, converted = isArray(values) ? values.concat() : [values]; if (!(isCategorized || /step\-(after|before)/.test(stepType))) { return values; } // when all datas are null, return empty array // https://github.com/naver/billboard.js/issues/3124 if (converted.length) { // insert & append cloning first/last value to be fully rendered covering on each gap sides const head = converted[0], tail = converted[converted.length - 1], id = head.id; let x = head.x; // insert head converted.unshift({ x: --x, value: head.value, id: id }); isCategorized && stepType === "step-after" && converted.unshift({ x: --x, value: head.value, id: id }); // append tail x = tail.x; converted.push({ x: ++x, value: tail.value, id: id }); isCategorized && stepType === "step-before" && converted.push({ x: ++x, value: tail.value, id: id }); } return converted; }, convertValuesToRange: function convertValuesToRange(values) { var _this37 = this; const converted = isArray(values) ? values.concat() : [values], ranges = []; converted.forEach(function (range) { _newArrowCheck(this, _this37); const x = range.x, id = range.id; ranges.push({ x: x, id: id, value: range.value[0] }); ranges.push({ x: x, id: id, value: range.value[2] }); }.bind(this)); return ranges; }, updateDataAttributes: function updateDataAttributes(name, attrs) { var _this38 = this; const $$ = this, config = $$.config, current = config["data_" + name]; if (isUndefined(attrs)) { return current; } Object.keys(attrs).forEach(function (id) { _newArrowCheck(this, _this38); current[id] = attrs[id]; }.bind(this)); $$.redraw({ withLegend: !0 }); return current; }, getRangedData: function getRangedData(d, key, type) { var _this39 = this; if (key === void 0) { key = ""; } if (type === void 0) { type = "areaRange"; } const value = d == null ? void 0 : d.value; if (isArray(value)) { if (type === "bar") { return value.reduce(function (a, c) { _newArrowCheck(this, _this39); return c - a; }.bind(this)); } else { // @ts-ignore const index = { areaRange: ["high", "mid", "low"], candlestick: ["open", "high", "low", "close", "volume"] }[type].indexOf(key); return index >= 0 && value ? value[index] : undefined; } } else if (value && key) { return value[key]; } return value; }, /** * Set ratio for grouped data * @param {Array} data Data array * @private */ setRatioForGroupedData: function setRatioForGroupedData(data) { var _this40 = this; const $$ = this, config = $$.config; // calculate ratio if grouped data exists if (config.data_groups.length && data.some(function (d) { _newArrowCheck(this, _this40); return $$.isGrouped(d.id); }.bind(this))) { const setter = function (d) { _newArrowCheck(this, _this40); return $$.getRatio("index", d, !0); }.bind(this); data.forEach(function (v) { _newArrowCheck(this, _this40); "values" in v ? v.values.forEach(setter) : setter(v); }.bind(this)); } }, /** * Get ratio value * @param {string} type Ratio for given type * @param {object} d Data value object * @param {boolean} asPercent Convert the return as percent or not * @returns {number} Ratio value * @private */ getRatio: function getRatio(type, d, asPercent) { var _this41 = this; if (asPercent === void 0) { asPercent = !1; } const $$ = this, config = $$.config, state = $$.state, api = $$.api; let ratio = 0; if (d && api.data.shown().length) { ratio = d.ratio || d.value; if (type === "arc") { // if has padAngle set, calculate rate based on value if ($$.pie.padAngle()()) { ratio = d.value / $$.getTotalDataSum(!0); // otherwise, based on the rendered angle value } else { const gaugeArcLength = config.gauge_fullCircle ? $$.getArcLength() : $$.getGaugeStartAngle() * -2, arcLength = $$.hasType("gauge") ? gaugeArcLength : Math.PI * 2; ratio = (d.endAngle - d.startAngle) / arcLength; } } else if (type === "index") { const dataValues = api.data.values.bind(api); let total = this.getTotalPerIndex(); if (state.hiddenTargetIds.length) { let hiddenSum = dataValues(state.hiddenTargetIds, !1); if (hiddenSum.length) { hiddenSum = hiddenSum.reduce(function (acc, curr) { var _this42 = this; _newArrowCheck(this, _this41); return acc.map(function (v, i) { _newArrowCheck(this, _this42); return (isNumber(v) ? v : 0) + curr[i]; }.bind(this)); }.bind(this)); total = total.map(function (v, i) { _newArrowCheck(this, _this41); return v - hiddenSum[i]; }.bind(this)); } } const divisor = total[d.index]; d.ratio = isNumber(d.value) && total && divisor ? d.value / divisor : 0; ratio = d.ratio; } else if (type === "radar") { ratio = parseFloat(Math.max(d.value, 0) + "") / state.current.dataMax * config.radar_size_ratio; } else if (type === "bar") { const yScale = $$.getYScaleById.bind($$)(d.id), max = yScale.domain().reduce(function (a, c) { _newArrowCheck(this, _this41); return c - a; }.bind(this)); // when all data are 0, return 0 ratio = max === 0 ? 0 : Math.abs($$.getRangedData(d, null, type) / max); } else if (type === "treemap") { ratio /= $$.getTotalDataSum(!0); } } return asPercent && ratio ? ratio * 100 : ratio; }, /** * Sort data index to be aligned with x axis. * @param {Array} tickValues Tick array values * @private */ updateDataIndexByX: function updateDataIndexByX(tickValues) { var _this43 = this; const $$ = this, tickValueMap = tickValues.reduce(function (out, tick, index) { _newArrowCheck(this, _this43); out[+tick.x] = index; return out; }.bind(this), {}); $$.data.targets.forEach(function (t) { var _this44 = this; _newArrowCheck(this, _this43); t.values.forEach(function (value, valueIndex) { _newArrowCheck(this, _this44); let index = tickValueMap[+value.x]; if (index === undefined) { index = valueIndex; } value.index = index; }.bind(this)); }.bind(this)); }, /** * Determine if bubble has dimension data * @param {object|Array} d data value * @returns {boolean} * @private */ isBubbleZType: function isBubbleZType(d) { const $$ = this; return $$.isBubbleType(d) && (isObject(d.value) && ("z" in d.value || "y" in d.value) || isArray(d.value) && d.value.length >= 2); }, /** * Determine if bar has ranged data * @param {Array} d data value * @returns {boolean} * @private */ isBarRangeType: function isBarRangeType(d) { var _this45 = this; const $$ = this, value = d.value; return $$.isBarType(d) && isArray(value) && value.length >= 2 && value.every(function (v) { _newArrowCheck(this, _this45); return isNumber(v); }.bind(this)); }, /** * Get data object by id * @param {string} id data id * @returns {object} * @private */ getDataById: function getDataById(id) { var _d$; const d = this.cache.get(id) || this.api.data(id); return (_d$ = d == null ? void 0 : d[0]) != null ? _d$ : d; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/data/load.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Call done callback with resize after transition * @param {Function} fn Callback function * @param {boolean} resizeAfter Weather to resize chart after the load * @private */ function callDone(fn, resizeAfter) { if (resizeAfter === void 0) { resizeAfter = !1; } const $$ = this, api = $$.api; resizeAfter && $$.api.flush(!0); fn == null || fn.call(api); } /* harmony default export */ var load = ({ load: function load(rawTargets, args) { var _this = this; const $$ = this, data = $$.data, append = args.append; let targets = rawTargets; if (targets) { // filter loading targets if needed if (args.filter) { targets = targets.filter(args.filter); } // set type if args.types || args.type specified if (args.type || args.types) { targets.forEach(function (t) { var _args$types; _newArrowCheck(this, _this); const type = ((_args$types = args.types) == null ? void 0 : _args$types[t.id]) || args.type; $$.setTargetType(t.id, type); }.bind(this)); } // Update/Add data data.targets.forEach(function (d) { _newArrowCheck(this, _this); for (let i = 0; i < targets.length; i++) { if (d.id === targets[i].id) { d.values = append ? d.values.concat(targets[i].values) : targets[i].values; targets.splice(i, 1); break; } } }.bind(this)); data.targets = data.targets.concat(targets); // add remained } // Set targets $$.updateTargets(data.targets); // Redraw with new targets $$.redraw({ withUpdateOrgXDomain: !0, withUpdateXDomain: !0, withLegend: !0 }); // Update current state chart type and elements list after redraw $$.updateTypesElements(); callDone.call($$, args.done, args.resizeAfter); }, loadFromArgs: function loadFromArgs(args) { var _this2 = this; const $$ = this; // prevent load when chart is already destroyed if (!$$.config) { return; } // reset internally cached data $$.cache.reset(); $$.convertData(args, function (d) { _newArrowCheck(this, _this2); const data = args.data || d; args.append && (data.__append__ = !0); data && $$.load($$.convertDataToTargets(data), args); }.bind(this)); }, unload: function unload(rawTargetIds, customDoneCb) { var _this3 = this; const $$ = this, state = $$.state, $el = $$.$el, $T = $$.$T; let done = customDoneCb, targetIds = rawTargetIds; // reset internally cached data $$.cache.reset(); if (!done) { done = function () { _newArrowCheck(this, _this3); }.bind(this); } // filter existing target targetIds = targetIds.filter(function (id) { _newArrowCheck(this, _this3); return $$.hasTarget($$.data.targets, id); }.bind(this)); // If no target, call done and return if (!targetIds || targetIds.length === 0) { done(); return; } const targets = $el.svg.selectAll(targetIds.map(function (id) { _newArrowCheck(this, _this3); return $$.selectorTarget(id); }.bind(this))); $T(targets).style("opacity", "0").remove().call(endall, done); targetIds.forEach(function (id) { var _this4 = this; _newArrowCheck(this, _this3); // Reset fadein for future load state.withoutFadeIn[id] = !1; // Remove target's elements if ($el.legend) { $el.legend.selectAll("." + $LEGEND.legendItem + $$.getTargetSelectorSuffix(id)).remove(); } // Remove target $$.data.targets = $$.data.targets.filter(function (t) { _newArrowCheck(this, _this4); return t.id !== id; }.bind(this)); }.bind(this)); // since treemap uses different data types, it needs to be transformed state.hasTreemap && $$.updateTargetsForTreemap($$.data.targets); // Update current state chart type and elements list after redraw $$.updateTypesElements(); } }); // EXTERNAL MODULE: external {"commonjs":"d3-drag","commonjs2":"d3-drag","amd":"d3-drag","root":"d3"} var external_commonjs_d3_drag_commonjs2_d3_drag_amd_d3_drag_root_d3_ = __webpack_require__(7); ;// CONCATENATED MODULE: ./src/ChartInternal/interactions/interaction.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var interactions_interaction = ({ /** * Expand data shape/point * @param {number} index Index number * @param {string} id Data id * @param {boolean} reset Reset expand state * @private */ setExpand: function setExpand(index, id, reset) { const $$ = this, config = $$.config, circle = $$.$el.circle; circle && config.point_focus_expand_enabled && $$.expandCircles(index, id, reset); // bar, candlestick $$.expandBarTypeShapes(!0, index, id, reset); }, /** * Expand/Unexpand bar type shapes * @param {boolean} expand Expand or unexpand * @param {number} i Shape index * @param {string} id Data id * @param {boolean} reset Reset expand style * @private */ expandBarTypeShapes: function expandBarTypeShapes(expand, i, id, reset) { var _this = this; if (expand === void 0) { expand = !0; } const $$ = this; ["bar", "candlestick"].filter(function (v) { _newArrowCheck(this, _this); return $$.$el[v]; }.bind(this)).forEach(function (v) { _newArrowCheck(this, _this); reset && $$.$el[v].classed($COMMON.EXPANDED, !1); $$.getShapeByIndex(v, i, id).classed($COMMON.EXPANDED, expand); }.bind(this)); }, /** * Handle data.onover/out callback options * @param {boolean} isOver Over or not * @param {number|object} d data object * @private */ setOverOut: function setOverOut(isOver, d) { var _this3 = this; const $$ = this, config = $$.config, _$$$state = $$.state, hasRadar = _$$$state.hasRadar, hasTreemap = _$$$state.hasTreemap, main = $$.$el.main, isArcTreemap = isObject(d); // Call event handler if (isArcTreemap || d !== -1) { const callback = config[isOver ? "data_onover" : "data_onout"].bind($$.api); config.color_onover && $$.setOverColor(isOver, d, isArcTreemap); if (isArcTreemap && "id") { const selector = hasTreemap ? $TREEMAP.treemap : $ARC.arc; callback(d, main.select("." + selector + $$.getTargetSelectorSuffix(d.id)).node()); } else if (!config.tooltip_grouped) { const last = $$.cache.get(KEY.setOverOut) || [], shapesAtIndex = main.selectAll("." + $SHAPE.shape + "-" + d).filter(function (d) { return $$.isWithinShape(this, d); }), shape = shapesAtIndex.filter(function () { var _this2 = this; return last.every(function (v) { _newArrowCheck(this, _this2); return v !== this; }.bind(this)); }); // select based on the index // filter if has new selection // call onout callback if (!isOver || shapesAtIndex.empty() || last.length === shape.size() && shape.nodes().every(function (v, i) { _newArrowCheck(this, _this3); return v !== last[i]; }.bind(this))) { while (last.length) { const target = last.pop(); config.data_onout.bind($$.api)((0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(target).datum(), target); } } // call onover callback shape.each(function () { if (isOver) { callback((0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this).datum(), this); last.push(this); } }); $$.cache.add(KEY.setOverOut, last); } else { if (isOver) { hasRadar && $$.isPointFocusOnly() ? $$.showCircleFocus($$.getAllValuesOnIndex(d, !0)) : $$.setExpand(d, null, !0); } $$.isMultipleX() || main.selectAll("." + $SHAPE.shape + "-" + d).each(function (d) { callback(d, this); }); } } }, /** * Call data.onover/out callback for touch event * @param {number|object} d target index or data object for Arc type * @private */ callOverOutForTouch: function callOverOutForTouch(d) { const $$ = this, last = $$.cache.get(KEY.callOverOutForTouch); if (isObject(d) && last ? d.id !== last.id : d !== last) { (last || isNumber(last)) && $$.setOverOut(!1, last); (d || isNumber(d)) && $$.setOverOut(!0, d); $$.cache.add(KEY.callOverOutForTouch, d); } }, /** * Return draggable selection function * @returns {Function} * @private */ getDraggableSelection: function getDraggableSelection() { var _this4 = this; const $$ = this, config = $$.config, state = $$.state; return config.interaction_enabled && config.data_selection_draggable && $$.drag ? (0,external_commonjs_d3_drag_commonjs2_d3_drag_amd_d3_drag_root_d3_.drag)().on("drag", function (event) { state.event = event; $$.drag(getPointer(event, this)); }).on("start", function (event) { state.event = event; $$.dragstart(getPointer(event, this)); }).on("end", function (event) { _newArrowCheck(this, _this4); state.event = event; $$.dragend(); }.bind(this)) : function () { _newArrowCheck(this, _this4); }.bind(this); }, /** * Dispatch a mouse event. * @private * @param {string} type event type * @param {number} index Index of eventRect * @param {Array} mouse x and y coordinate value */ dispatchEvent: function dispatchEvent(type, index, mouse) { var _ref; const $$ = this, config = $$.config, _$$$state2 = $$.state, eventReceiver = _$$$state2.eventReceiver, hasAxis = _$$$state2.hasAxis, hasRadar = _$$$state2.hasRadar, hasTreemap = _$$$state2.hasTreemap, _$$$$el = $$.$el, eventRect = _$$$$el.eventRect, radar = _$$$$el.radar, treemap = _$$$$el.treemap, element = (_ref = hasTreemap && eventReceiver.rect || hasRadar && radar.axes.select("." + $AXIS.axis + "-" + index + " text") || eventRect || ($$.getArcElementByIdOrIndex == null ? void 0 : $$.getArcElementByIdOrIndex(index))) == null ? void 0 : _ref.node(); if (element) { const isMultipleX = $$.isMultipleX(), isRotated = config.axis_rotated; let _element$getBoundingC = element.getBoundingClientRect(), width = _element$getBoundingC.width, left = _element$getBoundingC.left, top = _element$getBoundingC.top; if (hasAxis && !hasRadar && !isMultipleX) { const coords = eventReceiver.coords[index]; if (coords) { width = coords.w; left += coords.x; top += coords.y; } else { width = 0; left = 0; top = 0; } } const x = left + (mouse ? mouse[0] : 0) + (isMultipleX || isRotated ? 0 : width / 2), y = top + (mouse ? mouse[1] : 0) + (isRotated ? 4 : 0); // value 4, is to adjust coordinate value set from: scale.ts - updateScales(): $$.getResettedPadding(1) emulateEvent[/^(mouse|click)/.test(type) ? "mouse" : "touch"](hasTreemap ? treemap.node() : element, type, { screenX: x, screenY: y, clientX: x, clientY: y }); } }, setDragStatus: function setDragStatus(isDragging) { this.state.dragging = isDragging; }, /** * Unbind zoom events * @private */ unbindZoomEvent: function unbindZoomEvent() { const $$ = this, _$$$$el2 = $$.$el, eventRect = _$$$$el2.eventRect, zoomResetBtn = _$$$$el2.zoomResetBtn; eventRect == null || eventRect.on(".zoom wheel.zoom .drag", null); zoomResetBtn == null || zoomResetBtn.on("click", null).style("display", "none"); }, /** * Unbind all attached events * @private */ unbindAllEvents: function unbindAllEvents() { var _this5 = this; const $$ = this, _$$$$el3 = $$.$el, arcs = _$$$$el3.arcs, eventRect = _$$$$el3.eventRect, legend = _$$$$el3.legend, region = _$$$$el3.region, svg = _$$$$el3.svg, treemap = _$$$$el3.treemap, brush = $$.brush; // detach all possible event types [svg, eventRect, region == null ? void 0 : region.list, brush == null ? void 0 : brush.getSelection(), arcs == null ? void 0 : arcs.selectAll("path"), legend == null ? void 0 : legend.selectAll("g"), treemap].forEach(function (v) { _newArrowCheck(this, _this5); return v == null ? void 0 : v.on("wheel click mouseover mousemove mouseout touchstart touchmove touchend touchstart.eventRect touchmove.eventRect touchend.eventRect .brush .drag .zoom wheel.zoom dblclick.zoom", null); }.bind(this)); $$.unbindZoomEvent == null || $$.unbindZoomEvent(); } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/class.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var internals_class = ({ generateClass: function generateClass(prefix, targetId) { return " " + prefix + " " + (prefix + this.getTargetSelectorSuffix(targetId)); }, /** * Get class string * @param {string} type Shape type * @param {boolean} withShape Get with shape prefix * @returns {string} Class string * @private */ getClass: function getClass(type, withShape) { var _this = this; const isPlural = /s$/.test(type), useIdKey = /^(area|arc|line|treemap)s?$/.test(type), key = isPlural ? "id" : "index"; return function (d) { _newArrowCheck(this, _this); const data = d.data || d, result = (withShape ? this.generateClass(classes[isPlural ? "shapes" : "shape"], data[key]) : "") + this.generateClass(classes[type], data[useIdKey ? "id" : key]); return result.trim(); }.bind(this); }, /** * Get chart class string * @param {string} type Shape type * @returns {string} Class string * @private */ getChartClass: function getChartClass(type) { var _this2 = this; return function (d) { _newArrowCheck(this, _this2); return classes["chart" + type] + this.classTarget((d.data ? d.data : d).id); }.bind(this); }, generateExtraLineClass: function generateExtraLineClass() { const $$ = this, classes = $$.config.line_classes || [], ids = []; return function (d) { var _d$data; const id = d.id || ((_d$data = d.data) == null ? void 0 : _d$data.id) || d; if (ids.indexOf(id) < 0) { ids.push(id); } return classes[ids.indexOf(id) % classes.length]; }; }, classRegion: function classRegion(d, i) { return this.generateClass(classes.region, i) + " " + ("class" in d ? d.class : ""); }, classTarget: function classTarget(id) { const additionalClassSuffix = this.config.data_classes[id]; let additionalClass = ""; if (additionalClassSuffix) { additionalClass = " " + classes.target + "-" + additionalClassSuffix; } return this.generateClass(classes.target, id) + additionalClass; }, classFocus: function classFocus(d) { return this.classFocused(d) + this.classDefocused(d); }, classFocused: function classFocused(d) { return " " + (this.state.focusedTargetIds.indexOf(d.id) >= 0 ? classes.focused : ""); }, classDefocused: function classDefocused(d) { return " " + (this.state.defocusedTargetIds.indexOf(d.id) >= 0 ? classes.defocused : ""); }, getTargetSelectorSuffix: function getTargetSelectorSuffix(targetId) { const targetStr = targetId || targetId === 0 ? "-" + targetId : ""; return targetStr.replace(/([\s?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\])/g, "-"); }, selectorTarget: function selectorTarget(id, prefix, postfix) { if (prefix === void 0) { prefix = ""; } if (postfix === void 0) { postfix = ""; } const target = this.getTargetSelectorSuffix(id); // select target & circle return prefix + "." + (classes.target + target) + " " + postfix + ", " + prefix + "." + (classes.circles + target) + " " + postfix; }, selectorTargets: function selectorTargets(idsValue, prefix) { var _this3 = this; const ids = idsValue || []; return ids.length ? ids.map(function (id) { _newArrowCheck(this, _this3); return this.selectorTarget(id, prefix); }.bind(this)) : null; }, selectorLegend: function selectorLegend(id) { return "." + (classes.legendItem + this.getTargetSelectorSuffix(id)); }, selectorLegends: function selectorLegends(ids) { var _this4 = this; return ids != null && ids.length ? ids.map(function (id) { _newArrowCheck(this, _this4); return this.selectorLegend(id); }.bind(this)) : null; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/category.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var category = ({ /** * Category Name * @param {number} i Index number * @returns {string} category Name * @private */ categoryName: function categoryName(i) { var _axis_x_categories$i; const axis_x_categories = this.config.axis_x_categories; return (_axis_x_categories$i = axis_x_categories == null ? void 0 : axis_x_categories[i]) != null ? _axis_x_categories$i : i; } }); // EXTERNAL MODULE: external {"commonjs":"d3-scale","commonjs2":"d3-scale","amd":"d3-scale","root":"d3"} var external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_ = __webpack_require__(6); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/color.ts var color_this = undefined; /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Set pattern's background color * (it adds a element to simulate bg-color) * @param {SVGPatternElement} pattern SVG pattern element * @param {string} color Color string * @param {string} id ID to be set * @returns {{id: string, node: SVGPatternElement}} * @private */ const colorizePattern = function (pattern, color, id) { _newArrowCheck(this, color_this); const node = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(pattern.cloneNode(!0)); node.attr("id", id).insert("rect", ":first-child").attr("width", node.attr("width")).attr("height", node.attr("height")).style("fill", color); return { id: id, node: node.node() }; }.bind(undefined); /** * Get color pattern from CSS file * CSS should be defined as: background-image: url("#00c73c;#fa7171; ..."); * @param {d3Selection} element Chart element * @returns {Array} * @private */ function getColorFromCss(element) { var _this2 = this; const cacheKey = KEY.colorPattern, body = browser_doc.body; let pattern = body[cacheKey]; if (!pattern) { const content = element.classed($COLOR.colorPattern, !0).style("background-image"); element.classed($COLOR.colorPattern, !1); if (content.indexOf(";") > -1) { pattern = content.replace(/url[^#]*|["'()]|(\s|%20)/g, "").split(";").map(function (v) { _newArrowCheck(this, _this2); return v.trim().replace(/[\"'\s]/g, ""); }.bind(this)).filter(Boolean); body[cacheKey] = pattern; } } return pattern; } // Replacement of d3.schemeCategory10. // Contained differently depend on d3 version: v4(d3-scale), v5(d3-scale-chromatic) const schemeCategory10 = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"]; /* harmony default export */ var internals_color = ({ generateColor: function generateColor() { var _this3 = this; const $$ = this, $el = $$.$el, config = $$.config, colors = config.data_colors, callback = config.data_color, ids = []; let pattern = notEmpty(config.color_pattern) ? config.color_pattern : (0,external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleOrdinal)(getColorFromCss($el.chart) || schemeCategory10).range(); const originalColorPattern = pattern; if (isFunction(config.color_tiles)) { const tiles = config.color_tiles.bind($$.api)(), colorizedPatterns = pattern.map(function (p, index) { _newArrowCheck(this, _this3); const color = p.replace(/[#\(\)\s,]/g, ""), id = $$.state.datetimeId + "-pattern-" + color + "-" + index; return colorizePattern(tiles[index % tiles.length], p, id); }.bind(this)); // Add background color to patterns pattern = colorizedPatterns.map(function (p) { _newArrowCheck(this, _this3); return "url(#" + p.id + ")"; }.bind(this)); $$.patterns = colorizedPatterns; } return function (d) { var _data; const id = d.id || ((_data = d.data) == null ? void 0 : _data.id) || d, isLine = $$.isTypeOf(id, ["line", "spline", "step"]) || !config.data_types[id]; let color; // if callback function is provided if (isFunction(colors[id])) { color = colors[id].bind($$.api)(d); // if specified, choose that color } else if (colors[id]) { color = colors[id]; // if not specified, choose from pattern } else { if (ids.indexOf(id) < 0) { ids.push(id); } color = isLine ? originalColorPattern[ids.indexOf(id) % originalColorPattern.length] : pattern[ids.indexOf(id) % pattern.length]; colors[id] = color; } return isFunction(callback) ? callback.bind($$.api)(color, d) : color; }; }, generateLevelColor: function generateLevelColor() { const $$ = this, config = $$.config, colors = config.color_pattern, threshold = config.color_threshold, asValue = threshold.unit === "value", max = threshold.max || 100, values = threshold.values && threshold.values.length ? threshold.values : []; return notEmpty(threshold) ? function (value) { const v = asValue ? value : value * 100 / max; let color = colors[colors.length - 1]; for (let i = 0, l = values.length; i < l; i++) { if (v <= values[i]) { color = colors[i]; break; } } return color; } : null; }, /** * Append data backgound color filter definition * @param {string} color Color string * @private */ generateDataLabelBackgroundColorFilter: function generateDataLabelBackgroundColorFilter(color) { var _this4 = this; const $$ = this, $el = $$.$el, config = $$.config, state = $$.state, backgroundColors = color || config.data_labels_backgroundColors; if (backgroundColors) { let ids = []; if (isString(backgroundColors)) { ids.push(""); } else if (isObject(backgroundColors)) { ids = Object.keys(backgroundColors); } ids.forEach(function (v) { _newArrowCheck(this, _this4); const id = state.datetimeId + "-labels-bg" + $$.getTargetSelectorSuffix(v) + (color ? $$.getTargetSelectorSuffix(color) : ""); $el.defs.append("filter").attr("x", "0").attr("y", "0").attr("width", "1").attr("height", "1").attr("id", id).html(""); }.bind(this)); } }, /** * Get data gradient color url * @param {string} id Data id * @returns {string} * @private */ getGradienColortUrl: function getGradienColortUrl(id) { return "url(#" + this.state.datetimeId + "-gradient" + this.getTargetSelectorSuffix(id) + ")"; }, /** * Update linear/radial gradient definition * - linear: area & bar only * - radial: type which has data points only * @private */ updateLinearGradient: function updateLinearGradient() { var _this5 = this; const $$ = this, config = $$.config, targets = $$.data.targets, datetimeId = $$.state.datetimeId, defs = $$.$el.defs; targets.forEach(function (d) { var _this6 = this; _newArrowCheck(this, _this5); const id = datetimeId + "-gradient" + $$.getTargetSelectorSuffix(d.id), radialGradient = $$.hasPointType() && config.point_radialGradient, supportedType = $$.isAreaType(d) && "area" || $$.isBarType(d) && "bar"; if ((radialGradient || supportedType) && defs.select("#" + id).empty()) { const color = $$.color(d), gradient = { defs: null, stops: [] }; if (radialGradient) { const _radialGradient = radialGradient, _radialGradient$cx = _radialGradient.cx, cx = _radialGradient$cx === void 0 ? .3 : _radialGradient$cx, _radialGradient$cy = _radialGradient.cy, cy = _radialGradient$cy === void 0 ? .3 : _radialGradient$cy, _radialGradient$r = _radialGradient.r, r = _radialGradient$r === void 0 ? .7 : _radialGradient$r, _radialGradient$stops = _radialGradient.stops, stops = _radialGradient$stops === void 0 ? [[.1, color, 0], [.9, color, 1]] : _radialGradient$stops; gradient.stops = stops; gradient.defs = defs.append("radialGradient").attr("id", "" + id).attr("cx", cx).attr("cy", cy).attr("r", r); } else { const isRotated = config.axis_rotated, _config = config[supportedType + "_linearGradient"], _config$x = _config.x, x = _config$x === void 0 ? isRotated ? [1, 0] : [0, 0] : _config$x, _config$y = _config.y, y = _config$y === void 0 ? isRotated ? [0, 0] : [0, 1] : _config$y, _config$stops = _config.stops, stops = _config$stops === void 0 ? [[0, color, 1], [1, color, 0]] : _config$stops; gradient.stops = stops; gradient.defs = defs.append("linearGradient").attr("id", "" + id).attr("x1", x[0]).attr("x2", x[1]).attr("y1", y[0]).attr("y2", y[1]); } gradient.stops.forEach(function (v) { _newArrowCheck(this, _this6); const offset = v[0], stopColor = v[1], stopOpacity = v[2], colorValue = isFunction(stopColor) ? stopColor.bind($$.api)(d.id) : stopColor; gradient.defs && gradient.defs.append("stop").attr("offset", offset).attr("stop-color", colorValue || color).attr("stop-opacity", stopOpacity); }.bind(this)); } }.bind(this)); }, /** * Set the data over color. * When is out, will restate in its previous color value * @param {boolean} isOver true: set overed color, false: restore * @param {number|object} d target index or data object for Arc type * @private */ setOverColor: function setOverColor(isOver, d) { var _this7 = this; const $$ = this, config = $$.config, main = $$.$el.main, onover = config.color_onover; let color = isOver ? onover : $$.color; if (isObject(color)) { color = function (_ref) { let id = _ref.id; _newArrowCheck(this, _this7); return id in onover ? onover[id] : $$.color(id); }.bind(this); } else if (isString(color)) { color = function () { _newArrowCheck(this, _this7); return onover; }.bind(this); } else if (isFunction(onover)) { color = color.bind($$.api); } main.selectAll(isObject(d) ? // when is Arc type "." + $ARC.arc + $$.getTargetSelectorSuffix(d.id) : "." + $SHAPE.shape + "-" + d).style("fill", color); } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/domain.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var domain = ({ getYDomainMinMax: function getYDomainMinMax(targets, type) { var _this = this; const $$ = this, axis = $$.axis, config = $$.config, isMin = type === "min", dataGroups = config.data_groups, ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets); if (dataGroups.length > 0) { const hasValue = $$["has" + (isMin ? "Negative" : "Positive") + "ValueInTargets"](targets); dataGroups.forEach(function (groupIds) { var _this2 = this; _newArrowCheck(this, _this); // Determine baseId const idsInGroup = groupIds.filter(function (v) { _newArrowCheck(this, _this2); return ids.indexOf(v) >= 0; }.bind(this)); if (idsInGroup.length) { const baseId = idsInGroup[0], baseAxisId = axis.getId(baseId); // Initialize base value. Set to 0 if not match with the condition if (hasValue && ys[baseId]) { ys[baseId] = ys[baseId].map(function (v) { _newArrowCheck(this, _this2); return (isMin ? v < 0 : v > 0) ? v : 0; }.bind(this)); } idsInGroup.filter(function (v, i) { _newArrowCheck(this, _this2); return i > 0; }.bind(this)).forEach(function (id) { var _this3 = this; _newArrowCheck(this, _this2); if (ys[id]) { const axisId = axis.getId(id); ys[id].forEach(function (v, i) { _newArrowCheck(this, _this3); const val = +v, meetCondition = isMin ? val > 0 : val < 0; if (axisId === baseAxisId && !(hasValue && meetCondition)) { ys[baseId][i] += val; } }.bind(this)); } }.bind(this)); } }.bind(this)); } return getMinMax(type, Object.keys(ys).map(function (key) { _newArrowCheck(this, _this); return getMinMax(type, ys[key]); }.bind(this))); }, /** * Check if hidden targets bound to the given axis id * @param {string} id ID to be checked * @returns {boolean} * @private */ isHiddenTargetWithYDomain: function isHiddenTargetWithYDomain(id) { var _this4 = this; const $$ = this; return $$.state.hiddenTargetIds.some(function (v) { _newArrowCheck(this, _this4); return $$.axis.getId(v) === id; }.bind(this)); }, getYDomain: function getYDomain(targets, axisId, xDomain) { var _this5 = this; const $$ = this, axis = $$.axis, config = $$.config, scale = $$.scale, pfx = "axis_" + axisId; if ($$.isStackNormalized()) { return [0, 100]; } const isLog = (scale == null ? void 0 : scale[axisId]) && scale[axisId].type === "log", targetsByAxisId = targets.filter(function (t) { _newArrowCheck(this, _this5); return axis.getId(t.id) === axisId; }.bind(this)), yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId; if (yTargets.length === 0) { // use domain of the other axis if target of axisId is none if ($$.isHiddenTargetWithYDomain(axisId)) { return scale[axisId].domain(); } else { return axisId === "y2" ? scale.y.domain() : // When all data bounds to y2, y Axis domain is called prior y2. // So, it needs to call to get y2 domain here $$.getYDomain(targets, "y2", xDomain); } } const yMin = config[pfx + "_min"], yMax = config[pfx + "_max"], center = config[pfx + "_center"], isInverted = config[pfx + "_inverted"], showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; let yDomainMin = $$.getYDomainMinMax(yTargets, "min"), yDomainMax = $$.getYDomainMinMax(yTargets, "max"), isZeroBased = [TYPE.BAR, TYPE.BUBBLE, TYPE.SCATTER].concat(TYPE_BY_CATEGORY.Line).some(function (v) { _newArrowCheck(this, _this5); const type = v.indexOf("area") > -1 ? "area" : v; return $$.hasType(v, yTargets, !0) && config[type + "_zerobased"]; }.bind(this)); // MEMO: avoid inverting domain unexpectedly yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? yDomainMin <= yMax ? yDomainMin : yMax - 10 : yDomainMin; yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? yMin <= yDomainMax ? yDomainMax : yMin + 10 : yDomainMax; if (isNaN(yDomainMin)) { // set minimum to zero when not number yDomainMin = 0; } if (isNaN(yDomainMax)) { // set maximum to have same value as yDomainMin yDomainMax = yDomainMin; } if (yDomainMin === yDomainMax) { yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0; } const isAllPositive = yDomainMin >= 0 && yDomainMax >= 0, isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; // Cancel zerobased if axis_*_min / axis_*_max specified if (isValue(yMin) && isAllPositive || isValue(yMax) && isAllNegative) { isZeroBased = !1; } // Bar/Area chart should be 0-based if all positive|negative if (isZeroBased) { isAllPositive && (yDomainMin = 0); isAllNegative && (yDomainMax = 0); } const domainLength = Math.abs(yDomainMax - yDomainMin); let padding = { top: domainLength * .1, bottom: domainLength * .1 }; if (isDefined(center)) { const yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); yDomainMax = center + yDomainAbs; yDomainMin = center - yDomainAbs; } // add padding for data label if (showHorizontalDataLabel) { const diff = diffDomain(scale.y.range()), ratio = $$.getDataLabelLength(yDomainMin, yDomainMax, "width").map(function (v) { _newArrowCheck(this, _this5); return v / diff; }.bind(this)); ["bottom", "top"].forEach(function (v, i) { _newArrowCheck(this, _this5); padding[v] += domainLength * (ratio[i] / (1 - ratio[0] - ratio[1])); }.bind(this)); } else if (showVerticalDataLabel) { const lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, "height"); ["bottom", "top"].forEach(function (v, i) { _newArrowCheck(this, _this5); padding[v] += $$.convertPixelToScale("y", lengths[i], domainLength); }.bind(this)); } padding = $$.getResettedPadding(padding); // if padding is set, the domain will be updated relative the current domain value // ex) $$.height=300, padding.top=150, domainLength=4 --> domain=6 const p = config[pfx + "_padding"]; if (notEmpty(p)) { ["bottom", "top"].forEach(function (v) { _newArrowCheck(this, _this5); padding[v] = axis.getPadding(p, v, padding[v], domainLength); }.bind(this)); } // Bar/Area chart should be 0-based if all positive|negative if (isZeroBased) { isAllPositive && (padding.bottom = yDomainMin); isAllNegative && (padding.top = -yDomainMax); } const domain = isLog ? [yDomainMin, yDomainMax].map(function (v) { _newArrowCheck(this, _this5); return v < 0 ? 0 : v; }.bind(this)) : [yDomainMin - padding.bottom, yDomainMax + padding.top]; return isInverted ? domain.reverse() : domain; }, getXDomainMinMax: function getXDomainMinMax(targets, type) { var _this6 = this, _$$$axis; const $$ = this, configValue = $$.config["axis_x_" + type], dataValue = getMinMax(type, targets.map(function (t) { var _this7 = this; _newArrowCheck(this, _this6); return getMinMax(type, t.values.map(function (v) { _newArrowCheck(this, _this7); return v.x; }.bind(this))); }.bind(this))); let value = isObject(configValue) ? configValue.value : configValue; value = isDefined(value) && (_$$$axis = $$.axis) != null && _$$$axis.isTimeSeries() ? parseDate.bind(this)(value) : value; if (isObject(configValue) && configValue.fit && (type === "min" && value < dataValue || type === "max" && value > dataValue)) { value = undefined; } return isDefined(value) ? value : dataValue; }, /** * Get x Axis padding * @param {Array} domain x Axis domain * @param {number} tickCount Tick count * @returns {object} Padding object values with 'left' & 'right' key * @private */ getXDomainPadding: function getXDomainPadding(domain, tickCount) { const $$ = this, axis = $$.axis, config = $$.config, padding = config.axis_x_padding, isTimeSeriesTickCount = axis.isTimeSeries() && tickCount, diff = diffDomain(domain); let defaultValue; // determine default padding value if (axis.isCategorized() || isTimeSeriesTickCount) { defaultValue = 0; } else if ($$.hasType("bar")) { const maxDataCount = $$.getMaxDataCount(); defaultValue = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : .5; } else { defaultValue = $$.getResettedPadding(diff * .01); } let _ref = isNumber(padding) ? { left: padding, right: padding } : padding, _ref$left = _ref.left, left = _ref$left === void 0 ? defaultValue : _ref$left, _ref$right = _ref.right, right = _ref$right === void 0 ? defaultValue : _ref$right; // when the unit is pixel, convert pixels to axis scale value if (padding.unit === "px") { const domainLength = Math.abs(diff + diff * .2); left = axis.getPadding(padding, "left", defaultValue, domainLength); right = axis.getPadding(padding, "right", defaultValue, domainLength); } else { const range = diff + left + right; if (isTimeSeriesTickCount && range) { const relativeTickWidth = diff / tickCount / range; left = left / range / relativeTickWidth; right = right / range / relativeTickWidth; } } return { left: left, right: right }; }, /** * Get x Axis domain * @param {Array} targets targets * @returns {Array} x Axis domain * @private */ getXDomain: function getXDomain(targets) { const $$ = this, axis = $$.axis, config = $$.config, x = $$.scale.x, isInverted = config.axis_x_inverted, domain = [$$.getXDomainMinMax(targets, "min"), $$.getXDomainMinMax(targets, "max")]; let _domain$ = domain[0], min = _domain$ === void 0 ? 0 : _domain$, _domain$2 = domain[1], max = _domain$2 === void 0 ? 0 : _domain$2; if (x.type !== "log") { const isCategorized = axis.isCategorized(), isTimeSeries = axis.isTimeSeries(), padding = $$.getXDomainPadding(domain); let firstX = domain[0], lastX = domain[1]; // show center of x domain if min and max are the same if (firstX - lastX === 0 && !isCategorized) { if (isTimeSeries) { firstX = new Date(firstX.getTime() * .5); lastX = new Date(lastX.getTime() * 1.5); } else { firstX = firstX === 0 ? 1 : firstX * .5; lastX = lastX === 0 ? -1 : lastX * 1.5; } } if (firstX || firstX === 0) { min = isTimeSeries ? new Date(firstX.getTime() - padding.left) : firstX - padding.left; } if (lastX || lastX === 0) { max = isTimeSeries ? new Date(lastX.getTime() + padding.right) : lastX + padding.right; } } return isInverted ? [max, min] : [min, max]; }, updateXDomain: function updateXDomain(targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) { const $$ = this, config = $$.config, org = $$.org, _$$$scale = $$.scale, x = _$$$scale.x, subX = _$$$scale.subX, zoomEnabled = config.zoom_enabled; if (withUpdateOrgXDomain) { var _$$$brush; x.domain(domain || sortValue($$.getXDomain(targets), !config.axis_x_inverted)); org.xDomain = x.domain(); // zoomEnabled && $$.zoom.updateScaleExtent(); subX.domain(x.domain()); (_$$$brush = $$.brush) == null || _$$$brush.scale(subX); } if (withUpdateXDomain) { const domainValue = domain || !$$.brush || brushEmpty($$) ? org.xDomain : getBrushSelection($$).map(subX.invert); x.domain(domainValue); // zoomEnabled && $$.zoom.updateScaleExtent(); } if (withUpdateOrgXDomain || withUpdateXDomain) { zoomEnabled && $$.zoom.updateScaleExtent(); } // Trim domain when too big by zoom mousemove event withTrim && x.domain($$.trimXDomain(x.orgDomain())); return x.domain(); }, /** * Trim x domain when given domain surpasses the range * @param {Array} domain Domain value * @returns {Array} Trimed domain if given domain is out of range * @private */ trimXDomain: function trimXDomain(domain) { const $$ = this, isInverted = $$.config.axis_x_inverted, zoomDomain = $$.getZoomDomain(), _zoomDomain = zoomDomain, min = _zoomDomain[0], max = _zoomDomain[1]; if (isInverted ? domain[0] >= min : domain[0] <= min) { domain[1] = +domain[1] + (min - domain[0]); domain[0] = min; } if (isInverted ? domain[1] <= max : domain[1] >= max) { domain[0] = +domain[0] - (domain[1] - max); domain[1] = max; } return domain; }, /** * Get subchart/zoom domain * @param {string} type "subX" or "zoom" * @param {boolean} getCurrent Get current domain if true * @returns {Array} zoom domain * @private */ getZoomDomain: function getZoomDomain(type, getCurrent) { if (type === void 0) { type = "zoom"; } if (getCurrent === void 0) { getCurrent = !1; } const $$ = this, config = $$.config, scale = $$.scale, org = $$.org; let _ref2 = getCurrent && scale[type] ? scale[type].domain() : org.xDomain, min = _ref2[0], max = _ref2[1]; if (type === "zoom") { if (isDefined(config.zoom_x_min)) { min = getMinMax("min", [min, config.zoom_x_min]); } if (isDefined(config.zoom_x_max)) { max = getMinMax("max", [max, config.zoom_x_max]); } } return [min, max]; }, /** * Converts pixels to axis' scale values * @param {string} type Axis type * @param {number} pixels Pixels * @param {number} domainLength Domain length * @returns {number} * @private */ convertPixelToScale: function convertPixelToScale(type, pixels, domainLength) { const $$ = this, config = $$.config, state = $$.state, isRotated = config.axis_rotated; let length; if (type === "x") { length = isRotated ? "height" : "width"; } else { length = isRotated ? "width" : "height"; } return domainLength * (pixels / state[length]); }, /** * Check if the given domain is within subchart/zoom range * @param {Array} domain Target domain value * @param {Array} current Current subchart/zoom domain value * @param {Array} range subchart/zoom range value * @returns {boolean} * @private */ withinRange: function withinRange(domain, current, range) { var _this8 = this; const $$ = this, isInverted = $$.config.axis_x_inverted, _ref3 = range, min = _ref3[0], max = _ref3[1]; if (Array.isArray(domain)) { const target = [].concat(domain); isInverted && target.reverse(); if (target[0] < target[1]) { return domain.every(function (v, i) { var _this9 = this; _newArrowCheck(this, _this8); return (i === 0 ? isInverted ? +v <= min : +v >= min : isInverted ? +v >= max : +v <= max) && !domain.every(function (v, i) { _newArrowCheck(this, _this9); return v === current[i]; }.bind(this)); }.bind(this)); } } return !1; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/format.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get formatted * @param {object} $$ Context * @param {string} typeValue Axis type * @param {number} v Value to be formatted * @returns {number | string} * @private */ function getFormat($$, typeValue, v) { const config = $$.config, type = "axis_" + typeValue + "_tick_format", format = config[type] ? config[type] : $$.defaultValueFormat; return format.call($$.api, v); } /* harmony default export */ var format = ({ yFormat: function yFormat(v) { return getFormat(this, "y", v); }, y2Format: function y2Format(v) { return getFormat(this, "y2", v); }, /** * Get default value format function * @returns {Function} formatter function * @private */ getDefaultValueFormat: function getDefaultValueFormat() { const $$ = this, defaultArcValueFormat = $$.defaultArcValueFormat, yFormat = $$.yFormat, y2Format = $$.y2Format, hasArc = $$.hasArcType(null, ["gauge", "polar", "radar"]); return function (v, ratio, id) { const format = hasArc ? defaultArcValueFormat : $$.axis && $$.axis.getId(id) === "y2" ? y2Format : yFormat; return format.call($$, v, ratio); }; }, defaultValueFormat: function defaultValueFormat(v) { return isArray(v) ? v.join("~") : isValue(v) ? +v : ""; }, defaultArcValueFormat: function defaultArcValueFormat(v, ratio) { return (ratio * 100).toFixed(1) + "%"; }, defaultPolarValueFormat: function defaultPolarValueFormat(v) { return "" + v; }, dataLabelFormat: function dataLabelFormat(targetId) { var _this = this; const $$ = this, dataLabels = $$.config.data_labels, defaultFormat = function (v) { _newArrowCheck(this, _this); const delimiter = "~"; let res = v; if (isArray(v)) { res = v.join(delimiter); } else if (isObject(v)) { res = Object.values(v).join(delimiter); } return res; }.bind(this); let format = defaultFormat; // find format according to axis id if (isFunction(dataLabels.format)) { format = dataLabels.format; } else if (isObjectType(dataLabels.format)) { if (dataLabels.format[targetId]) { format = dataLabels.format[targetId] === !0 ? defaultFormat : dataLabels.format[targetId]; } else { format = function () { _newArrowCheck(this, _this); return ""; }.bind(this); } } return format.bind($$.api); } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/legend.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get color string for given data id * @param {string} id Data id * @returns {string} Color string * @private */ function getLegendColor(id) { const $$ = this, data = $$.getDataById(id), color = $$.levelColor ? $$.levelColor(data.values[0].value) : $$.color(data); return color; } /* harmony default export */ var internals_legend = ({ /** * Initialize the legend. * @private */ initLegend: function initLegend() { const $$ = this, config = $$.config, $el = $$.$el; $$.legendItemTextBox = {}; $$.state.legendHasRendered = !1; if (config.legend_show) { if (!config.legend_contents_bindto) { $el.legend = $$.$el.svg.append("g").classed($LEGEND.legend, !0).attr("transform", $$.getTranslate("legend")); } // MEMO: call here to update legend box and translate for all // MEMO: translate will be updated by this, so transform not needed in updateLegend() $$.updateLegend(); } else { $$.state.hiddenLegendIds = $$.mapToIds($$.data.targets); } }, /** * Update legend element * @param {Array} targetIds ID's of target * @param {object} options withTransform : Whether to use the transform property / withTransitionForTransform: Whether transition is used when using the transform property / withTransition : whether or not to transition. * @param {object} transitions Return value of the generateTransitions * @private */ updateLegend: function updateLegend(targetIds, options, transitions) { var _$el$legend; const $$ = this, config = $$.config, state = $$.state, scale = $$.scale, $el = $$.$el, optionz = options || { withTransform: !1, withTransitionForTransform: !1, withTransition: !1 }; optionz.withTransition = getOption(optionz, "withTransition", !0); optionz.withTransitionForTransform = getOption(optionz, "withTransitionForTransform", !0); if (config.legend_contents_bindto && config.legend_contents_template) { $$.updateLegendTemplate(); } else if (!state.hasTreemap) { $$.updateLegendElement(targetIds || $$.mapToIds($$.data.targets), optionz, transitions); } // toggle legend state (_$el$legend = $el.legend) == null || _$el$legend.selectAll("." + $LEGEND.legendItem).classed($LEGEND.legendItemHidden, function (id) { const hide = !$$.isTargetToShow(id); if (hide) { this.style.opacity = null; } return hide; }); // Update size and scale $$.updateScales(!1, !scale.zoom); $$.updateSvgSize(); // Update g positions $$.transformAll(optionz.withTransitionForTransform, transitions); state.legendHasRendered = !0; }, /** * Update legend using template option * @private */ updateLegendTemplate: function updateLegendTemplate() { var _this = this; const $$ = this, config = $$.config, $el = $$.$el, wrapper = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(config.legend_contents_bindto), template = config.legend_contents_template; if (!wrapper.empty()) { const targets = $$.mapToIds($$.data.targets), ids = []; let html = ""; targets.forEach(function (v) { _newArrowCheck(this, _this); const content = isFunction(template) ? template.bind($$.api)(v, $$.color(v), $$.api.data(v)[0].values) : tplProcess(template, { COLOR: $$.color(v), TITLE: v }); if (content) { ids.push(v); html += content; } }.bind(this)); const legendItem = wrapper.html(html).selectAll(function () { return this.childNodes; }).data(ids); $$.setLegendItem(legendItem); $el.legend = wrapper; } }, /** * Update the size of the legend. * @param {Obejct} size Size object * @private */ updateSizeForLegend: function updateSizeForLegend(size) { const $$ = this, config = $$.config, _$$$state = $$.state, isLegendTop = _$$$state.isLegendTop, isLegendLeft = _$$$state.isLegendLeft, isLegendRight = _$$$state.isLegendRight, isLegendInset = _$$$state.isLegendInset, current = _$$$state.current, width = size.width, height = size.height, insetLegendPosition = { top: isLegendTop ? $$.getCurrentPaddingByDirection("top") + config.legend_inset_y + 5.5 : current.height - height - $$.getCurrentPaddingByDirection("bottom") - config.legend_inset_y, left: isLegendLeft ? $$.getCurrentPaddingByDirection("left") + config.legend_inset_x + .5 : current.width - width - $$.getCurrentPaddingByDirection("right") - config.legend_inset_x + .5 }; $$.state.margin3 = { top: isLegendRight ? 0 : isLegendInset ? insetLegendPosition.top : current.height - height, right: NaN, bottom: 0, left: isLegendRight ? current.width - width : isLegendInset ? insetLegendPosition.left : 0 }; }, /** * Transform Legend * @param {boolean} withTransition whether or not to transition. * @private */ transformLegend: function transformLegend(withTransition) { const $$ = this, legend = $$.$el.legend, $T = $$.$T; $T(legend, withTransition).attr("transform", $$.getTranslate("legend")); }, /** * Update the legend step * @param {number} step Step value * @private */ updateLegendStep: function updateLegendStep(step) { this.state.legendStep = step; }, /** * Update legend item width * @param {number} width Width value * @private */ updateLegendItemWidth: function updateLegendItemWidth(width) { this.state.legendItemWidth = width; }, /** * Update legend item height * @param {number} height Height value * @private */ updateLegendItemHeight: function updateLegendItemHeight(height) { this.state.legendItemHeight = height; }, /** * Update legend item color * @param {string} id Corresponding data ID value * @param {string} color Color value * @private */ updateLegendItemColor: function updateLegendItemColor(id, color) { const legend = this.$el.legend; if (legend) { legend.select("." + $LEGEND.legendItem + "-" + id + " line").style("stroke", color); } }, /** * Get the width of the legend * @returns {number} width * @private */ getLegendWidth: function getLegendWidth() { const $$ = this, _$$$state2 = $$.state, width = _$$$state2.current.width, isLegendRight = _$$$state2.isLegendRight, isLegendInset = _$$$state2.isLegendInset, legendItemWidth = _$$$state2.legendItemWidth, legendStep = _$$$state2.legendStep; return $$.config.legend_show ? isLegendRight || isLegendInset ? legendItemWidth * (legendStep + 1) : width : 0; }, /** * Get the height of the legend * @returns {number} height * @private */ getLegendHeight: function getLegendHeight() { var _$$$config$padding; const $$ = this, _$$$state3 = $$.state, current = _$$$state3.current, isLegendRight = _$$$state3.isLegendRight, legendItemHeight = _$$$state3.legendItemHeight, legendStep = _$$$state3.legendStep, isFitPadding = ((_$$$config$padding = $$.config.padding) == null ? void 0 : _$$$config$padding.mode) === "fit"; return $$.config.legend_show ? isLegendRight ? current.height : (isFitPadding ? 10 : Math.max(20, legendItemHeight)) * (legendStep + 1) : 0; }, /** * Get the opacity of the legend that is unfocused * @param {d3.selection} legendItem Legend item node * @returns {string|null} opacity * @private */ opacityForUnfocusedLegend: function opacityForUnfocusedLegend(legendItem) { return legendItem.classed($LEGEND.legendItemHidden) ? null : "0.3"; }, /** * Toggles the focus of the legend * @param {Array} targetIds ID's of target * @param {boolean} focus whether or not to focus. * @private */ toggleFocusLegend: function toggleFocusLegend(targetIds, focus) { var _this2 = this; const $$ = this, legend = $$.$el.legend, $T = $$.$T, targetIdz = $$.mapToTargetIds(targetIds); legend && $T(legend.selectAll("." + $LEGEND.legendItem).filter(function (id) { _newArrowCheck(this, _this2); return targetIdz.indexOf(id) >= 0; }.bind(this)).classed($FOCUS.legendItemFocused, focus)).style("opacity", function () { return focus ? null : $$.opacityForUnfocusedLegend.call($$, (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this)); }); }, /** * Revert the legend to its default state * @private */ revertLegend: function revertLegend() { const $$ = this, legend = $$.$el.legend, $T = $$.$T; legend && $T(legend.selectAll("." + $LEGEND.legendItem).classed($FOCUS.legendItemFocused, !1)).style("opacity", null); }, /** * Shows the legend * @param {Array} targetIds ID's of target * @private */ showLegend: function showLegend(targetIds) { const $$ = this, config = $$.config, $el = $$.$el, $T = $$.$T; if (!config.legend_show) { config.legend_show = !0; $el.legend ? $el.legend.style("visibility", null) : $$.initLegend(); $$.state.legendHasRendered || $$.updateLegend(); } $$.removeHiddenLegendIds(targetIds); $T($el.legend.selectAll($$.selectorLegends(targetIds)).style("visibility", null)).style("opacity", null); }, /** * Hide the legend * @param {Array} targetIds ID's of target * @private */ hideLegend: function hideLegend(targetIds) { const $$ = this, config = $$.config, legend = $$.$el.legend; if (config.legend_show && isEmpty(targetIds)) { config.legend_show = !1; legend.style("visibility", "hidden"); } $$.addHiddenLegendIds(targetIds); legend.selectAll($$.selectorLegends(targetIds)).style("opacity", "0").style("visibility", "hidden"); }, /** * Get legend item textbox dimension * @param {string} id Data ID * @param {HTMLElement|d3.selection} textElement Text node element * @returns {object} Bounding rect * @private */ getLegendItemTextBox: function getLegendItemTextBox(id, textElement) { const $$ = this, cache = $$.cache, state = $$.state; let data; // do not prefix w/'$', to not be resetted cache in .load() call const cacheKey = KEY.legendItemTextBox; if (id) { data = !state.redrawing && cache.get(cacheKey) || {}; if (!data[id]) { data[id] = $$.getTextRect(textElement, $LEGEND.legendItem); cache.add(cacheKey, data); } data = data[id]; } return data; }, /** * Set legend item style & bind events * @param {d3.selection} item Item node * @private */ setLegendItem: function setLegendItem(item) { var _this3 = this; const $$ = this, $el = $$.$el, api = $$.api, config = $$.config, state = $$.state, isTouch = state.inputType === "touch", hasGauge = $$.hasType("gauge"), useCssRule = config.boost_useCssRule, interaction = config.legend_item_interaction; item.attr("class", function (id) { const node = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this), itemClass = !node.empty() && node.attr("class") || ""; return itemClass + $$.generateClass($LEGEND.legendItem, id); }).style("visibility", function (id) { _newArrowCheck(this, _this3); return $$.isLegendToShow(id) ? null : "hidden"; }.bind(this)); if (config.interaction_enabled) { if (useCssRule) { [["." + $LEGEND.legendItem, "cursor:pointer"], ["." + $LEGEND.legendItem + " text", "pointer-events:none"], ["." + $LEGEND.legendItemPoint + " text", "pointer-events:none"], ["." + $LEGEND.legendItemTile, "pointer-events:none"], ["." + $LEGEND.legendItemEvent, "fill-opacity:0"]].forEach(function (v) { _newArrowCheck(this, _this3); const selector = v[0], props = v[1]; $$.setCssRule(!1, selector, [props])($el.legend); }.bind(this)); } item.on(interaction.dblclick ? "dblclick" : "click", interaction || isFunction(config.legend_item_onclick) ? function (event, id) { if (!callFn(config.legend_item_onclick, api, id)) { const altKey = event.altKey, target = event.target, type = event.type; if (type === "dblclick" || altKey) { // when focused legend is clicked(with altKey or double clicked), reset all hiding. if (state.hiddenTargetIds.length && target.parentNode.getAttribute("class").indexOf($LEGEND.legendItemHidden) === -1) { api.show(); } else { api.hide(); api.show(id); } } else { api.toggle(id); (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this).classed($FOCUS.legendItemFocused, !1); } } isTouch && $$.hideTooltip(); } : null); isTouch || item.on("mouseout", interaction || isFunction(config.legend_item_onout) ? function (event, id) { if (!callFn(config.legend_item_onout, api, id)) { (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this).classed($FOCUS.legendItemFocused, !1); if (hasGauge) { $$.undoMarkOverlapped($$, "." + $GAUGE.gaugeValue); } $$.api.revert(); } } : null).on("mouseover", interaction || isFunction(config.legend_item_onover) ? function (event, id) { if (!callFn(config.legend_item_onover, api, id)) { (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this).classed($FOCUS.legendItemFocused, !0); if (hasGauge) { $$.markOverlapped(id, $$, "." + $GAUGE.gaugeValue); } if (!state.transiting && $$.isTargetToShow(id)) { api.focus(id); } } } : null); // set cursor when has some interaction !item.empty() && item.on("click mouseout mouseover") && item.style("cursor", $$.getStylePropValue("pointer")); } }, /** * Update the legend * @param {Array} targetIds ID's of target * @param {object} options withTransform : Whether to use the transform property / withTransitionForTransform: Whether transition is used when using the transform property / withTransition : whether or not to transition. * @private */ updateLegendElement: function updateLegendElement(targetIds, options) { var _this4 = this; const $$ = this, config = $$.config, state = $$.state, legend = $$.$el.legend, $T = $$.$T, legendType = config.legend_item_tile_type, isRectangle = legendType !== "circle", legendItemR = config.legend_item_tile_r, itemTileSize = { width: isRectangle ? config.legend_item_tile_width : legendItemR * 2, height: isRectangle ? config.legend_item_tile_height : legendItemR * 2 }, dimension = { padding: { top: 4, right: 10 }, max: { width: 0, height: 0 }, posMin: 10, step: 0, tileWidth: itemTileSize.width + 5, totalLength: 0 }, sizes = { offsets: {}, widths: {}, heights: {}, margins: [0], steps: {} }; let xForLegend, yForLegend, background; // Skip elements when their name is set to null const targetIdz = targetIds.filter(function (id) { _newArrowCheck(this, _this4); return !isDefined(config.data_names[id]) || config.data_names[id] !== null; }.bind(this)), withTransition = options.withTransition, updatePositions = $$.getUpdateLegendPositions(targetIdz, dimension, sizes); if (state.isLegendInset) { dimension.step = config.legend_inset_step ? config.legend_inset_step : targetIdz.length; $$.updateLegendStep(dimension.step); } if (state.isLegendRight) { xForLegend = function (id) { _newArrowCheck(this, _this4); return dimension.max.width * sizes.steps[id]; }.bind(this); yForLegend = function (id) { _newArrowCheck(this, _this4); return sizes.margins[sizes.steps[id]] + sizes.offsets[id]; }.bind(this); } else if (state.isLegendInset) { xForLegend = function (id) { _newArrowCheck(this, _this4); return dimension.max.width * sizes.steps[id] + 10; }.bind(this); yForLegend = function (id) { _newArrowCheck(this, _this4); return sizes.margins[sizes.steps[id]] + sizes.offsets[id]; }.bind(this); } else { xForLegend = function (id) { _newArrowCheck(this, _this4); return sizes.margins[sizes.steps[id]] + sizes.offsets[id]; }.bind(this); yForLegend = function (id) { _newArrowCheck(this, _this4); return dimension.max.height * sizes.steps[id]; }.bind(this); } const posFn = { xText: function xText(id, i) { _newArrowCheck(this, _this4); return xForLegend(id, i) + 4 + itemTileSize.width; }.bind(this), xRect: function xRect(id, i) { _newArrowCheck(this, _this4); return xForLegend(id, i); }.bind(this), x1Tile: function x1Tile(id, i) { _newArrowCheck(this, _this4); return xForLegend(id, i) - 2; }.bind(this), x2Tile: function x2Tile(id, i) { _newArrowCheck(this, _this4); return xForLegend(id, i) - 2 + itemTileSize.width; }.bind(this), yText: function yText(id, i) { _newArrowCheck(this, _this4); return yForLegend(id, i) + 9; }.bind(this), yRect: function yRect(id, i) { _newArrowCheck(this, _this4); return yForLegend(id, i) - 5; }.bind(this), yTile: function yTile(id, i) { _newArrowCheck(this, _this4); return yForLegend(id, i) + 4; }.bind(this) }; $$.generateLegendItem(targetIdz, itemTileSize, updatePositions, posFn); // Set background for inset legend background = legend.select("." + $LEGEND.legendBackground + " rect"); if (state.isLegendInset && dimension.max.width > 0 && background.size() === 0) { background = legend.insert("g", "." + $LEGEND.legendItem).attr("class", $LEGEND.legendBackground).append("rect"); } const texts = legend.selectAll("text").data(targetIdz).text(function (id) { _newArrowCheck(this, _this4); return isDefined(config.data_names[id]) ? config.data_names[id] : id; }.bind(this)) // MEMO: needed for update .each(function (id, i) { updatePositions(this, id, i); }); $T(texts, withTransition).attr("x", posFn.xText).attr("y", posFn.yText); const rects = legend.selectAll("rect." + $LEGEND.legendItemEvent).data(targetIdz); $T(rects, withTransition).attr("width", function (id) { _newArrowCheck(this, _this4); return sizes.widths[id]; }.bind(this)).attr("height", function (id) { _newArrowCheck(this, _this4); return sizes.heights[id]; }.bind(this)).attr("x", posFn.xRect).attr("y", posFn.yRect); // update legend items position $$.updateLegendItemPos(targetIdz, withTransition, posFn); if (background) { $T(background, withTransition).attr("height", $$.getLegendHeight() - 12).attr("width", dimension.max.width * (dimension.step + 1) + 10); } // Update all to reflect change of legend $$.updateLegendItemWidth(dimension.max.width); $$.updateLegendItemHeight(dimension.max.height); $$.updateLegendStep(dimension.step); }, /** * Get position update function * @param {Array} targetIdz Data ids * @param {object} dimension Dimension object * @param {object} sizes Size object * @returns {Function} Update position function * @private */ getUpdateLegendPositions: function getUpdateLegendPositions(targetIdz, dimension, sizes) { const $$ = this, config = $$.config, state = $$.state, isLegendRightOrInset = state.isLegendRight || state.isLegendInset; return function (textElement, id, index) { var _this5 = this; const isLast = index === targetIdz.length - 1, box = $$.getLegendItemTextBox(id, textElement), itemWidth = box.width + dimension.tileWidth + (isLast && !isLegendRightOrInset ? 0 : dimension.padding.right) + config.legend_padding, itemHeight = box.height + dimension.padding.top, itemLength = isLegendRightOrInset ? itemHeight : itemWidth, areaLength = isLegendRightOrInset ? $$.getLegendHeight() : $$.getLegendWidth(); let margin; // MEMO: care about condifion of step, totalLength const updateValues = function (id2, withoutStep) { if (!withoutStep) { margin = (areaLength - dimension.totalLength - itemLength) / 2; if (margin < dimension.posMin) { margin = (areaLength - itemLength) / 2; dimension.totalLength = 0; dimension.step++; } } sizes.steps[id2] = dimension.step; sizes.margins[dimension.step] = state.isLegendInset ? 10 : margin; sizes.offsets[id2] = dimension.totalLength; dimension.totalLength += itemLength; }; if (index === 0) { dimension.totalLength = 0; dimension.step = 0; dimension.max.width = 0; dimension.max.height = 0; } if (config.legend_show && !$$.isLegendToShow(id)) { sizes.widths[id] = 0; sizes.heights[id] = 0; sizes.steps[id] = 0; sizes.offsets[id] = 0; return; } sizes.widths[id] = itemWidth; sizes.heights[id] = itemHeight; if (!dimension.max.width || itemWidth >= dimension.max.width) { dimension.max.width = itemWidth; } if (!dimension.max.height || itemHeight >= dimension.max.height) { dimension.max.height = itemHeight; } const maxLength = isLegendRightOrInset ? dimension.max.height : dimension.max.width; if (config.legend_equally) { Object.keys(sizes.widths).forEach(function (id2) { _newArrowCheck(this, _this5); return sizes.widths[id2] = dimension.max.width; }.bind(this)); Object.keys(sizes.heights).forEach(function (id2) { _newArrowCheck(this, _this5); return sizes.heights[id2] = dimension.max.height; }.bind(this)); margin = (areaLength - maxLength * targetIdz.length) / 2; if (margin < dimension.posMin) { dimension.totalLength = 0; dimension.step = 0; targetIdz.forEach(function (id2) { _newArrowCheck(this, _this5); return updateValues(id2); }.bind(this)); } else { updateValues(id, !0); } } else { updateValues(id); } }; }, /** * Generate legend item elements * @param {Array} targetIdz Data ids * @param {object} itemTileSize Item tile size {width, height} * @param {Function} updatePositions Update position function * @param {object} posFn Position functions * @private */ generateLegendItem: function generateLegendItem(targetIdz, itemTileSize, updatePositions, posFn) { var _this6 = this; const $$ = this, config = $$.config, state = $$.state, legend = $$.$el.legend, usePoint = config.legend_usePoint, legendItemR = config.legend_item_tile_r, legendType = config.legend_item_tile_type, isRectangle = legendType !== "circle", isLegendRightOrInset = state.isLegendRight || state.isLegendInset, pos = -200, l = legend.selectAll("." + $LEGEND.legendItem).data(targetIdz).enter().append("g"); // Define g for legend area $$.setLegendItem(l); l.append("text").text(function (id) { _newArrowCheck(this, _this6); return isDefined(config.data_names[id]) ? config.data_names[id] : id; }.bind(this)).each(function (id, i) { updatePositions(this, id, i); }).style("pointer-events", $$.getStylePropValue("none")).attr("x", isLegendRightOrInset ? posFn.xText : -200).attr("y", isLegendRightOrInset ? -200 : posFn.yText); l.append("rect").attr("class", $LEGEND.legendItemEvent).style("fill-opacity", $$.getStylePropValue("0")).attr("x", isLegendRightOrInset ? posFn.xRect : -200).attr("y", isLegendRightOrInset ? -200 : posFn.yRect); if (usePoint) { const ids = []; l.append(function (d) { _newArrowCheck(this, _this6); const pattern = notEmpty(config.point_pattern) ? config.point_pattern : [config.point_type]; ids.indexOf(d) === -1 && ids.push(d); let point = pattern[ids.indexOf(d) % pattern.length]; if (point === "rectangle") { point = "rect"; } return browser_doc.createElementNS(external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.namespaces.svg, "hasValidPointType" in $$ && $$.hasValidPointType(point) ? point : "use"); }.bind(this)).attr("class", $LEGEND.legendItemPoint).style("fill", getLegendColor.bind($$)).style("pointer-events", $$.getStylePropValue("none")).attr("href", function (data, idx, selection) { _newArrowCheck(this, _this6); const node = selection[idx], nodeName = node.nodeName.toLowerCase(), id = $$.getTargetSelectorSuffix(data); return nodeName === "use" ? "#" + state.datetimeId + "-point" + id : undefined; }.bind(this)); } else { l.append(isRectangle ? "line" : legendType).attr("class", $LEGEND.legendItemTile).style("stroke", getLegendColor.bind($$)).style("pointer-events", $$.getStylePropValue("none")).call(function (selection) { _newArrowCheck(this, _this6); if (legendType === "circle") { selection.attr("r", legendItemR).style("fill", getLegendColor.bind($$)).attr("cx", isLegendRightOrInset ? posFn.x2Tile : pos).attr("cy", isLegendRightOrInset ? pos : posFn.yTile); } else if (isRectangle) { selection.attr("stroke-width", itemTileSize.height).attr("x1", isLegendRightOrInset ? posFn.x1Tile : pos).attr("y1", isLegendRightOrInset ? pos : posFn.yTile).attr("x2", isLegendRightOrInset ? posFn.x2Tile : pos).attr("y2", isLegendRightOrInset ? pos : posFn.yTile); } }.bind(this)); } }, /** * Update legend item position * @param {Array} targetIdz Data ids * @param {boolean} withTransition Whether or not to apply transition * @param {object} posFn Position functions * @private */ updateLegendItemPos: function updateLegendItemPos(targetIdz, withTransition, posFn) { var _this8 = this; const $$ = this, config = $$.config, legend = $$.$el.legend, $T = $$.$T, usePoint = config.legend_usePoint, legendType = config.legend_item_tile_type; if (usePoint) { const tiles = legend.selectAll("." + $LEGEND.legendItemPoint).data(targetIdz); $T(tiles, withTransition).each(function () { var _this7 = this; const nodeName = this.nodeName.toLowerCase(), pointR = config.point_r; let x = "x", y = "y", xOffset = 2, yOffset = 2.5, radius = null, width = null, height = null; if (nodeName === "circle") { const size = pointR * .2; x = "cx"; y = "cy"; radius = pointR + size; xOffset = pointR * 2; yOffset = -size; } else if (nodeName === "rect") { const size = pointR * 2.5; width = size; height = size; yOffset = 3; } (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this).attr(x, function (d) { _newArrowCheck(this, _this7); return posFn.x1Tile(d) + xOffset; }.bind(this)).attr(y, function (d) { _newArrowCheck(this, _this7); return posFn.yTile(d) - yOffset; }.bind(this)).attr("r", radius).attr("width", width).attr("height", height); }); } else { const tiles = legend.selectAll("." + $LEGEND.legendItemTile).data(targetIdz); $T(tiles, withTransition).style("stroke", getLegendColor.bind($$)).call(function (selection) { var _this9 = this; _newArrowCheck(this, _this8); if (legendType === "circle") { selection.attr("cx", function (d) { _newArrowCheck(this, _this9); const x2 = posFn.x2Tile(d); return x2 - (x2 - posFn.x1Tile(d)) / 2; }.bind(this)).attr("cy", posFn.yTile); } else if (legendType !== "circle") { selection.attr("x1", posFn.x1Tile).attr("y1", posFn.yTile).attr("x2", posFn.x2Tile).attr("y2", posFn.yTile); } }.bind(this)); } } }); // EXTERNAL MODULE: external {"commonjs":"d3-transition","commonjs2":"d3-transition","amd":"d3-transition","root":"d3"} var external_commonjs_d3_transition_commonjs2_d3_transition_amd_d3_transition_root_d3_ = __webpack_require__(8); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/redraw.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var redraw = ({ redraw: function redraw(options) { var _$$$axis, _this = this; if (options === void 0) { options = {}; } const $$ = this, config = $$.config, state = $$.state, $el = $$.$el, _$el = $el, main = _$el.main, treemap = _$el.treemap; state.redrawing = !0; const targetsToShow = $$.filterTargetsToShow($$.data.targets), _options = options, flow = _options.flow, initializing = _options.initializing, wth = $$.getWithOption(options), duration = wth.Transition ? config.transition_duration : 0, durationForExit = wth.TransitionForExit ? duration : 0, durationForAxis = wth.TransitionForAxis ? duration : 0, transitions = (_$$$axis = $$.axis) == null ? void 0 : _$$$axis.generateTransitions(durationForAxis); $$.updateSizes(initializing); // update legend and transform each g if (wth.Legend && config.legend_show) { options.withTransition = !!duration; treemap || $$.updateLegend($$.mapToIds($$.data.targets), options, transitions); } else if (wth.Dimension) { // need to update dimension (e.g. axis.y.tick.values) because y tick values should change // no need to update axis in it because they will be updated in redraw() $$.updateDimension(!0); } // Data empty label positioning and text. config.data_empty_label_text && main.select("text." + $TEXT.text + "." + $COMMON.empty).attr("x", state.width / 2).attr("y", state.height / 2).text(config.data_empty_label_text).style("display", targetsToShow.length ? "none" : null); // update axis if (state.hasAxis) { // @TODO: Make 'init' state to be accessible everywhere not passing as argument. $$.axis.redrawAxis(targetsToShow, wth, transitions, flow, initializing); // grid $$.hasGrid() && $$.updateGrid(); // rect for regions config.regions.length && $$.updateRegion(); ["bar", "candlestick", "line", "area"].forEach(function (v) { _newArrowCheck(this, _this); const name = capitalize(v); if (/^(line|area)$/.test(v) && $$.hasTypeOf(name) || $$.hasType(v)) { $$["update" + name](wth.TransitionForExit); } }.bind(this)); // circles for select $el.text && main.selectAll("." + $SELECT.selectedCircles).filter($$.isBarType.bind($$)).selectAll("circle").remove(); // event rects will redrawn when flow called if (config.interaction_enabled && !flow && wth.EventRect) { $$.redrawEventRect(); $$.bindZoomEvent == null || $$.bindZoomEvent(); } } else { // arc $el.arcs && $$.redrawArc(duration, durationForExit, wth.Transform); // radar $el.radar && $$.redrawRadar(); // polar $el.polar && $$.redrawPolar(); // treemap treemap && $$.updateTreemap(durationForExit); } // @TODO: Axis & Radar type if (!state.resizing && !treemap && ($$.hasPointType() || state.hasRadar)) { $$.updateCircle(); } // text $$.hasDataLabel() && !$$.hasArcType(null, ["radar"]) && $$.updateText(); // title $$.redrawTitle == null || $$.redrawTitle(); initializing && $$.updateTypesElements(); $$.generateRedrawList(targetsToShow, flow, duration, wth.Subchart); $$.updateTooltipOnRedraw(); $$.callPluginHook("$redraw", options, duration); }, /** * Generate redraw list * @param {object} targets targets data to be shown * @param {object} flow flow object * @param {number} duration duration value * @param {boolean} withSubchart whether or not to show subchart * @private */ generateRedrawList: function generateRedrawList(targets, flow, duration, withSubchart) { var _this2 = this; const $$ = this, config = $$.config, state = $$.state, shape = $$.getDrawShape(); if (state.hasAxis) { // subchart config.subchart_show && $$.redrawSubchart(withSubchart, duration, shape); } // generate flow const flowFn = flow && $$.generateFlow({ targets: targets, flow: flow, duration: flow.duration, shape: shape, xv: $$.xv.bind($$) }), withTransition = (duration || flowFn) && isTabVisible(), redrawList = $$.getRedrawList(shape, flow, flowFn, withTransition), afterRedraw = function () { _newArrowCheck(this, _this2); flowFn && flowFn(); state.redrawing = !1; callFn(config.onrendered, $$.api); }.bind(this); // redraw list // callback function after redraw ends if (afterRedraw) { // Only use transition when current tab is visible. if (withTransition && redrawList.length) { // Wait for end of transitions for callback const waitForDraw = generateWait(); // transition should be derived from one transition (0,external_commonjs_d3_transition_commonjs2_d3_transition_amd_d3_transition_root_d3_.transition)().duration(duration).each(function () { var _this3 = this; _newArrowCheck(this, _this2); redrawList.reduce(function (acc, t1) { _newArrowCheck(this, _this3); return acc.concat(t1); }.bind(this), []).forEach(function (t) { _newArrowCheck(this, _this3); return waitForDraw.add(t); }.bind(this)); }.bind(this)).call(waitForDraw, afterRedraw); } else if (!state.transiting) { afterRedraw(); } } // update fadein condition $$.mapToIds($$.data.targets).forEach(function (id) { _newArrowCheck(this, _this2); state.withoutFadeIn[id] = !0; }.bind(this)); }, getRedrawList: function getRedrawList(shape, flow, flowFn, withTransition) { var _this4 = this; const $$ = this, config = $$.config, _$$$state = $$.state, hasAxis = _$$$state.hasAxis, hasRadar = _$$$state.hasRadar, hasTreemap = _$$$state.hasTreemap, grid = $$.$el.grid, _shape$pos = shape.pos, cx = _shape$pos.cx, cy = _shape$pos.cy, xForText = _shape$pos.xForText, yForText = _shape$pos.yForText, list = []; if (hasAxis) { if (config.grid_x_lines.length || config.grid_y_lines.length) { list.push($$.redrawGrid(withTransition)); } if (config.regions.length) { list.push($$.redrawRegion(withTransition)); } Object.keys(shape.type).forEach(function (v) { _newArrowCheck(this, _this4); const name = capitalize(v), drawFn = shape.type[v]; if (/^(area|line)$/.test(v) && $$.hasTypeOf(name) || $$.hasType(v)) { list.push($$["redraw" + name](drawFn, withTransition)); } }.bind(this)); !flow && grid.main && list.push($$.updateGridFocus()); } if (!$$.hasArcType() || hasRadar) { notEmpty(config.data_labels) && config.data_labels !== !1 && list.push($$.redrawText(xForText, yForText, flow, withTransition)); } if (($$.hasPointType() || hasRadar) && !$$.isPointFocusOnly()) { $$.redrawCircle && list.push($$.redrawCircle(cx, cy, withTransition, flowFn)); } if (hasTreemap) { list.push($$.redrawTreemap(withTransition)); } return list; }, updateAndRedraw: function updateAndRedraw(options) { if (options === void 0) { options = {}; } const $$ = this, config = $$.config, state = $$.state; let transitions; // same with redraw options.withTransition = getOption(options, "withTransition", !0); options.withTransform = getOption(options, "withTransform", !1); options.withLegend = getOption(options, "withLegend", !1); // NOT same with redraw options.withUpdateXDomain = !0; options.withUpdateOrgXDomain = !0; options.withTransitionForExit = !1; options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); // MEMO: called in updateLegend in redraw if withLegend if (!(options.withLegend && config.legend_show)) { if (state.hasAxis) { transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0); } // Update scales $$.updateScales(); $$.updateSvgSize(); // Update g positions $$.transformAll(options.withTransitionForTransform, transitions); } // Draw with new sizes & scales $$.redraw(options, transitions); } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/scale.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get scale * @param {string} [type='linear'] Scale type * @param {number} [min] Min range * @param {number} [max] Max range * @returns {d3.scaleLinear|d3.scaleTime} scale * @private */ function getScale(type, min, max) { if (type === void 0) { type = "linear"; } if (min === void 0) { min = 0; } if (max === void 0) { max = 1; } const scale = { linear: external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleLinear, log: external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleSymlog, _log: external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleLog, time: external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleTime, utc: external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleUtc }[type](); scale.type = type; /_?log/.test(type) && scale.clamp(!0); return scale.range([min, max]); } /* harmony default export */ var scale = ({ /** * Get x Axis scale function * @param {number} min Min value * @param {number} max Max value * @param {Array} domain Domain value * @param {Function} offset The offset getter to be sum * @returns {Function} scale * @private */ getXScale: function getXScale(min, max, domain, offset) { const $$ = this, scale = $$.scale.zoom || getScale($$.axis.getAxisType("x"), min, max); return $$.getCustomizedXScale(domain ? scale.domain(domain) : scale, offset); }, /** * Get y Axis scale function * @param {string} id Axis id: 'y' or 'y2' * @param {number} min Min value * @param {number} max Max value * @param {Array} domain Domain value * @returns {Function} Scale function * @private */ getYScale: function getYScale(id, min, max, domain) { const $$ = this, scale = getScale($$.axis.getAxisType(id), min, max); domain && scale.domain(domain); return scale; }, /** * Get y Axis scale * @param {string} id Axis id * @param {boolean} isSub Weather is sub Axis * @returns {Function} Scale function * @private */ getYScaleById: function getYScaleById(id, isSub) { var _this$axis; if (isSub === void 0) { isSub = !1; } const isY2 = ((_this$axis = this.axis) == null ? void 0 : _this$axis.getId(id)) === "y2", key = isSub ? isY2 ? "subY2" : "subY" : isY2 ? "y2" : "y"; return this.scale[key]; }, /** * Get customized x axis scale * @param {d3.scaleLinear|d3.scaleTime} scaleValue Scale function * @param {Function} offsetValue Offset getter to be sum * @returns {Function} Scale function * @private */ getCustomizedXScale: function getCustomizedXScale(scaleValue, offsetValue) { var _this = this; const $$ = this, offset = offsetValue || function () { _newArrowCheck(this, _this); return $$.axis.x.tickOffset(); }.bind(this), isInverted = $$.config.axis_x_inverted, scale = function (d, raw) { const v = scaleValue(d) + offset(); return raw ? v : Math.ceil(v); }; // copy original scale methods for (const key in scaleValue) { scale[key] = scaleValue[key]; } scale.orgDomain = function () { _newArrowCheck(this, _this); return scaleValue.domain(); }.bind(this); scale.orgScale = function () { _newArrowCheck(this, _this); return scaleValue; }.bind(this); // define custom domain() for categorized axis if ($$.axis.isCategorized()) { scale.domain = function (domainValue) { let domain = domainValue; if (!arguments.length) { domain = this.orgDomain(); return isInverted ? [domain[0] + 1, domain[1]] : [domain[0], domain[1] + 1]; } scaleValue.domain(domain); return scale; }; } return scale; }, /** * Update scale * @param {boolean} isInit Param is given at the init rendering * @param {boolean} updateXDomain If update x domain * @private */ updateScales: function updateScales(isInit, updateXDomain) { var _this2 = this; if (updateXDomain === void 0) { updateXDomain = !0; } const $$ = this, axis = $$.axis, config = $$.config, format = $$.format, org = $$.org, scale = $$.scale, _$$$state = $$.state, current = _$$$state.current, width = _$$$state.width, height = _$$$state.height, width2 = _$$$state.width2, height2 = _$$$state.height2, hasAxis = _$$$state.hasAxis, hasTreemap = _$$$state.hasTreemap; if (hasAxis) { var _scale$x; const isRotated = config.axis_rotated, resettedPadding = $$.getResettedPadding(1), min = { x: isRotated ? resettedPadding : 0, y: isRotated ? 0 : height, subX: isRotated ? 1 : 0, subY: isRotated ? 0 : height2 }, max = { x: isRotated ? height : width, y: isRotated ? width : resettedPadding, subX: isRotated ? height : width, subY: isRotated ? width2 : 1 }, xDomain = updateXDomain && ((_scale$x = scale.x) == null ? void 0 : _scale$x.orgDomain()), xSubDomain = updateXDomain && org.xDomain; // update edges // update scales // x Axis scale.x = $$.getXScale(min.x, max.x, xDomain, function () { _newArrowCheck(this, _this2); return axis.x.tickOffset(); }.bind(this)); scale.subX = $$.getXScale(min.x, max.x, xSubDomain, function (d) { var _axis$subX; _newArrowCheck(this, _this2); return d % 1 ? 0 : ((_axis$subX = axis.subX) != null ? _axis$subX : axis.x).tickOffset(); }.bind(this)); format.xAxisTick = axis.getXAxisTickFormat(); format.subXAxisTick = axis.getXAxisTickFormat(!0); axis.setAxis("x", scale.x, config.axis_x_tick_outer, isInit); if (config.subchart_show) { axis.setAxis("subX", scale.subX, config.axis_x_tick_outer, isInit); } // y Axis scale.y = $$.getYScale("y", min.y, max.y, scale.y ? scale.y.domain() : config.axis_y_default); scale.subY = $$.getYScale("y", min.subY, max.subY, scale.subY ? scale.subY.domain() : config.axis_y_default); axis.setAxis("y", scale.y, config.axis_y_tick_outer, isInit); // y2 Axis if (config.axis_y2_show) { scale.y2 = $$.getYScale("y2", min.y, max.y, scale.y2 ? scale.y2.domain() : config.axis_y2_default); scale.subY2 = $$.getYScale("y2", min.subY, max.subY, scale.subY2 ? scale.subY2.domain() : config.axis_y2_default); axis.setAxis("y2", scale.y2, config.axis_y2_tick_outer, isInit); } } else if (hasTreemap) { const padding = $$.getCurrentPadding(); scale.x = (0,external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleLinear)().rangeRound([padding.left, current.width - padding.right]); scale.y = (0,external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleLinear)().rangeRound([padding.top, current.height - padding.bottom]); } else { // update for arc $$.updateArc == null || $$.updateArc(); } }, /** * Get the zoom or unzoomed scaled value * @param {Date|number|object} d Data value * @returns {number|null} * @private */ xx: function xx(d) { const $$ = this, config = $$.config, _$$$scale = $$.scale, x = _$$$scale.x, zoom = _$$$scale.zoom, fn = config.zoom_enabled && zoom ? zoom : x; return d ? fn(isValue(d.x) ? d.x : d) : null; }, xv: function xv(d) { const $$ = this, axis = $$.axis, config = $$.config, _$$$scale2 = $$.scale, x = _$$$scale2.x, zoom = _$$$scale2.zoom, fn = config.zoom_enabled && zoom ? zoom : x; let value = $$.getBaseValue(d); if (axis.isTimeSeries()) { value = parseDate.call($$, value); } else if (axis.isCategorized() && isString(value)) { value = config.axis_x_categories.indexOf(value); } return Math.ceil(fn(value)); }, yv: function yv(d) { const $$ = this, _$$$scale3 = $$.scale, y = _$$$scale3.y, y2 = _$$$scale3.y2, yScale = d.axis && d.axis === "y2" ? y2 : y; return Math.ceil(yScale($$.getBaseValue(d))); }, subxx: function subxx(d) { return d ? this.scale.subX(d.x) : null; } }); // EXTERNAL MODULE: external {"commonjs":"d3-shape","commonjs2":"d3-shape","amd":"d3-shape","root":"d3"} var external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_ = __webpack_require__(9); ;// CONCATENATED MODULE: ./src/ChartInternal/shape/shape.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get grouped data point function for y coordinate * - Note: Grouped(stacking) works only for line and bar types * @param {object} d data vlaue * @returns {Function|undefined} * @private */ function getGroupedDataPointsFn(d) { const $$ = this; let fn; if ($$.isLineType(d)) { fn = $$.generateGetLinePoints($$.getShapeIndices($$.isLineType)); } else if ($$.isBarType(d)) { fn = $$.generateGetBarPoints($$.getShapeIndices($$.isBarType)); } return fn; } /* harmony default export */ var shape = ({ /** * Get the shape draw function * @returns {object} * @private */ getDrawShape: function getDrawShape() { var _this = this; const $$ = this, isRotated = $$.config.axis_rotated, _$$$state = $$.state, hasRadar = _$$$state.hasRadar, hasTreemap = _$$$state.hasTreemap, shape = { type: {}, indices: {}, pos: {} }; hasTreemap || ["bar", "candlestick", "line", "area"].forEach(function (v) { _newArrowCheck(this, _this); const name = capitalize(/^(bubble|scatter)$/.test(v) ? "line" : v); if ($$.hasType(v) || $$.hasTypeOf(name) || v === "line" && ($$.hasType("bubble") || $$.hasType("scatter"))) { const indices = $$.getShapeIndices($$["is" + name + "Type"]), drawFn = $$["generateDraw" + name]; shape.indices[v] = indices; shape.type[v] = drawFn ? drawFn.bind($$)(indices, !1) : undefined; } }.bind(this)); if (!$$.hasArcType() || hasRadar || hasTreemap) { let cx, cy; // generate circle x/y functions depending on updated params if (!hasTreemap) { cx = hasRadar ? $$.radarCircleX : isRotated ? $$.circleY : $$.circleX; cy = hasRadar ? $$.radarCircleY : isRotated ? $$.circleX : $$.circleY; } shape.pos = { xForText: $$.generateXYForText(shape.indices, !0), yForText: $$.generateXYForText(shape.indices, !1), cx: (cx || function () {}).bind($$), cy: (cy || function () {}).bind($$) }; } return shape; }, /** * Get shape's indices according it's position within each axis tick. * * From the below example, indices will be: * ==> {data1: 0, data2: 0, data3: 1, data4: 1, __max__: 1} * * data1 data3 data1 data3 * data2 data4 data2 data4 * ------------------------- * 0 1 * @param {Function} typeFilter Chart type filter function * @returns {object} Indices object with its position */ getShapeIndices: function getShapeIndices(typeFilter) { var _this2 = this; const $$ = this, config = $$.config, xs = config.data_xs, hasXs = notEmpty(xs), indices = {}; let i = hasXs ? {} : 0; if (hasXs) { getUnique(Object.keys(xs).map(function (v) { _newArrowCheck(this, _this2); return xs[v]; }.bind(this))).forEach(function (v) { _newArrowCheck(this, _this2); i[v] = 0; indices[v] = {}; }.bind(this)); } $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) { _newArrowCheck(this, _this2); const xKey = d.id in xs ? xs[d.id] : "", ind = xKey ? indices[xKey] : indices; for (let j = 0, groups; groups = config.data_groups[j]; j++) { if (groups.indexOf(d.id) < 0) { continue; } for (let k = 0, key; key = groups[k]; k++) { if (key in ind) { ind[d.id] = ind[key]; break; } // for same grouped data, add other data to same indices if (d.id !== key && xKey) { var _ind$d$id; ind[key] = (_ind$d$id = ind[d.id]) != null ? _ind$d$id : i[xKey]; } } } if (isUndefined(ind[d.id])) { ind[d.id] = xKey ? i[xKey]++ : i++; ind.__max__ = (xKey ? i[xKey] : i) - 1; } }.bind(this)); return indices; }, /** * Get indices value based on data ID value * @param {object} indices Indices object * @param {object} d Data row * @param {string} caller Caller function name (Used only for 'sparkline' plugin) * @returns {object} Indices object * @private */ getIndices: function getIndices(indices, d) { var _this3 = this; // eslint-disable-line const $$ = this, _$$$config = $$.config, xs = _$$$config.data_xs, removeNull = _$$$config.bar_indices_removeNull, id = d.id, index = d.index; if ($$.isBarType(id) && removeNull) { const ind = {}; // redefine bar indices order $$.getAllValuesOnIndex(index, !0).forEach(function (v, i) { _newArrowCheck(this, _this3); ind[v.id] = i; ind.__max__ = i; }.bind(this)); return ind; } return notEmpty(xs) ? indices[xs[id]] : indices; }, /** * Get indices max number * @param {object} indices Indices object * @returns {number} Max number * @private */ getIndicesMax: function getIndicesMax(indices) { var _this4 = this; return notEmpty(this.config.data_xs) ? // if is multiple xs, return total sum of xs' __max__ value Object.keys(indices).map(function (v) { _newArrowCheck(this, _this4); return indices[v].__max__ || 0; }.bind(this)).reduce(function (acc, curr) { _newArrowCheck(this, _this4); return acc + curr; }.bind(this)) : indices.__max__; }, getShapeX: function getShapeX(offset, indices, isSub) { var _this5 = this; const $$ = this, config = $$.config, scale = $$.scale, currScale = isSub ? scale.subX : scale.zoom || scale.x, barOverlap = config.bar_overlap, barPadding = config.bar_padding, sum = function (p, c) { _newArrowCheck(this, _this5); return p + c; }.bind(this), halfWidth = isObjectType(offset) && (offset._$total.length ? offset._$total.reduce(sum) / 2 : 0); // total shapes half width return function (d) { _newArrowCheck(this, _this5); const ind = $$.getIndices(indices, d, "getShapeX"), index = d.id in ind ? ind[d.id] : 0, targetsNum = (ind.__max__ || 0) + 1; let x = 0; if (notEmpty(d.x)) { const xPos = currScale(d.x, !0); if (halfWidth) { const offsetWidth = offset[d.id] || offset._$width; x = barOverlap ? xPos - offsetWidth / 2 : xPos - offsetWidth + offset._$total.slice(0, index + 1).reduce(sum) - halfWidth; } else { x = xPos - (isNumber(offset) ? offset : offset._$width) * (targetsNum / 2 - (barOverlap ? 1 : index)); } } // adjust x position for bar.padding option if (offset && x && targetsNum > 1 && barPadding) { if (index) { x += barPadding * index; } if (targetsNum > 2) { x -= (targetsNum - 1) * barPadding / 2; } else if (targetsNum === 2) { x -= barPadding / 2; } } return x; }.bind(this); }, getShapeY: function getShapeY(isSub) { var _this6 = this; const $$ = this, isStackNormalized = $$.isStackNormalized(); return function (d) { _newArrowCheck(this, _this6); let value = d.value; if (isNumber(d)) { value = d; } else if ($$.isAreaRangeType(d)) { value = $$.getBaseValue(d, "mid"); } else if (isStackNormalized) { value = $$.getRatio("index", d, !0); } else if ($$.isBubbleZType(d)) { value = $$.getBubbleZData(d.value, "y"); } else if ($$.isBarRangeType(d)) { // TODO use range.getEnd() like method value = value[1]; } return $$.getYScaleById(d.id, isSub)(value); }.bind(this); }, /** * Get shape based y Axis min value * @param {string} id Data id * @returns {number} * @private */ getShapeYMin: function getShapeYMin(id) { const $$ = this, axisId = $$.axis.getId(id), scale = $$.scale[axisId], _scale$domain = scale.domain(), yMin = _scale$domain[0], inverted = $$.config["axis_" + axisId + "_inverted"]; return !$$.isGrouped(id) && !inverted && yMin > 0 ? yMin : 0; }, /** * Get Shape's offset data * @param {Function} typeFilter Type filter function * @returns {object} * @private */ getShapeOffsetData: function getShapeOffsetData(typeFilter) { var _this7 = this; const $$ = this, targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))), isStackNormalized = $$.isStackNormalized(), shapeOffsetTargets = targets.map(function (target) { var _this8 = this; _newArrowCheck(this, _this7); let rowValues = target.values; const values = {}; if ($$.isStepType(target)) { rowValues = $$.convertValuesToStep(rowValues); } const rowValueMapByXValue = rowValues.reduce(function (out, d) { _newArrowCheck(this, _this8); const key = +d.x; out[key] = d; values[key] = isStackNormalized ? $$.getRatio("index", d, !0) : d.value; return out; }.bind(this), {}); return { id: target.id, rowValues: rowValues, rowValueMapByXValue: rowValueMapByXValue, values: values }; }.bind(this)), indexMapByTargetId = targets.reduce(function (out, _ref, index) { let id = _ref.id; _newArrowCheck(this, _this7); out[id] = index; return out; }.bind(this), {}); return { indexMapByTargetId: indexMapByTargetId, shapeOffsetTargets: shapeOffsetTargets }; }, getShapeOffset: function getShapeOffset(typeFilter, indices, isSub) { var _this9 = this; const $$ = this, _$$$getShapeOffsetDat = $$.getShapeOffsetData(typeFilter), shapeOffsetTargets = _$$$getShapeOffsetDat.shapeOffsetTargets, indexMapByTargetId = _$$$getShapeOffsetDat.indexMapByTargetId, groupsZeroAs = $$.config.data_groupsZeroAs; return function (d, idx) { var _this10 = this; _newArrowCheck(this, _this9); const id = d.id, value = d.value, x = d.x, ind = $$.getIndices(indices, d), scale = $$.getYScaleById(id, isSub); if ($$.isBarRangeType(d)) { // TODO use range.getStart() return scale(value[0]); } const dataXAsNumber = +x, y0 = scale(groupsZeroAs === "zero" ? 0 : $$.getShapeYMin(id)); let offset = y0; shapeOffsetTargets.filter(function (t) { _newArrowCheck(this, _this10); return t.id !== id && ind[t.id] === ind[id]; }.bind(this)).forEach(function (t) { _newArrowCheck(this, _this10); const tid = t.id, rowValueMapByXValue = t.rowValueMapByXValue, rowValues = t.rowValues, tvalues = t.values; // for same stacked group (ind[tid] === ind[id]) if (indexMapByTargetId[tid] < indexMapByTargetId[id]) { var _row; const rValue = tvalues[dataXAsNumber]; let row = rowValues[idx]; // check if the x values line up if (!row || +row.x !== dataXAsNumber) { row = rowValueMapByXValue[dataXAsNumber]; } if (((_row = row) == null ? void 0 : _row.value) * value >= 0 && isNumber(rValue)) { const addOffset = value === 0 ? groupsZeroAs === "positive" && rValue > 0 || groupsZeroAs === "negative" && rValue < 0 : !0; if (addOffset) { offset += scale(rValue) - y0; } } } }.bind(this)); return offset; }.bind(this); }, /** * Get data's y coordinate * @param {object} d Target data * @param {number} i Index number * @returns {number} y coordinate * @private */ circleY: function circleY(d, i) { const $$ = this, id = d.id; let points; if ($$.isGrouped(id)) { points = getGroupedDataPointsFn.bind($$)(d); } return points ? points(d, i)[0][1] : $$.getYScaleById(id)($$.getBaseValue(d)); }, getBarW: function getBarW(type, axis, targetsNum) { var _this11 = this; const $$ = this, config = $$.config, org = $$.org, scale = $$.scale, maxDataCount = $$.getMaxDataCount(), isGrouped = type === "bar" && config.data_groups.length, configName = type + "_width", tickInterval = scale.zoom && !$$.axis.isCategorized() ? org.xDomain.map(function (v) { _newArrowCheck(this, _this11); return scale.zoom(v); }.bind(this)).reduce(function (a, c) { _newArrowCheck(this, _this11); return Math.abs(a) + c; }.bind(this)) / maxDataCount : axis.tickInterval(maxDataCount), getWidth = function (id) { _newArrowCheck(this, _this11); const width = id ? config[configName][id] : config[configName], ratio = id ? width.ratio : config[configName + "_ratio"], max = id ? width.max : config[configName + "_max"], w = isNumber(width) ? width : targetsNum ? tickInterval * ratio / targetsNum : 0; return max && w > max ? max : w; }.bind(this); let result = getWidth(); if (!isGrouped && isObjectType(config[configName])) { result = { _$width: result, _$total: [] }; $$.filterTargetsToShow($$.data.targets).forEach(function (v) { _newArrowCheck(this, _this11); if (config[configName][v.id]) { result[v.id] = getWidth(v.id); result._$total.push(result[v.id] || result._$width); } }.bind(this)); } return result; }, /** * Get shape element * @param {string} shapeName Shape string * @param {number} i Index number * @param {string} id Data series id * @returns {d3Selection} * @private */ getShapeByIndex: function getShapeByIndex(shapeName, i, id) { var _this12 = this; const $$ = this, $el = $$.$el, suffix = isValue(i) ? "-" + i : ""; let shape = $el[shapeName]; // filter from shape reference if has if (shape && !shape.empty()) { shape = shape.filter(function (d) { _newArrowCheck(this, _this12); return id ? d.id === id : !0; }.bind(this)).filter(function (d) { _newArrowCheck(this, _this12); return isValue(i) ? d.index === i : !0; }.bind(this)); } else { shape = (id ? $el.main.selectAll("." + classes[shapeName + "s"] + $$.getTargetSelectorSuffix(id)) : $el.main).selectAll("." + classes[shapeName] + suffix); } return shape; }, isWithinShape: function isWithinShape(that, d) { const $$ = this, shape = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(that); let isWithin; if (!$$.isTargetToShow(d.id)) { isWithin = !1; } else if ($$.hasValidPointType != null && $$.hasValidPointType(that.nodeName)) { isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScaleById(d.id)(d.value)) : $$.isWithinCircle(that, $$.isBubbleType(d) ? $$.pointSelectR(d) * 1.5 : 0); } else if (that.nodeName === "path") { isWithin = shape.classed(classes.bar) ? $$.isWithinBar(that) : !0; } return isWithin; }, getInterpolate: function getInterpolate(d) { const $$ = this, interpolation = $$.getInterpolateType(d); return { "basis": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveBasis, "basis-closed": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveBasisClosed, "basis-open": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveBasisOpen, "bundle": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveBundle, "cardinal": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveCardinal, "cardinal-closed": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveCardinalClosed, "cardinal-open": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveCardinalOpen, "catmull-rom": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveCatmullRom, "catmull-rom-closed": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveCatmullRomClosed, "catmull-rom-open": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveCatmullRomOpen, "monotone-x": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveMonotoneX, "monotone-y": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveMonotoneY, "natural": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveNatural, "linear-closed": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveLinearClosed, "linear": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveLinear, "step": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveStep, "step-after": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveStepAfter, "step-before": external_commonjs_d3_shape_commonjs2_d3_shape_amd_d3_shape_root_d3_.curveStepBefore }[interpolation]; }, getInterpolateType: function getInterpolateType(d) { const $$ = this, config = $$.config, type = config.spline_interpolation_type, interpolation = $$.isInterpolationType(type) ? type : "cardinal"; return $$.isSplineType(d) ? interpolation : $$.isStepType(d) ? config.line_step_type : "linear"; }, isWithinBar: function isWithinBar(that) { const mouse = getPointer(this.state.event, that), list = getRectSegList(that), _list = list, seg0 = _list[0], seg1 = _list[1], x = Math.min(seg0.x, seg1.x), y = Math.min(seg0.y, seg1.y), offset = this.config.bar_sensitivity, _that$getBBox = that.getBBox(), width = _that$getBBox.width, height = _that$getBBox.height, isWithin = x - offset < mouse[0] && mouse[0] < x + width + offset && y - offset < mouse[1] && mouse[1] < y + height + offset; return isWithin; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/size.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var size = ({ /** * Update container size * @private */ setContainerSize: function setContainerSize() { const $$ = this, state = $$.state; state.current.width = $$.getCurrentWidth(); state.current.height = $$.getCurrentHeight(); }, getCurrentWidth: function getCurrentWidth() { const $$ = this; return $$.config.size_width || $$.getParentWidth(); }, getCurrentHeight: function getCurrentHeight() { const $$ = this, config = $$.config, h = config.size_height || $$.getParentHeight(); return h > 0 ? h : 320 / ($$.hasType("gauge") && !config.gauge_fullCircle ? 2 : 1); }, /** * Get the parent rect element's size * @param {string} key property/attribute name * @returns {number} * @private */ getParentRectValue: function getParentRectValue(key) { const offsetName = "offset" + capitalize(key); let parent = this.$el.chart.node(), v = 0; while (v < 30 && parent && parent.tagName !== "BODY") { try { v = parent.getBoundingClientRect()[key]; } catch (e) { if (offsetName in parent) { // In IE in certain cases getBoundingClientRect // will cause an "unspecified error" v = parent[offsetName]; } } parent = parent.parentNode; } // Sometimes element's dimension value is incorrect(ex. flex container) // In this case, use body's offset instead. const bodySize = browser_doc.body[offsetName]; v > bodySize && (v = bodySize); return v; }, getParentWidth: function getParentWidth() { return this.getParentRectValue("width"); }, getParentHeight: function getParentHeight() { const h = this.$el.chart.style("height"); let height = 0; if (h) { height = /px$/.test(h) ? parseInt(h, 10) : this.getParentRectValue("height"); } return height; }, getSvgLeft: function getSvgLeft(withoutRecompute) { const $$ = this, config = $$.config, hasAxis = $$.state.hasAxis, $el = $$.$el, isRotated = config.axis_rotated, hasLeftAxisRect = isRotated || !isRotated && !config.axis_y_inner, leftAxisClass = isRotated ? $AXIS.axisX : $AXIS.axisY, leftAxis = $el.main.select("." + leftAxisClass).node(), leftLabel = hasAxis && config["axis_" + (isRotated ? "x" : "y") + "_label"]; let labelWidth = 0; // if axis label position set to inner, exclude from the value if (hasAxis && (isString(leftLabel) || isString(leftLabel.text) || /^inner-/.test(leftLabel == null ? void 0 : leftLabel.position))) { const label = $el.main.select("." + leftAxisClass + "-label"); if (!label.empty()) { labelWidth = label.node().getBoundingClientRect().left; } } const svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : { right: 0 }, chartRectLeft = $el.chart.node().getBoundingClientRect().left + labelWidth, hasArc = $$.hasArcType(), svgLeft = svgRect.right - chartRectLeft - (hasArc ? 0 : $$.getCurrentPaddingByDirection("left", withoutRecompute)); return svgLeft > 0 ? svgLeft : 0; }, updateDimension: function updateDimension(withoutAxis) { const $$ = this, config = $$.config, hasAxis = $$.state.hasAxis, $el = $$.$el; if (hasAxis && !withoutAxis && $$.axis.x && config.axis_rotated) { var _$$$axis$subX; (_$$$axis$subX = $$.axis.subX) == null || _$$$axis$subX.create($el.axis.subX); } // pass 'withoutAxis' param to not animate at the init rendering $$.updateScales(withoutAxis); $$.updateSvgSize(); $$.transformAll(!1); }, updateSvgSize: function updateSvgSize() { const $$ = this, _$$$state = $$.state, clip = _$$$state.clip, current = _$$$state.current, hasAxis = _$$$state.hasAxis, width = _$$$state.width, height = _$$$state.height, svg = $$.$el.svg; svg.attr("width", current.width).attr("height", current.height); if (hasAxis) { const brush = svg.select("." + $SUBCHART.brush + " .overlay"), brushSize = { width: 0, height: 0 }; if (brush.size()) { brushSize.width = +brush.attr("width"); brushSize.height = +brush.attr("height"); } svg.selectAll(["#" + clip.id, "#" + clip.idGrid]).select("rect").attr("width", width).attr("height", height); svg.select("#" + clip.idXAxis).select("rect").call($$.setXAxisClipPath.bind($$)); svg.select("#" + clip.idYAxis).select("rect").call($$.setYAxisClipPath.bind($$)); clip.idSubchart && svg.select("#" + clip.idSubchart).select("rect").attr("width", width).attr("height", brushSize.height); } }, /** * Get padding by the direction. * @param {string} type "top" | "bottom" | "left" | "right" * @param {boolean} [withoutRecompute=false] If set true, do not recompute the padding value. * @param {boolean} [withXAxisTickTextOverflow=false] If set true, calculate x axis tick text overflow. * @returns {number} padding value * @private */ getCurrentPaddingByDirection: function getCurrentPaddingByDirection(type, withoutRecompute, withXAxisTickTextOverflow) { var _config$padding; if (withoutRecompute === void 0) { withoutRecompute = !1; } if (withXAxisTickTextOverflow === void 0) { withXAxisTickTextOverflow = !1; } const $$ = this, config = $$.config, $el = $$.$el, hasAxis = $$.state.hasAxis, isRotated = config.axis_rotated, isFitPadding = ((_config$padding = config.padding) == null ? void 0 : _config$padding.mode) === "fit", paddingOption = isNumber(config["padding_" + type]) ? config["padding_" + type] : undefined, axisId = hasAxis ? { top: isRotated ? "y2" : null, bottom: isRotated ? "y" : "x", left: isRotated ? "x" : "y", right: isRotated ? null : "y2" }[type] : null, isLeftRight = /^(left|right)$/.test(type), isAxisInner = axisId && config["axis_" + axisId + "_inner"], isAxisShow = axisId && config["axis_" + axisId + "_show"], axesLen = axisId ? config["axis_" + axisId + "_axes"].length : 0; let axisSize = axisId ? isLeftRight ? $$.getAxisWidthByAxisId(axisId, withoutRecompute) : $$.getHorizontalAxisHeight(axisId) : 0; const defaultPadding = 20; let gap = 0; if (!isFitPadding && isLeftRight) { axisSize = ceil10(axisSize); } let padding = hasAxis && isLeftRight && (isAxisInner || isUndefined(paddingOption) && !isAxisShow) ? 0 : isFitPadding ? (isAxisShow ? axisSize : 0) + (paddingOption != null ? paddingOption : 0) : isUndefined(paddingOption) ? axisSize : paddingOption; if (isLeftRight && hasAxis) { if (axisId && (isFitPadding || isAxisInner) && config["axis_" + axisId + "_label"].text) { padding += $$.axis.getAxisLabelPosition(axisId).isOuter ? defaultPadding : 0; } if (type === "right") { padding += isRotated ? !isFitPadding && isUndefined(paddingOption) ? 10 : 2 : !isAxisShow || isAxisInner ? isFitPadding ? 2 : 1 : 0; padding += withXAxisTickTextOverflow ? $$.axis.getXAxisTickTextY2Overflow(defaultPadding) : 0; } else if (type === "left" && isRotated && isUndefined(paddingOption)) { padding = !config.axis_x_show ? 1 : isFitPadding ? axisSize : Math.max(axisSize, 40); } } else { if (type === "top") { if ($el.title && $el.title.node()) { padding += $$.getTitlePadding(); } gap = isRotated && !isAxisInner ? axesLen : 0; } else if (type === "bottom" && hasAxis && isRotated && !isAxisShow) { padding += 1; } } return padding + axisSize * axesLen - gap; }, getCurrentPadding: function getCurrentPadding(withXAxisTickTextOverflow) { var _this = this; if (withXAxisTickTextOverflow === void 0) { withXAxisTickTextOverflow = !1; } const $$ = this, _map = ["top", "bottom", "left", "right"].map(function (v) { _newArrowCheck(this, _this); return $$.getCurrentPaddingByDirection(v, null, withXAxisTickTextOverflow); }.bind(this)), top = _map[0], bottom = _map[1], left = _map[2], right = _map[3]; return { top: top, bottom: bottom, left: left, right: right }; }, /** * Get resetted padding values when 'padding=false' option is set * https://github.com/naver/billboard.js/issues/2367 * @param {number|object} v Padding values to be resetted * @returns {number|object} Padding value * @private */ getResettedPadding: function getResettedPadding(v) { var _this2 = this; const $$ = this, config = $$.config, isNum = isNumber(v); let p = isNum ? 0 : {}; if (config.padding === !1) { isNum || Object.keys(v).forEach(function (key) { _newArrowCheck(this, _this2); // when data.lables=true, do not reset top padding p[key] = !isEmpty(config.data_labels) && config.data_labels !== !1 && key === "top" ? v[key] : 0; }.bind(this)); } else { p = v; } return p; }, /** * Update size values * @param {boolean} isInit If is called at initialization * @private */ updateSizes: function updateSizes(isInit) { var _config$padding2; const $$ = this, config = $$.config, state = $$.state, legend = $$.$el.legend, isRotated = config.axis_rotated, isNonAxis = $$.hasArcType() || state.hasTreemap, isFitPadding = ((_config$padding2 = config.padding) == null ? void 0 : _config$padding2.mode) === "fit"; isInit || $$.setContainerSize(); const currLegend = { width: legend ? $$.getLegendWidth() : 0, height: legend ? $$.getLegendHeight() : 0 }; if (!isNonAxis && config.axis_x_show && config.axis_x_tick_autorotate) { $$.updateXAxisTickClip(); } const legendSize = { right: config.legend_show && state.isLegendRight ? $$.getLegendWidth() + (isFitPadding ? 0 : 20) : 0, bottom: !config.legend_show || state.isLegendRight || state.isLegendInset ? 0 : currLegend.height }, xAxisHeight = isRotated || isNonAxis ? 0 : $$.getHorizontalAxisHeight("x"), subchartXAxisHeight = config.subchart_axis_x_show && config.subchart_axis_x_tick_text_show ? xAxisHeight : 30, subchartHeight = config.subchart_show && !isNonAxis ? config.subchart_size_height + subchartXAxisHeight : 0, gaugeHeight = $$.hasType("gauge") && config.arc_needle_show && !config.gauge_fullCircle && !config.gauge_label_show ? 10 : 0, padding = $$.getCurrentPadding(!0); // when needle is shown with legend, it need some bottom space to not overlap with legend text // for main state.margin = !isNonAxis && isRotated ? { top: padding.top, right: isNonAxis ? 0 : padding.right + legendSize.right, bottom: legendSize.bottom + padding.bottom, left: subchartHeight + (isNonAxis ? 0 : padding.left) } : { top: (isFitPadding ? 0 : 4) + padding.top, // for top tick text right: isNonAxis ? 0 : padding.right + legendSize.right, bottom: gaugeHeight + subchartHeight + legendSize.bottom + padding.bottom, left: isNonAxis ? 0 : padding.left }; state.margin = $$.getResettedPadding(state.margin); // for subchart state.margin2 = isRotated ? { top: state.margin.top, right: NaN, bottom: 20 + legendSize.bottom, left: $$.state.rotatedPadding.left } : { top: state.current.height - subchartHeight - legendSize.bottom, right: NaN, bottom: subchartXAxisHeight + legendSize.bottom, left: state.margin.left }; // for legend state.margin3 = { top: 0, right: NaN, bottom: 0, left: 0 }; $$.updateSizeForLegend == null || $$.updateSizeForLegend(currLegend); state.width = state.current.width - state.margin.left - state.margin.right; state.height = state.current.height - state.margin.top - state.margin.bottom; if (state.width < 0) { state.width = 0; } if (state.height < 0) { state.height = 0; } state.width2 = isRotated ? state.margin.left - state.rotatedPadding.left - state.rotatedPadding.right : state.width; state.height2 = isRotated ? state.height : state.current.height - state.margin2.top - state.margin2.bottom; if (state.width2 < 0) { state.width2 = 0; } if (state.height2 < 0) { state.height2 = 0; } // for arc if ($$.hasArcType()) { const hasGauge = $$.hasType("gauge"), isLegendRight = config.legend_show && state.isLegendRight; state.arcWidth = state.width - (isLegendRight ? currLegend.width + 10 : 0); state.arcHeight = state.height - (isLegendRight && !hasGauge ? 0 : 10); if (hasGauge && !config.gauge_fullCircle) { state.arcHeight += state.height - $$.getPaddingBottomForGauge(); } $$.updateRadius == null || $$.updateRadius(); } if (state.isLegendRight && isNonAxis) { state.margin3.left = state.arcWidth / 2 + state.radiusExpanded * 1.1; } } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/style.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var style = ({ /** * Add props color css rule to given selector * @param {boolean} withShape Set shpes' prefix class * @param {string} selector CSS selector * @param {Array} props CSS props list * @param {Function} propsFn Function to retrieve value or determine for props * @returns {Function} * @private */ setCssRule: function setCssRule(withShape, selector, props, propsFn) { var _this = this; const $$ = this, config = $$.config, _$$$state = $$.state, cssRule = _$$$state.cssRule, style = _$$$state.style; return config.boost_useCssRule ? function (selection) { var _this2 = this; _newArrowCheck(this, _this); selection.each(function (d) { var _this3 = this; _newArrowCheck(this, _this2); const res = propsFn && (propsFn == null ? void 0 : propsFn.call($$, d)), shapeSelector = "" + (withShape ? "." + ($SHAPE.shapes + $$.getTargetSelectorSuffix(d.id)) : "") + selector; selector in cssRule && style.sheet.deleteRule(cssRule[shapeSelector]); $$.state.cssRule[shapeSelector] = addCssRules(style, shapeSelector, props.filter(Boolean).map(function (v) { _newArrowCheck(this, _this3); return isString(res) && v.indexOf(":") === -1 ? v + ": " + res : v || ""; }.bind(this))); }.bind(this)); }.bind(this) : function () { _newArrowCheck(this, _this); }.bind(this); }, /** * Get style prop value * @param {Function|string} v Value * @returns {string|null} * @private */ getStylePropValue: function getStylePropValue(v) { const useCssRule = this.config.boost_useCssRule; return useCssRule ? null : isFunction(v) ? v.bind(this) : v; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/text.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get text-anchor according text.labels.rotate angle * @param {number} angle Angle value * @returns {string} Anchor string value * @private */ function getRotateAnchor(angle) { let anchor = "middle"; if (angle > 0 && angle <= 170) { anchor = "end"; } else if (angle > 190 && angle <= 360) { anchor = "start"; } return anchor; } /** * Set rotated position coordinate according text.labels.rotate angle * @param {object} d Data object * @param {object} pos Position object * @param {object} pos.x x coordinate * @param {object} pos.y y coordinate * @param {string} anchor string value * @param {boolean} isRotated If axis is rotated * @param {boolean} isInverted If axis is inverted * @returns {object} x, y coordinate * @private */ function setRotatePos(d, pos, anchor, isRotated, isInverted) { var _$$$getCandlestickDat; const $$ = this, value = d.value, isCandlestickType = $$.isCandlestickType(d), isNegative = isNumber(value) && value < 0 || isCandlestickType && !((_$$$getCandlestickDat = $$.getCandlestickData(d)) != null && _$$$getCandlestickDat._isUp); let x = pos.x, y = pos.y; const gap = 4, doubleGap = 8; if (isRotated) { if (anchor === "start") { x += isNegative ? 0 : doubleGap; y += gap; } else if (anchor === "middle") { x += doubleGap; y -= doubleGap; } else if (anchor === "end") { isNegative && (x -= doubleGap); y += gap; } } else { if (anchor === "start") { x += gap; isNegative && (y += doubleGap * 2); } else if (anchor === "middle") { y -= doubleGap; } else if (anchor === "end") { x -= gap; isNegative && (y += doubleGap * 2); } if (isInverted) { y += isNegative ? -17 : isCandlestickType ? 13 : 7; } } return { x: x, y: y }; } /** * Get data.labels.position value * @param {object} d Data object * @param {string} type x | y * @returns {number} Position value * @private */ function getTextPos(d, type) { var _ref; const position = this.config.data_labels_position, id = d.id, index = d.index, value = d.value; return (_ref = isFunction(position) ? position.bind(this.api)(type, value, id, index, this.$el.text) : (id in position ? position[id] : position)[type]) != null ? _ref : 0; } /* harmony default export */ var internals_text = ({ opacityForText: function opacityForText(d) { const $$ = this; return $$.isBarType(d) && !$$.meetsLabelThreshold(Math.abs($$.getRatio("bar", d)), "bar") ? "0" : $$.hasDataLabel ? null : "0"; }, /** * Initializes the text * @private */ initText: function initText() { const $el = this.$el; $el.main.select("." + $COMMON.chart).append("g").attr("class", $TEXT.chartTexts).style("pointer-events", $el.treemap ? "none" : null); }, /** * Update chartText * @param {object} targets $$.data.targets * @private */ updateTargetsForText: function updateTargetsForText(targets) { var _this = this; const $$ = this, classChartText = $$.getChartClass("Text"), classTexts = $$.getClass("texts", "id"), classFocus = $$.classFocus.bind($$), mainTextUpdate = $$.$el.main.select("." + $TEXT.chartTexts).selectAll("." + $TEXT.chartText).data(targets).attr("class", function (d) { _newArrowCheck(this, _this); return ("" + classChartText(d) + classFocus(d)).trim(); }.bind(this)), mainTextEnter = mainTextUpdate.enter().append("g").style("opacity", "0").attr("class", classChartText).call($$.setCssRule(!0, " ." + $TEXT.text, ["fill", "pointer-events:none"], $$.updateTextColor)); mainTextEnter.append("g").attr("class", classTexts); }, /** * Update text * @private */ updateText: function updateText() { var _this2 = this; const $$ = this, $el = $$.$el, $T = $$.$T, config = $$.config, axis = $$.axis, classText = $$.getClass("text", "index"), labelsCentered = config.data_labels.centered, text = $el.main.selectAll("." + $TEXT.texts).selectAll("." + $TEXT.text).data($$.labelishData.bind($$)); $T(text.exit()).style("fill-opacity", "0").remove(); $el.text = text.enter().append("text").merge(text).attr("class", classText).attr("text-anchor", function (d) { _newArrowCheck(this, _this2); const isInverted = config["axis_" + (axis == null ? void 0 : axis.getId(d.id)) + "_inverted"]; // when value is negative or let isEndAnchor = isInverted ? d.value > 0 : d.value < 0; if ($$.isCandlestickType(d)) { const data = $$.getCandlestickData(d); isEndAnchor = !(data != null && data._isUp); } else if ($$.isTreemapType(d)) { return labelsCentered ? "middle" : "start"; } return config.axis_rotated ? isEndAnchor ? "end" : "start" : "middle"; }.bind(this)).style("fill", $$.getStylePropValue($$.updateTextColor)).style("fill-opacity", "0").each(function (d, i, texts) { const node = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this); let value = d.value; if ($$.isBubbleZType(d)) { value = $$.getBubbleZData(value, "z"); } else if ($$.isCandlestickType(d)) { const data = $$.getCandlestickData(d); if (data) { value = data.close; } } value = $$.isTreemapType(d) ? $$.treemapDataLabelFormat(d)(node) : $$.dataLabelFormat(d.id)(value, d.id, d.index, texts); if (isNumber(value)) { this.textContent = value; } else { setTextValue(node, value); } }); }, updateTextColor: function updateTextColor(d) { const $$ = this, config = $$.config, labelColors = config.data_labels_colors, defaultColor = $$.isArcType(d) && !$$.isRadarType(d) || $$.isTreemapType(d) ? null : $$.color(d); let color; if (isString(labelColors)) { color = labelColors; } else if (isObject(labelColors)) { const _ref2 = d.data || d, id = _ref2.id; color = labelColors[id]; } else if (isFunction(labelColors)) { color = labelColors.bind($$.api)(defaultColor, d); } if ($$.isCandlestickType(d) && !isFunction(labelColors)) { const value = $$.getCandlestickData(d); if (!(value != null && value._isUp)) { const downColor = config.candlestick_color_down; color = isObject(downColor) ? downColor[d.id] : downColor; } } return color || defaultColor; }, /** * Update data label text background color * @param {object} d Data object * @returns {string|null} * @private */ updateTextBackgroundColor: function updateTextBackgroundColor(d) { const $$ = this, $el = $$.$el, config = $$.config, backgroundColor = config.data_labels_backgroundColors; let color = ""; if (isString(backgroundColor) || isObject(backgroundColor)) { const id = isString(backgroundColor) ? "" : $$.getTargetSelectorSuffix("id" in d ? d.id : d.data.id), filter = $el.defs.select(["filter[id*='labels-bg", "']"].join(id)); if (filter.size()) { color = "url(#" + filter.attr("id") + ")"; } } return color || null; }, /** * Redraw chartText * @param {Function} getX Positioning function for x * @param {Function} getY Positioning function for y * @param {boolean} forFlow Weather is flow * @param {boolean} withTransition transition is enabled * @returns {Array} * @private */ redrawText: function redrawText(getX, getY, forFlow, withTransition) { const $$ = this, $T = $$.$T, axis = $$.axis, config = $$.config, hasTreemap = $$.state.hasTreemap, t = getRandom(!0), isRotated = config.axis_rotated, angle = config.data_labels.rotate, anchorString = getRotateAnchor(angle), rotateString = angle ? "rotate(" + angle + ")" : ""; $$.$el.text.style("fill", $$.getStylePropValue($$.updateTextColor)).attr("filter", $$.updateTextBackgroundColor.bind($$)).style("fill-opacity", forFlow ? 0 : $$.opacityForText.bind($$)).each(function (d, i) { // do not apply transition for newly added text elements const node = $T(hasTreemap && this.childElementCount ? this.parentNode : this, !!(withTransition && this.getAttribute("x")), t), isInverted = config["axis_" + (axis == null ? void 0 : axis.getId(d.id)) + "_inverted"]; let pos = { x: getX.bind(this)(d, i), y: getY.bind(this)(d, i) }; if (angle) { pos = setRotatePos.bind($$)(d, pos, anchorString, isRotated, isInverted); node.attr("text-anchor", anchorString); } // when is multiline if (this.childElementCount || angle) { node.attr("transform", "translate(" + pos.x + " " + pos.y + ") " + rotateString); } else { node.attr("x", pos.x).attr("y", pos.y); } }); // need to return 'true' as of being pushed to the redraw list // ref: getRedrawList() return !0; }, /** * Gets the getBoundingClientRect value of the element * @param {HTMLElement|d3.selection} element Target element * @param {string} className Class name * @returns {object} value of element.getBoundingClientRect() * @private */ getTextRect: function getTextRect(element, className) { var _this3 = this; const $$ = this; let base = element.node ? element.node() : element; if (!/text/i.test(base.tagName)) { base = base.querySelector("text"); } const text = base.textContent, cacheKey = KEY.textRect + "-" + text.replace(/\W/g, "_"); let rect = $$.cache.get(cacheKey); if (!rect) { $$.$el.svg.append("text").style("visibility", "hidden").style("font", (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(base).style("font")).classed(className, !0).text(text).call(function (v) { _newArrowCheck(this, _this3); rect = getBoundingRect(v.node()); }.bind(this)).remove(); $$.cache.add(cacheKey, rect); } return rect; }, /** * Gets the x or y coordinate of the text * @param {object} indices Indices values * @param {boolean} forX whether or not to x * @returns {number} coordinates * @private */ generateXYForText: function generateXYForText(indices, forX) { var _this4 = this; const $$ = this, _$$$state = $$.state, hasRadar = _$$$state.hasRadar, hasTreemap = _$$$state.hasTreemap, types = Object.keys(indices), points = {}, getter = forX ? $$.getXForText : $$.getYForText; hasRadar && types.push("radar"); hasTreemap && types.push("treemap"); types.forEach(function (v) { _newArrowCheck(this, _this4); points[v] = $$["generateGet" + capitalize(v) + "Points"](indices[v], !1); }.bind(this)); return function (d, i) { const type = $$.isAreaType(d) && "area" || $$.isBarType(d) && "bar" || $$.isCandlestickType(d) && "candlestick" || $$.isRadarType(d) && "radar" || $$.isTreemapType(d) && "treemap" || "line"; return getter.call($$, points[type](d, i), d, this); }; }, /** * Get centerized text position for bar type data.label.text * @param {object} d Data object * @param {Array} points Data points position * @param {HTMLElement} textElement Data label text element * @param {string} type 'x' or 'y' * @returns {number} Position value * @private */ getCenteredTextPos: function getCenteredTextPos(d, points, textElement, type) { const $$ = this, config = $$.config, isRotated = config.axis_rotated, isBarType = $$.isBarType(d), isTreemapType = $$.isTreemapType(d); if (config.data_labels.centered && (isBarType || isTreemapType)) { const rect = getBoundingRect(textElement); if (isBarType) { const isPositive = $$.getRangedData(d, null, "bar") >= 0; if (isRotated) { const w = (isPositive ? points[1][1] - points[0][1] : points[0][1] - points[1][1]) / 2 + rect.width / 2; return isPositive ? -w - 3 : w + 2; } else { const h = (isPositive ? points[0][1] - points[1][1] : points[1][1] - points[0][1]) / 2 + rect.height / 2; return isPositive ? h : -h - 2; } } else if (isTreemapType) { return type === "x" ? (points[1][0] - points[0][0]) / 2 : (points[1][1] - points[0][1]) / 2 + rect.height / 2; } } return 0; }, /** * Gets the x coordinate of the text * @param {object} points Data points position * @param {object} d Data object * @param {HTMLElement} textElement Data label text element * @returns {number} x coordinate * @private */ getXForText: function getXForText(points, d, textElement) { const $$ = this, config = $$.config, isRotated = config.axis_rotated, isTreemapType = $$.isTreemapType(d); let xPos = points[0][0]; if ($$.isCandlestickType(d)) { if (isRotated) { var _$$$getCandlestickDat2; xPos = (_$$$getCandlestickDat2 = $$.getCandlestickData(d)) != null && _$$$getCandlestickDat2._isUp ? points[2][2] + 4 : points[2][1] - 4; } else { xPos += (points[1][0] - xPos) / 2; } } else if (isTreemapType) { xPos += config.data_labels.centered ? 0 : 5; } else { if (isRotated) { const isInverted = config["axis_" + $$.axis.getId(d.id) + "_inverted"], padding = $$.isBarType(d) ? 4 : 6, value = d.value; xPos = points[2][1]; if (isInverted) { xPos -= padding * (value > 0 ? 1 : -1); } else { xPos += padding * (value < 0 ? -1 : 1); } } else { xPos = $$.hasType("bar") ? (points[2][0] + points[0][0]) / 2 : xPos; } } if (isRotated || isTreemapType) { xPos += $$.getCenteredTextPos(d, points, textElement, "x"); } return xPos + getTextPos.call(this, d, "x"); }, /** * Gets the y coordinate of the text * @param {object} points Data points position * @param {object} d Data object * @param {HTMLElement} textElement Data label text element * @returns {number} y coordinate * @private */ getYForText: function getYForText(points, d, textElement) { const $$ = this, axis = $$.axis, config = $$.config, state = $$.state, isRotated = config.axis_rotated, isInverted = config["axis_" + (axis == null ? void 0 : axis.getId(d.id)) + "_inverted"], isBarType = $$.isBarType(d), isTreemapType = $$.isTreemapType(d), r = config.point_r, rect = getBoundingRect(textElement); let value = d.value, baseY = 3, yPos; if ($$.isCandlestickType(d)) { value = $$.getCandlestickData(d); if (isRotated) { yPos = points[0][0]; yPos += (points[1][0] - yPos) / 2 + baseY; } else { yPos = value && value._isUp ? points[2][2] - baseY : points[2][1] + baseY * 4; if (isInverted) { yPos += 15 * (value._isUp ? 1 : -1); } } } else if (isTreemapType) { yPos = points[0][1] + (config.data_labels.centered ? 0 : rect.height + 5); } else { if (isRotated) { yPos = (points[0][0] + points[2][0] + rect.height * .6) / 2; } else { yPos = points[2][1]; if (isNumber(r) && r > 5 && ($$.isLineType(d) || $$.isScatterType(d))) { baseY += config.point_r / 2.3; } if (value < 0 || value === 0 && !state.hasPositiveValue && state.hasNegativeValue) { yPos += isInverted ? isBarType ? -3 : -5 : rect.height + (isBarType ? -baseY : baseY); } else { let diff = -baseY * 2; if (isBarType) { diff = -baseY; } else if ($$.isBubbleType(d)) { diff = baseY; } if (isInverted) { diff = isBarType ? 10 : 15; } yPos += diff; } } } if (!isRotated || isTreemapType) { yPos += $$.getCenteredTextPos(d, points, textElement, "y"); } return yPos + getTextPos.call(this, d, "y"); }, /** * Calculate if two or more text nodes are overlapping * Mark overlapping text nodes with "text-overlapping" class * @param {string} id Axis id * @param {ChartInternal} $$ ChartInternal context * @param {string} selector Selector string * @private */ markOverlapped: function markOverlapped(id, $$, selector) { var _this5 = this; const textNodes = $$.$el.arcs.selectAll(selector), filteredTextNodes = textNodes.filter(function (node) { _newArrowCheck(this, _this5); return node.data.id !== id; }.bind(this)), textNode = textNodes.filter(function (node) { _newArrowCheck(this, _this5); return node.data.id === id; }.bind(this)), translate = getTranslation(textNode.node()), calcHypo = function (x, y) { _newArrowCheck(this, _this5); return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); }.bind(this); // Calculates the length of the hypotenuse textNode.node() && filteredTextNodes.each(function () { const coordinate = getTranslation(this), filteredTextNode = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(this), nodeForWidth = calcHypo(translate.e, translate.f) > calcHypo(coordinate.e, coordinate.f) ? textNode : filteredTextNode, overlapsX = Math.ceil(Math.abs(translate.e - coordinate.e)) < Math.ceil(nodeForWidth.node().getComputedTextLength()), overlapsY = Math.ceil(Math.abs(translate.f - coordinate.f)) < parseInt(textNode.style("font-size"), 10); filteredTextNode.classed($TEXT.TextOverlapping, overlapsX && overlapsY); }); }, /** * Calculate if two or more text nodes are overlapping * Remove "text-overlapping" class on selected text nodes * @param {ChartInternal} $$ ChartInternal context * @param {string} selector Selector string * @private */ undoMarkOverlapped: function undoMarkOverlapped($$, selector) { $$.$el.arcs.selectAll(selector).each(function () { (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.selectAll)([this, this.previousSibling]).classed($TEXT.TextOverlapping, !1); }); }, /** * Check if meets the ratio to show data label text * @param {number} ratio ratio to meet * @param {string} type chart type * @returns {boolean} * @private */ meetsLabelThreshold: function meetsLabelThreshold(ratio, type) { if (ratio === void 0) { ratio = 0; } const $$ = this, config = $$.config, threshold = config[type + "_label_threshold"] || 0; return ratio >= threshold; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/title.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Get the text position * @param {string} pos right, left or center * @param {number} width chart width * @returns {string|number} text-anchor value or position in pixel * @private */ function getTextXPos(pos, width) { if (pos === void 0) { pos = "left"; } const isNum = isNumber(width); let position; if (pos.indexOf("center") > -1) { position = isNum ? width / 2 : "middle"; } else if (pos.indexOf("right") > -1) { position = isNum ? width : "end"; } else { position = isNum ? 0 : "start"; } return position; } /* harmony default export */ var internals_title = ({ /** * Initializes the title * @private */ initTitle: function initTitle() { const $$ = this, config = $$.config, $el = $$.$el; if (config.title_text) { $el.title = $el.svg.append("g"); const text = $el.title.append("text").style("text-anchor", getTextXPos(config.title_position)).attr("class", $TEXT.title); setTextValue(text, config.title_text, [.3, 1.5]); } }, /** * Redraw title * @private */ redrawTitle: function redrawTitle() { const $$ = this, config = $$.config, current = $$.state.current, title = $$.$el.title; if (title) { const x = getTextXPos(config.title_position, current.width), y = (config.title_padding.top || 0) + $$.getTextRect($$.$el.title, $TEXT.title).height; title.attr("transform", "translate(" + x + ", " + y + ")"); } }, /** * Get title padding * @returns {number} padding value * @private */ getTitlePadding: function getTitlePadding() { const $$ = this, $el = $$.$el, config = $$.config; return (config.title_padding.top || 0) + $$.getTextRect($el.title, $TEXT.title).height + (config.title_padding.bottom || 0); } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/tooltip.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var internals_tooltip = ({ /** * Initializes the tooltip * @private */ initTooltip: function initTooltip() { const $$ = this, config = $$.config, $el = $$.$el; $el.tooltip = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(config.tooltip_contents.bindto); if ($el.tooltip.empty()) { $el.tooltip = $el.chart.append("div").attr("class", $TOOLTIP.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none"); } $$.bindTooltipResizePos(); }, /** * Show tooltip at initialization. * Is called only when tooltip.init.show=true option is set * @private */ initShowTooltip: function initShowTooltip() { const $$ = this, config = $$.config, $el = $$.$el, _$$$state = $$.state, hasAxis = _$$$state.hasAxis, hasRadar = _$$$state.hasRadar; // Show tooltip if needed if (config.tooltip_init_show) { var _$$$axis, _data; if ((_$$$axis = $$.axis) != null && _$$$axis.isTimeSeries() && isString(config.tooltip_init_x)) { config.tooltip_init_x = parseDate.call($$, config.tooltip_init_x); } $$.api.tooltip.show({ data: (_data = {}, _data[!(hasAxis || hasRadar) ? "index" : "x"] = config.tooltip_init_x, _data) }); const position = config.tooltip_init_position; if (!config.tooltip_contents.bindto && !isEmpty(position)) { const _position$top = position.top, top = _position$top === void 0 ? 0 : _position$top, _position$left = position.left, left = _position$left === void 0 ? 50 : _position$left; $el.tooltip.style("top", isString(top) ? top : top + "px").style("left", isString(left) ? left : left + "px").style("display", null); } } }, /** * Get the tooltip HTML string * @param {Array} args Arguments * @returns {string} Formatted HTML string * @private */ getTooltipHTML: function getTooltipHTML() { const $$ = this, api = $$.api, config = $$.config; return isFunction(config.tooltip_contents) ? config.tooltip_contents.bind(api).apply(void 0, arguments) : $$.getTooltipContent.apply($$, arguments); }, /** * Returns the tooltip content(HTML string) * @param {object} d data * @param {Function} defaultTitleFormat Default title format * @param {Function} defaultValueFormat Default format for each data value in the tooltip. * @param {Function} color Color function * @returns {string} html * @private */ getTooltipContent: function getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) { var _this = this; const $$ = this, api = $$.api, config = $$.config, state = $$.state, $el = $$.$el, _map = ["title", "name", "value"].map(function (v) { _newArrowCheck(this, _this); const fn = config["tooltip_format_" + v]; return isFunction(fn) ? fn.bind(api) : fn; }.bind(this)), titleFn = _map[0], nameFn = _map[1], valueFn = _map[2], titleFormat = function () { _newArrowCheck(this, _this); return sanitize((titleFn || defaultTitleFormat).apply(void 0, arguments)); }.bind(this), nameFormat = function () { var _this2 = this; _newArrowCheck(this, _this); return sanitize((nameFn || function (name) { _newArrowCheck(this, _this2); return name; }.bind(this)).apply(void 0, arguments)); }.bind(this), valueFormat = function () { var _this3 = this; _newArrowCheck(this, _this); const fn = valueFn || (state.hasTreemap || $$.isStackNormalized() ? function (v, ratio) { _newArrowCheck(this, _this3); return (ratio * 100).toFixed(2) + "%"; }.bind(this) : defaultValueFormat); return sanitize(fn.apply(void 0, arguments)); }.bind(this), order = config.tooltip_order, getRowValue = function (row) { _newArrowCheck(this, _this); return $$.axis && $$.isBubbleZType(row) ? $$.getBubbleZData(row.value, "z") : $$.getBaseValue(row); }.bind(this), getBgColor = $$.levelColor ? function (row) { _newArrowCheck(this, _this); return $$.levelColor(row.value); }.bind(this) : function (row) { _newArrowCheck(this, _this); return color(row); }.bind(this), contents = config.tooltip_contents, tplStr = contents.template, targetIds = $$.mapToTargetIds(); // get formatter function // determine fotmatter function with sanitization if (order === null && config.data_groups.length) { // for stacked data, order should aligned with the visually displayed data const ids = $$.orderTargets($$.data.targets).map(function (i2) { _newArrowCheck(this, _this); return i2.id; }.bind(this)).reverse(); d.sort(function (a, b) { _newArrowCheck(this, _this); let v1 = a ? a.value : null, v2 = b ? b.value : null; if (v1 > 0 && v2 > 0) { v1 = a.id ? ids.indexOf(a.id) : null; v2 = b.id ? ids.indexOf(b.id) : null; } return v1 - v2; }.bind(this)); } else if (/^(asc|desc)$/.test(order)) { d.sort(function (a, b) { _newArrowCheck(this, _this); const v1 = a ? getRowValue(a) : null, v2 = b ? getRowValue(b) : null; return order === "asc" ? v1 - v2 : v2 - v1; }.bind(this)); } else if (isFunction(order)) { d.sort(order.bind(api)); } const tpl = $$.getTooltipContentTemplate(tplStr), len = d.length; let text, row, param, value, i; for (i = 0; i < len; i++) { row = d[i]; if (!row || !(getRowValue(row) || getRowValue(row) === 0)) { continue; } if (isUndefined(text)) { const title = (state.hasAxis || state.hasRadar) && titleFormat(row.x); text = tplProcess(tpl[0], { CLASS_TOOLTIP: $TOOLTIP.tooltip, TITLE: isValue(title) ? tplStr ? title : "" + title + "" : "" }); } if (!row.ratio && $el.arcs) { param = ["arc", $$.$el.arcs.select("path." + $ARC.arc + "-" + row.id).data()[0]]; row.ratio = $$.getRatio.apply($$, param); } // arrange param to be passed to formatter param = [row.ratio, row.id, row.index]; if ($$.isAreaRangeType(row)) { const _map2 = ["high", "low"].map(function (v) { _newArrowCheck(this, _this); return valueFormat.apply(void 0, [$$.getRangedData(row, v)].concat(param)); }.bind(this)), high = _map2[0], low = _map2[1], mid = valueFormat.apply(void 0, [getRowValue(row)].concat(param)); value = "Mid: " + mid + " High: " + high + " Low: " + low; } else if ($$.isCandlestickType(row)) { const _map3 = ["open", "high", "low", "close", "volume"].map(function (v) { _newArrowCheck(this, _this); const value = $$.getRangedData(row, v, "candlestick"); return value ? valueFormat.apply(void 0, [$$.getRangedData(row, v, "candlestick")].concat(param)) : undefined; }.bind(this)), open = _map3[0], high = _map3[1], low = _map3[2], close = _map3[3], volume = _map3[4]; value = "Open: " + open + " High: " + high + " Low: " + low + " Close: " + close + (volume ? " Volume: " + volume : ""); } else if ($$.isBarRangeType(row)) { const _row = row, rangeValue = _row.value, id = _row.id, index = _row.index; value = "" + valueFormat(rangeValue, undefined, id, index); } else { value = valueFormat.apply(void 0, [getRowValue(row)].concat(param)); } if (value !== undefined) { // Skip elements when their name is set to null if (row.name === null) { continue; } const name = nameFormat.apply(void 0, [row.name].concat(param)), color = getBgColor(row), contentValue = { CLASS_TOOLTIP_NAME: $TOOLTIP.tooltipName + $$.getTargetSelectorSuffix(row.id), COLOR: tplStr || !$$.patterns ? color : "", NAME: name, VALUE: value }; if (tplStr && isObject(contents.text)) { const index = targetIds.indexOf(row.id); Object.keys(contents.text).forEach(function (key) { _newArrowCheck(this, _this); contentValue[key] = contents.text[key][index]; }.bind(this)); } text += tplProcess(tpl[1], contentValue); } } return text + ""; }, /** * Get the content template string * @param {string} tplStr Tempalte string * @returns {Array} Template string * @private */ getTooltipContentTemplate: function getTooltipContentTemplate(tplStr) { return (tplStr || "\n\t\t\t\t{=TITLE}\n\t\t\t\t{{\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t}}\n\t\t\t
    " + (this.patterns ? "{=COLOR}" : "") + "{=NAME}{=VALUE}
    ").replace(/(\r?\n|\t)/g, "").split(/{{(.*)}}/); }, /** * Update tooltip position coordinate * @param {object} dataToShow Data object * @param {SVGElement} eventTarget Event element * @private */ setTooltipPosition: function setTooltipPosition(dataToShow, eventTarget) { var _this4 = this; const $$ = this, config = $$.config, scale = $$.scale, state = $$.state, _$$$$el = $$.$el, eventRect = _$$$$el.eventRect, tooltip = _$$$$el.tooltip, bindto = config.tooltip_contents.bindto, isRotated = config.axis_rotated, datum = tooltip == null ? void 0 : tooltip.datum(); if (!bindto && datum) { var _config$tooltip_posit, _config$tooltip_posit2; const data = dataToShow != null ? dataToShow : JSON.parse(datum.current), _getPointer = getPointer(state.event, eventTarget != null ? eventTarget : eventRect == null ? void 0 : eventRect.node()), x = _getPointer[0], y = _getPointer[1], currPos = { x: x, y: y }; // get mouse event position if (state.hasAxis && scale.x && datum && "x" in datum) { const getYPos = function (value, id, axisId) { var _$$$axis2; if (value === void 0) { value = 0; } if (axisId === void 0) { axisId = "y"; } _newArrowCheck(this, _this4); const scaleFn = scale[id ? (_$$$axis2 = $$.axis) == null ? void 0 : _$$$axis2.getId(id) : axisId]; return scaleFn ? scaleFn(value) + (isRotated ? state.margin.left : state.margin.top) : 0; }.bind(this); currPos.xAxis = scale.x(datum.x) + ( // add margin only when user specified tooltip.position function config.tooltip_position ? isRotated ? state.margin.top : state.margin.left : 0); if (data.length === 1) { currPos.yAxis = getYPos(data[0].value, data[0].id); } else { currPos.yAxis = getYPos; } } const _datum$width = datum.width, width = _datum$width === void 0 ? 0 : _datum$width, _datum$height = datum.height, height = _datum$height === void 0 ? 0 : _datum$height, pos = (_config$tooltip_posit = (_config$tooltip_posit2 = config.tooltip_position) == null ? void 0 : _config$tooltip_posit2.bind($$.api)(data, width, height, eventRect == null ? void 0 : eventRect.node(), currPos)) != null ? _config$tooltip_posit : $$.getTooltipPosition.bind($$)(width, height, currPos); // Get tooltip position ["top", "left"].forEach(function (v) { _newArrowCheck(this, _this4); const value = pos[v]; tooltip.style(v, value + "px"); // Remember left pos in percentage to be used on resize call if (v === "left" && !datum.xPosInPercent) { datum.xPosInPercent = value / state.current.width * 100; } }.bind(this)); } }, /** * Returns the position of the tooltip * @param {string} tWidth Width value of tooltip element * @param {string} tHeight Height value of tooltip element * @param {object} currPos Current mouse position * @returns {object} top, left value * @private */ getTooltipPosition: function getTooltipPosition(tWidth, tHeight, currPos) { var _this5 = this; const $$ = this, config = $$.config, scale = $$.scale, state = $$.state, _state = state, width = _state.width, height = _state.height, current = _state.current, isLegendRight = _state.isLegendRight, inputType = _state.inputType, hasGauge = $$.hasType("gauge") && !config.gauge_fullCircle, hasTreemap = state.hasTreemap, isRotated = config.axis_rotated, hasArcType = $$.hasArcType(), svgLeft = $$.getSvgLeft(!0); let chartRight = svgLeft + current.width - $$.getCurrentPaddingByDirection("right"); const size = 20; let x = currPos.x, y = currPos.y; // Determine tooltip position if (hasArcType) { const raw = inputType === "touch" || $$.hasType("radar"); if (!raw) { x += (width - (isLegendRight ? $$.getLegendWidth() : 0)) / 2; y += hasGauge ? height : height / 2; } } else if (!hasTreemap) { const padding = { top: $$.getCurrentPaddingByDirection("top", !0), left: $$.getCurrentPaddingByDirection("left", !0) }; if (isRotated) { x += svgLeft + padding.left + size; y = padding.top + currPos.xAxis + size; chartRight -= svgLeft; } else { x = svgLeft + padding.left + size + (scale.zoom ? x : currPos.xAxis); y += padding.top - 5; } } // when tooltip left + tWidth > chart's width if (x + tWidth + 15 > chartRight) { x -= tWidth + (hasTreemap || hasArcType ? 0 : isRotated ? 40 : 38); } if (y + tHeight > current.height) { const gap = hasTreemap ? 0 : 30; y -= hasGauge ? tHeight * 3 : tHeight + gap; } const pos = { top: y, left: x }; // make sure to not be positioned out of viewport Object.keys(pos).forEach(function (v) { _newArrowCheck(this, _this5); if (pos[v] < 0) { pos[v] = 0; } }.bind(this)); return pos; }, /** * Show the tooltip * @param {object} selectedData Data object * @param {SVGElement} eventTarget Event element * @private */ showTooltip: function showTooltip(selectedData, eventTarget) { var _this6 = this; const $$ = this, config = $$.config, tooltip = $$.$el.tooltip, dataToShow = selectedData.filter(function (d) { _newArrowCheck(this, _this6); return d && isValue($$.getBaseValue(d)); }.bind(this)); if (!tooltip || dataToShow.length === 0 || !config.tooltip_show) { return; } let datum = tooltip.datum(); const dataStr = JSON.stringify(selectedData); if (!datum || datum.current !== dataStr) { const _selectedData$concat$ = selectedData.concat().sort()[0], index = _selectedData$concat$.index, x = _selectedData$concat$.x; callFn(config.tooltip_onshow, $$.api, selectedData); // set tooltip content tooltip.html($$.getTooltipHTML(selectedData, // data $$.axis ? $$.axis.getXAxisTickFormat() : $$.categoryName.bind($$), // defaultTitleFormat $$.getDefaultValueFormat(), // defaultValueFormat $$.color // color )).style("display", null).style("visibility", null) // for IE9 .datum(datum = { index: index, x: x, current: dataStr, width: tooltip.property("offsetWidth"), height: tooltip.property("offsetHeight") }); callFn(config.tooltip_onshown, $$.api, selectedData); $$._handleLinkedCharts(!0, index); } $$.setTooltipPosition(dataToShow, eventTarget); }, /** * Adjust tooltip position on resize event * @private */ bindTooltipResizePos: function bindTooltipResizePos() { var _this7 = this; const $$ = this, resizeFunction = $$.resizeFunction, state = $$.state, tooltip = $$.$el.tooltip; resizeFunction.add(function () { _newArrowCheck(this, _this7); if (tooltip.style("display") === "block") { const current = state.current, _tooltip$datum = tooltip.datum(), width = _tooltip$datum.width, xPosInPercent = _tooltip$datum.xPosInPercent; let value = current.width / 100 * xPosInPercent; const diff = current.width - (value + width); // if tooltip size overs current viewport size if (diff < 0) { value += diff; } tooltip.style("left", value + "px"); } }.bind(this)); }, /** * Hide the tooltip * @param {boolean} force Force to hide * @private */ hideTooltip: function hideTooltip(force) { const $$ = this, api = $$.api, config = $$.config, tooltip = $$.$el.tooltip; if (tooltip && tooltip.style("display") !== "none" && (!config.tooltip_doNotHide || force)) { var _tooltip$datum$curren; const selectedData = JSON.parse((_tooltip$datum$curren = tooltip.datum().current) != null ? _tooltip$datum$curren : {}); callFn(config.tooltip_onhide, api, selectedData); // hide tooltip tooltip.style("display", "none").style("visibility", "hidden") // for IE9 .datum(null); callFn(config.tooltip_onhidden, api, selectedData); } }, /** * Toggle display for linked chart instances * @param {boolean} show true: show, false: hide * @param {number} index x Axis index * @private */ _handleLinkedCharts: function _handleLinkedCharts(show, index) { var _this8 = this; const $$ = this, charts = $$.charts, config = $$.config, event = $$.state.event; // Prevent propagation among instances if isn't instantiated from the user's event // https://github.com/naver/billboard.js/issues/1979 if (event != null && event.isTrusted && config.tooltip_linked && charts.length > 1) { const linkedName = config.tooltip_linked_name; charts.filter(function (c) { _newArrowCheck(this, _this8); return c !== $$.api; }.bind(this)).forEach(function (c) { _newArrowCheck(this, _this8); const _c$internal = c.internal, config = _c$internal.config, $el = _c$internal.$el, isLinked = config.tooltip_linked, name = config.tooltip_linked_name, isInDom = browser_doc.body.contains($el.chart.node()); if (isLinked && linkedName === name && isInDom) { const data = $el.tooltip.data()[0], isNotSameIndex = index !== (data == null ? void 0 : data.index); try { c.tooltip[show && isNotSameIndex ? "show" : "hide"]({ index: index }); } catch (e) {} } }.bind(this)); } }, /** * Update tooltip content on redraw * - In a situation where tooltip is displayed and data load happens, it should reflect loaded data to tooltip * @param {d3Selection} context Event rect element * @param {number} index Data index * @private */ updateTooltipOnRedraw: function updateTooltipOnRedraw(context, index) { var _this9 = this; const $$ = this, config = $$.config, _$$$$el2 = $$.$el, eventRect = _$$$$el2.eventRect, svg = _$$$$el2.svg, tooltip = _$$$$el2.tooltip, _$$$state2 = $$.state, event = _$$$state2.event, hasAxis = _$$$state2.hasAxis, hasRadar = _$$$state2.hasRadar, hasTreemap = _$$$state2.hasTreemap; // Update tooltip, when tooltip is in shown state if ((tooltip == null ? void 0 : tooltip.style("display")) === "block" && event) { var _ref; const rect = context != null ? context : (_ref = hasRadar ? svg : eventRect) == null ? void 0 : _ref.node(); // for Axis based & Radar if (hasAxis || hasRadar) { if ($$.isMultipleX()) { $$.selectRectForMultipleXs(rect, !1); } else { const idx = index != null ? index : $$.getDataIndexFromEvent(event); if (index === -1) { $$.api.tooltip.hide(); } else { $$.selectRectForSingle(rect, idx); $$.setExpand(idx, null, !0); } } // for Arc & Treemap } else { const clientX = event.clientX, clientY = event.clientY; setTimeout(function () { _newArrowCheck(this, _this9); let target = browser_doc.elementFromPoint(clientX, clientY); const data = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(target).datum(); if (data) { const d = $$.hasArcType() ? $$.convertToArcData($$.updateAngle(data)) : data == null ? void 0 : data.data; hasTreemap && (target = svg.node()); d && $$.showTooltip([d], target); } else { $$.api.tooltip.hide(); } }.bind(this), config.transition_duration); } } } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/transform.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var transform = ({ getTranslate: function getTranslate(target, index) { if (index === void 0) { index = 0; } const $$ = this, config = $$.config, state = $$.state, isRotated = config.axis_rotated; let padding = 0, x, y; if (index && /^(x|y2?)$/.test(target)) { padding = $$.getAxisSize(target) * index; } if (target === "main") { x = asHalfPixel(state.margin.left); y = asHalfPixel(state.margin.top); } else if (target === "context") { x = asHalfPixel(state.margin2.left); y = asHalfPixel(state.margin2.top); } else if (target === "legend") { x = state.margin3.left; y = state.margin3.top; } else if (target === "x") { x = isRotated ? -padding : 0; y = isRotated ? 0 : state.height + padding; } else if (target === "y") { x = isRotated ? 0 : -padding; y = isRotated ? state.height + padding : 0; } else if (target === "y2") { x = isRotated ? 0 : state.width + padding; y = isRotated ? -padding - 1 : 0; } else if (target === "subX") { x = 0; y = isRotated ? 0 : state.height2; } else if (target === "arc") { x = state.arcWidth / 2; y = state.arcHeight / 2; } else if (target === "polar") { x = state.arcWidth / 2; y = state.arcHeight / 2; } else if (target === "radar") { const _$$$getRadarSize = $$.getRadarSize(), width = _$$$getRadarSize[0]; x = state.width / 2 - width; y = asHalfPixel(state.margin.top); } return "translate(" + x + ", " + y + ")"; }, transformMain: function transformMain(withTransition, transitions) { const $$ = this, main = $$.$el.main, $T = $$.$T, xAxis = transitions != null && transitions.axisX ? transitions.axisX : $T(main.select("." + $AXIS.axisX), withTransition), yAxis = transitions != null && transitions.axisY ? transitions.axisY : $T(main.select("." + $AXIS.axisY), withTransition), y2Axis = transitions != null && transitions.axisY2 ? transitions.axisY2 : $T(main.select("." + $AXIS.axisY2), withTransition); $T(main, withTransition).attr("transform", $$.getTranslate("main")); xAxis.attr("transform", $$.getTranslate("x")); yAxis.attr("transform", $$.getTranslate("y")); y2Axis.attr("transform", $$.getTranslate("y2")); main.select("." + $ARC.chartArcs).attr("transform", $$.getTranslate("arc")); }, transformAll: function transformAll(withTransition, transitions) { const $$ = this, config = $$.config, _$$$state = $$.state, hasAxis = _$$$state.hasAxis, hasTreemap = _$$$state.hasTreemap, $el = $$.$el; hasTreemap || $$.transformMain(withTransition, transitions); hasAxis && config.subchart_show && $$.transformContext(withTransition, transitions); $el.legend && $$.transformLegend(withTransition); } }); ;// CONCATENATED MODULE: ./src/ChartInternal/internals/type.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var type = ({ /** * Check if the given chart type is valid * @param {string} type Chart type string * @returns {boolean} * @private */ isValidChartType: function isValidChartType(type) { return !!(type && Object.values(TYPE).indexOf(type) > -1); }, setTargetType: function setTargetType(targetIds, type) { var _this = this; const $$ = this, config = $$.config, withoutFadeIn = $$.state.withoutFadeIn; $$.mapToTargetIds(targetIds).forEach(function (id) { _newArrowCheck(this, _this); withoutFadeIn[id] = type === config.data_types[id]; config.data_types[id] = type; }.bind(this)); if (!targetIds) { config.data_type = type; } }, /** * Updte current used chart types * @private */ updateTypesElements: function updateTypesElements() { var _this2 = this; const $$ = this, current = $$.state.current; Object.keys(TYPE).forEach(function (v) { _newArrowCheck(this, _this2); const t = TYPE[v], has = $$.hasType(t, null, !0), idx = current.types.indexOf(t); if (idx === -1 && has) { current.types.push(t); } else if (idx > -1 && !has) { current.types.splice(idx, 1); } }.bind(this)); // Update current chart elements reference $$.setChartElements(); }, /** * Check if given chart types exists * @param {string} type Chart type * @param {Array} targetsValue Data array * @param {boolean} checkFromData Force to check type cotains from data targets * @returns {boolean} * @private */ hasType: function hasType(type, targetsValue, checkFromData) { var _current$types, _this3 = this; if (checkFromData === void 0) { checkFromData = !1; } const $$ = this, config = $$.config, current = $$.state.current, types = config.data_types, targets = targetsValue || $$.data.targets; let has = !1; if (!checkFromData && ((_current$types = current.types) == null ? void 0 : _current$types.indexOf(type)) > -1) { has = !0; } else if (targets != null && targets.length) { targets.forEach(function (target) { _newArrowCheck(this, _this3); const t = types[target.id]; if (t === type || !t && type === "line") { has = !0; } }.bind(this)); } else if (Object.keys(types).length) { Object.keys(types).forEach(function (id) { _newArrowCheck(this, _this3); if (types[id] === type) { has = !0; } }.bind(this)); } else { has = config.data_type === type; } return has; }, /** * Check if contains given chart types * @param {string} type Type key * @param {object} targets Target data * @param {Array} exclude Excluded types * @returns {boolean} * @private */ hasTypeOf: function hasTypeOf(type, targets, exclude) { var _this4 = this; if (exclude === void 0) { exclude = []; } if (type in TYPE_BY_CATEGORY) { return !TYPE_BY_CATEGORY[type].filter(function (v) { _newArrowCheck(this, _this4); return exclude.indexOf(v) === -1; }.bind(this)).every(function (v) { _newArrowCheck(this, _this4); return !this.hasType(v, targets); }.bind(this)); } return !1; }, /** * Check if given data is certain chart type * @param {object} d Data object * @param {string|Array} type chart type * @returns {boolean} * @private */ isTypeOf: function isTypeOf(d, type) { const id = isString(d) ? d : d.id, dataType = this.config.data_types[id] || this.config.data_type; return isArray(type) ? type.indexOf(dataType) >= 0 : dataType === type; }, hasPointType: function hasPointType() { const $$ = this; return $$.hasTypeOf("Line") || $$.hasType("bubble") || $$.hasType("scatter"); }, /** * Check if contains arc types chart * @param {object} targets Target data * @param {Array} exclude Excluded types * @returns {boolean} * @private */ hasArcType: function hasArcType(targets, exclude) { return this.hasTypeOf("Arc", targets, exclude); }, hasMultiArcGauge: function hasMultiArcGauge() { return this.hasType("gauge") && this.config.gauge_type === "multi"; }, isLineType: function isLineType(d) { const id = isString(d) ? d : d.id; return !this.config.data_types[id] || this.isTypeOf(id, TYPE_BY_CATEGORY.Line); }, isStepType: function isStepType(d) { return this.isTypeOf(d, TYPE_BY_CATEGORY.Step); }, isSplineType: function isSplineType(d) { return this.isTypeOf(d, TYPE_BY_CATEGORY.Spline); }, isAreaType: function isAreaType(d) { return this.isTypeOf(d, TYPE_BY_CATEGORY.Area); }, isAreaRangeType: function isAreaRangeType(d) { return this.isTypeOf(d, TYPE_BY_CATEGORY.AreaRange); }, isBarType: function isBarType(d) { return this.isTypeOf(d, "bar"); }, isBubbleType: function isBubbleType(d) { return this.isTypeOf(d, "bubble"); }, isCandlestickType: function isCandlestickType(d) { return this.isTypeOf(d, "candlestick"); }, isScatterType: function isScatterType(d) { return this.isTypeOf(d, "scatter"); }, isTreemapType: function isTreemapType(d) { return this.isTypeOf(d, "treemap"); }, isPieType: function isPieType(d) { return this.isTypeOf(d, "pie"); }, isGaugeType: function isGaugeType(d) { return this.isTypeOf(d, "gauge"); }, isDonutType: function isDonutType(d) { return this.isTypeOf(d, "donut"); }, isPolarType: function isPolarType(d) { return this.isTypeOf(d, "polar"); }, isRadarType: function isRadarType(d) { return this.isTypeOf(d, "radar"); }, isArcType: function isArcType(d) { return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d) || this.isPolarType(d) || this.isRadarType(d); }, // determine if is 'circle' data point isCirclePoint: function isCirclePoint(node) { const config = this.config, pattern = config.point_pattern; let isCircle = !1; if ((node == null ? void 0 : node.tagName) === "circle") { isCircle = !0; } else { isCircle = config.point_type === "circle" && (!pattern || isArray(pattern) && pattern.length === 0); } return isCircle; }, lineData: function lineData(d) { return this.isLineType(d) ? [d] : []; }, arcData: function arcData(d) { return this.isArcType(d.data) ? [d] : []; }, /** * Get data adapt for data label showing * @param {object} d Data object * @returns {Array} * @private */ labelishData: function labelishData(d) { var _this5 = this; return this.isBarType(d) || this.isLineType(d) || this.isScatterType(d) || this.isBubbleType(d) || this.isCandlestickType(d) || this.isRadarType(d) || this.isTreemapType(d) ? d.values.filter(function (v) { _newArrowCheck(this, _this5); return isNumber(v.value) || !!v.value; }.bind(this)) : []; }, barLineBubbleData: function barLineBubbleData(d) { return this.isBarType(d) || this.isLineType(d) || this.isBubbleType(d) ? d.values : []; }, // https://github.com/d3/d3-shape#curves isInterpolationType: function isInterpolationType(type) { return ["basis", "basis-closed", "basis-open", "bundle", "cardinal", "cardinal-closed", "cardinal-open", "catmull-rom", "catmull-rom-closed", "catmull-rom-open", "linear", "linear-closed", "monotone-x", "monotone-y", "natural"].indexOf(type) >= 0; } }); ;// CONCATENATED MODULE: ./src/ChartInternal/ChartInternal.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license * @ignore */ // data // interactions // internals // used to retrieve radar Axis name /** * Internal chart class. * - Note: Instantiated internally, not exposed for public. * @class ChartInternal * @ignore * @private */ let ChartInternal = /*#__PURE__*/function () { function ChartInternal(api) { this.api = void 0; // API interface this.config = void 0; // config object this.cache = void 0; // cache instance this.$el = void 0; // elements this.state = void 0; // state variables this.charts = void 0; // all Chart instances array within page (equivalent of 'bb.instances') // data object this.data = { xs: {}, targets: [] }; // Axis this.axis = void 0; // Axis // scales this.scale = { x: null, y: null, y2: null, subX: null, subY: null, subY2: null, zoom: null }; // original values this.org = { xScale: null, xDomain: null }; // formatter function this.color = void 0; this.patterns = void 0; this.levelColor = void 0; this.point = void 0; this.brush = void 0; // format function this.format = { extraLineClasses: null, xAxisTick: null, dataTime: null, // dataTimeFormat defaultAxisTime: null, // defaultAxisTimeFormat axisTime: null // axisTimeFormat }; const $$ = this; $$.api = api; // Chart class instance alias $$.config = new Options(); $$.cache = new Cache(); const store = new Store(); $$.$el = store.getStore("element"); $$.state = store.getStore("state"); $$.$T = $$.$T.bind($$); } /** * Get the selection based on transition config * @param {SVGElement|d3Selection} selection Target selection * @param {boolean} force Force transition * @param {string} name Transition name * @returns {d3Selection} * @private */ var _proto = ChartInternal.prototype; _proto.$T = function $T(selection, force, name) { const config = this.config, state = this.state, duration = config.transition_duration, subchart = config.subchart_show; let t = selection; if (t) { // in case of non d3 selection, wrap with d3 selection if ("tagName" in t) { t = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(t); } // do not transit on: // - wheel zoom (state.zooming = true) // - when has no subchart // - initialization // - resizing const transit = (force !== !1 && duration || force) && (!state.zooming || state.dragging) && !state.resizing && state.rendered && !subchart; t = transit ? t.transition(name).duration(duration) : t; } return t; }; _proto.beforeInit = function beforeInit() { const $$ = this; $$.callPluginHook("$beforeInit"); // can do something callFn($$.config.onbeforeinit, $$.api); }; _proto.afterInit = function afterInit() { const $$ = this; $$.callPluginHook("$afterInit"); // can do something callFn($$.config.onafterinit, $$.api); }; _proto.init = function init() { const $$ = this, config = $$.config, state = $$.state, $el = $$.$el, useCssRule = config.boost_useCssRule; checkModuleImport($$); state.hasRadar = !state.hasAxis && $$.hasType("radar"); state.hasTreemap = !state.hasAxis && $$.hasType("treemap"); state.hasAxis = !$$.hasArcType() && !state.hasTreemap; // datetime to be used for uniqueness state.datetimeId = "bb-" + +new Date() * getRandom(); if (useCssRule) { // append style element const styleEl = browser_doc.createElement("style"); // styleEl.id = styleId; styleEl.type = "text/css"; browser_doc.head.appendChild(styleEl); state.style = { rootSelctor: "." + state.datetimeId, sheet: styleEl.sheet }; // used on .destroy() $el.style = styleEl; } const bindto = { element: config.bindto, classname: "bb" }; if (isObject(config.bindto)) { bindto.element = config.bindto.element || "#chart"; bindto.classname = config.bindto.classname || bindto.classname; } // select bind element $el.chart = isFunction(bindto.element.node) ? config.bindto.element : (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(bindto.element || []); if ($el.chart.empty()) { $el.chart = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.select)(browser_doc.body.appendChild(browser_doc.createElement("div"))); } $el.chart.html("").classed(bindto.classname, !0).classed(state.datetimeId, useCssRule).style("position", "relative"); $$.initParams(); $$.initToRender(); } /** * Initialize the rendering process * @param {boolean} forced Force to render process * @private */; _proto.initToRender = function initToRender(forced) { var _this = this; const $$ = this, config = $$.config, state = $$.state, chart = $$.$el.chart, isHidden = function () { _newArrowCheck(this, _this); return chart.style("display") === "none" || chart.style("visibility") === "hidden"; }.bind(this), isLazy = config.render.lazy || isHidden(), MutationObserver = win.MutationObserver; if (isLazy && MutationObserver && config.render.observe !== !1 && !forced) { new MutationObserver(function (mutation, observer) { _newArrowCheck(this, _this); if (!isHidden()) { observer.disconnect(); state.rendered || $$.initToRender(!0); } }.bind(this)).observe(chart.node(), { attributes: !0, attributeFilter: ["class", "style"] }); } if (!isLazy || forced) { $$.convertData(config, function (res) { _newArrowCheck(this, _this); $$.initWithData(res); $$.afterInit(); }.bind(this)); } }; _proto.initParams = function initParams() { var _this2 = this; const $$ = this, config = $$.config, format = $$.format, state = $$.state, isRotated = config.axis_rotated; // color settings $$.color = $$.generateColor(); $$.levelColor = $$.generateLevelColor(); // when 'padding=false' is set, disable axes and subchart. Because they are useless. if (config.padding === !1) { config.axis_x_show = !1; config.axis_y_show = !1; config.axis_y2_show = !1; config.subchart_show = !1; } if ($$.hasPointType()) { $$.point = $$.generatePoint(); } if (state.hasAxis) { $$.initClip(); format.extraLineClasses = $$.generateExtraLineClass(); format.dataTime = config.data_xLocaltime ? external_commonjs_d3_time_format_commonjs2_d3_time_format_amd_d3_time_format_root_d3_.timeParse : external_commonjs_d3_time_format_commonjs2_d3_time_format_amd_d3_time_format_root_d3_.utcParse; format.axisTime = config.axis_x_localtime ? external_commonjs_d3_time_format_commonjs2_d3_time_format_amd_d3_time_format_root_d3_.timeFormat : external_commonjs_d3_time_format_commonjs2_d3_time_format_amd_d3_time_format_root_d3_.utcFormat; const isDragZoom = $$.config.zoom_enabled && $$.config.zoom_type === "drag"; format.defaultAxisTime = function (d) { _newArrowCheck(this, _this2); const _$$$scale = $$.scale, x = _$$$scale.x, zoom = _$$$scale.zoom, isZoomed = isDragZoom ? zoom : zoom && x.orgDomain().toString() !== zoom.domain().toString(), specifier = d.getMilliseconds() && ".%L" || d.getSeconds() && ".:%S" || d.getMinutes() && "%I:%M" || d.getHours() && "%I %p" || d.getDate() !== 1 && "%b %d" || isZoomed && d.getDate() === 1 && "%b\'%y" || d.getMonth() && "%-m/%-d" || "%Y"; return format.axisTime(specifier)(d); }.bind(this); } state.isLegendRight = config.legend_position === "right"; state.isLegendInset = config.legend_position === "inset"; state.isLegendTop = config.legend_inset_anchor === "top-left" || config.legend_inset_anchor === "top-right"; state.isLegendLeft = config.legend_inset_anchor === "top-left" || config.legend_inset_anchor === "bottom-left"; state.rotatedPadding.top = $$.getResettedPadding(state.rotatedPadding.top); state.rotatedPadding.right = isRotated && !config.axis_x_show ? 0 : 30; state.inputType = convertInputType(config.interaction_inputType_mouse, config.interaction_inputType_touch); }; _proto.initWithData = function initWithData(data) { var _this3 = this; const $$ = this, config = $$.config, scale = $$.scale, state = $$.state, $el = $$.$el, org = $$.org, _state = state, hasAxis = _state.hasAxis, hasTreemap = _state.hasTreemap, hasInteraction = config.interaction_enabled, hasPolar = $$.hasType("polar"); // for arc type, set axes to not be shown // $$.hasArcType() && ["x", "y", "y2"].forEach(id => (config[`axis_${id}_show`] = false)); if (hasAxis) { $$.axis = $$.getAxisInstance(); config.zoom_enabled && $$.initZoom(); } // Init data as targets $$.data.xs = {}; $$.data.targets = $$.convertDataToTargets(data); if (config.data_filter) { $$.data.targets = $$.data.targets.filter(config.data_filter.bind($$.api)); } // Set targets to hide if needed if (config.data_hide) { $$.addHiddenTargetIds(config.data_hide === !0 ? $$.mapToIds($$.data.targets) : config.data_hide); } if (config.legend_hide) { $$.addHiddenLegendIds(config.legend_hide === !0 ? $$.mapToIds($$.data.targets) : config.legend_hide); } // Init sizes and scales $$.updateSizes(); $$.updateScales(!0); // retrieve scale after the 'updateScales()' is called if (hasAxis) { const x = scale.x, y = scale.y, y2 = scale.y2, subX = scale.subX, subY = scale.subY, subY2 = scale.subY2; // Set domains for each scale if (x) { x.domain(sortValue($$.getXDomain($$.data.targets), !config.axis_x_inverted)); subX.domain(x.domain()); // Save original x domain for zoom update org.xDomain = x.domain(); } if (y) { y.domain($$.getYDomain($$.data.targets, "y")); subY.domain(y.domain()); } if (y2) { y2.domain($$.getYDomain($$.data.targets, "y2")); subY2 && subY2.domain(y2.domain()); } } // -- Basic Elements -- $el.svg = $el.chart.append("svg").style("overflow", "hidden").style("display", "block"); if (hasInteraction && state.inputType) { const isTouch = state.inputType === "touch", onclick = config.onclick, onover = config.onover, onout = config.onout; $el.svg.on("click", (onclick == null ? void 0 : onclick.bind($$.api)) || null).on(isTouch ? "touchstart" : "mouseenter", (onover == null ? void 0 : onover.bind($$.api)) || null).on(isTouch ? "touchend" : "mouseleave", (onout == null ? void 0 : onout.bind($$.api)) || null); } config.svg_classname && $el.svg.attr("class", config.svg_classname); // Define defs const hasColorPatterns = isFunction(config.color_tiles) && $$.patterns; if (hasAxis || hasColorPatterns || hasPolar || hasTreemap || config.data_labels_backgroundColors) { $el.defs = $el.svg.append("defs"); if (hasAxis) { ["id", "idXAxis", "idYAxis", "idGrid"].forEach(function (v) { _newArrowCheck(this, _this3); $$.appendClip($el.defs, state.clip[v]); }.bind(this)); } // Append data background color filter definition $$.generateDataLabelBackgroundColorFilter(); // set color patterns if (hasColorPatterns) { $$.patterns.forEach(function (p) { var _this4 = this; _newArrowCheck(this, _this3); return $el.defs.append(function () { _newArrowCheck(this, _this4); return p.node; }.bind(this)); }.bind(this)); } } $$.updateSvgSize(); // Bind resize event $$.bindResize(); // Define regions const main = $el.svg.append("g").classed($COMMON.main, !0).attr("transform", hasTreemap ? null : $$.getTranslate("main")); $el.main = main; // initialize subchart when subchart show option is set config.subchart_show && $$.initSubchart(); config.tooltip_show && $$.initTooltip(); config.title_text && $$.initTitle(); !hasTreemap && config.legend_show && $$.initLegend(); // -- Main Region -- // text when empty if (config.data_empty_label_text) { main.append("text").attr("class", $TEXT.text + " " + $COMMON.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers. .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE. } if (hasAxis) { // Regions config.regions.length && $$.initRegion(); // Add Axis here, when clipPath is 'false' config.clipPath || $$.axis.init(); } // Define g for chart area main.append("g").classed($COMMON.chart, !0).attr("clip-path", hasAxis ? state.clip.path : null); $$.callPluginHook("$init"); $$.initChartElements(); if (hasAxis) { var _$$$axis; // Cover whole with rects for events hasInteraction && ($$.initEventRect == null ? void 0 : $$.initEventRect()); // Grids $$.initGrid(); // Add Axis here, when clipPath is 'true' config.clipPath && ((_$$$axis = $$.axis) == null ? void 0 : _$$$axis.init()); } // Set targets $$.updateTargets($$.data.targets); // Draw with targets $$.updateDimension(); // oninit callback callFn(config.oninit, $$.api); // Set background $$.setBackground(); $$.redraw({ withTransition: !1, withTransform: !0, withUpdateXDomain: !0, withUpdateOrgXDomain: !0, withTransitionForAxis: !1, initializing: !0 }); // data.onmin/max callback if (config.data_onmin || config.data_onmax) { const minMax = $$.getMinMaxData(); callFn(config.data_onmin, $$.api, minMax.min); callFn(config.data_onmax, $$.api, minMax.max); } config.tooltip_show && $$.initShowTooltip(); state.rendered = !0; } /** * Initialize chart elements * @private */; _proto.initChartElements = function initChartElements() { var _this5 = this; const $$ = this, _$$$state = $$.state, hasAxis = _$$$state.hasAxis, hasRadar = _$$$state.hasRadar, hasTreemap = _$$$state.hasTreemap, types = []; if (hasAxis) { const shapes = ["bar", "bubble", "candlestick", "line"]; if ($$.config.bar_front) { shapes.push(shapes.shift()); } shapes.forEach(function (v) { _newArrowCheck(this, _this5); const name = capitalize(v); if (v === "line" && $$.hasTypeOf(name) || $$.hasType(v)) { types.push(name); } }.bind(this)); } else if (hasTreemap) { types.push("Treemap"); } else { const hasPolar = $$.hasType("polar"); if (!hasRadar) { types.push("Arc", "Pie"); } if ($$.hasType("gauge")) { types.push("Gauge"); } else if (hasRadar) { types.push("Radar"); } else if (hasPolar) { types.push("Polar"); } } types.forEach(function (v) { _newArrowCheck(this, _this5); $$["init" + v](); }.bind(this)); notEmpty($$.config.data_labels) && !$$.hasArcType(null, ["radar"]) && $$.initText(); } /** * Set chart elements * @private */; _proto.setChartElements = function setChartElements() { const $$ = this, _$$$$el = $$.$el, chart = _$$$$el.chart, svg = _$$$$el.svg, defs = _$$$$el.defs, main = _$$$$el.main, tooltip = _$$$$el.tooltip, legend = _$$$$el.legend, title = _$$$$el.title, grid = _$$$$el.grid, needle = _$$$$el.needle, arc = _$$$$el.arcs, circles = _$$$$el.circle, bars = _$$$$el.bar, candlestick = _$$$$el.candlestick, lines = _$$$$el.line, areas = _$$$$el.area, texts = _$$$$el.text; // public $$.api.$ = { chart: chart, svg: svg, defs: defs, main: main, tooltip: tooltip, legend: legend, title: title, grid: grid, arc: arc, circles: circles, bar: { bars: bars }, candlestick: candlestick, line: { lines: lines, areas: areas }, needle: needle, text: { texts: texts } }; } /** * Set background element/image * @private */; _proto.setBackground = function setBackground() { const $$ = this, bg = $$.config.background, state = $$.state, svg = $$.$el.svg; if (notEmpty(bg)) { const element = svg.select("g").insert(bg.imgUrl ? "image" : "rect", ":first-child"); if (bg.imgUrl) { element.attr("href", bg.imgUrl); } else if (bg.color) { element.style("fill", bg.color).attr("clip-path", state.clip.path); } element.attr("class", bg.class || null).attr("width", "100%").attr("height", "100%"); } } /** * Update targeted element with given data * @param {object} targets Data object formatted as 'target' * @private */; _proto.updateTargets = function updateTargets(targets) { var _this6 = this; const $$ = this, _$$$state2 = $$.state, hasAxis = _$$$state2.hasAxis, hasRadar = _$$$state2.hasRadar, hasTreemap = _$$$state2.hasTreemap, helper = function (type) { _newArrowCheck(this, _this6); return $$["updateTargetsFor" + type](targets.filter($$["is" + type + "Type"].bind($$))); }.bind(this); // Text $$.updateTargetsForText(targets); if (hasAxis) { ["bar", "candlestick", "line"].forEach(function (v) { _newArrowCheck(this, _this6); const name = capitalize(v); if (v === "line" && $$.hasTypeOf(name) || $$.hasType(v)) { helper(name); } }.bind(this)); // Sub Chart $$.updateTargetsForSubchart && $$.updateTargetsForSubchart(targets); // Arc, Polar, Radar } else if ($$.hasArcType(targets)) { let type = "Arc"; if (hasRadar) { type = "Radar"; } else if ($$.hasType("polar")) { type = "Polar"; } helper(type); // Arc, Polar, Radar } else if (hasTreemap) { helper("Treemap"); } // Point types const hasPointType = $$.hasType("bubble") || $$.hasType("scatter"); if (hasPointType) { $$.updateTargetForCircle == null || $$.updateTargetForCircle(); } // Fade-in each chart $$.filterTargetsToShowAtInit(hasPointType); } /** * Display targeted elements at initialization * @param {boolean} hasPointType whether has point type(bubble, scatter) or not * @private */; _proto.filterTargetsToShowAtInit = function filterTargetsToShowAtInit(hasPointType) { var _this7 = this; if (hasPointType === void 0) { hasPointType = !1; } const $$ = this, svg = $$.$el.svg, $T = $$.$T; let selector = "." + $COMMON.target; if (hasPointType) { selector += ", ." + $CIRCLE.chartCircles + " > ." + $CIRCLE.circles; } $T(svg.selectAll(selector).filter(function (d) { _newArrowCheck(this, _this7); return $$.isTargetToShow(d.id); }.bind(this))).style("opacity", null); }; _proto.getWithOption = function getWithOption(options) { var _this8 = this; const withOptions = { Dimension: !0, EventRect: !0, Legend: !1, Subchart: !0, Transform: !1, Transition: !0, TrimXDomain: !0, UpdateXAxis: "UpdateXDomain", UpdateXDomain: !1, UpdateOrgXDomain: !1, TransitionForExit: "Transition", TransitionForAxis: "Transition", Y: !0 }; Object.keys(withOptions).forEach(function (key) { _newArrowCheck(this, _this8); let defVal = withOptions[key]; if (isString(defVal)) { defVal = withOptions[defVal]; } withOptions[key] = getOption(options, "with" + key, defVal); }.bind(this)); return withOptions; }; _proto.initialOpacity = function initialOpacity(d) { const $$ = this, withoutFadeIn = $$.state.withoutFadeIn, r = $$.getBaseValue(d) !== null && withoutFadeIn[d.id] ? null : "0"; return r; }; _proto.bindResize = function bindResize() { var _this9 = this; const $$ = this, config = $$.config, state = $$.state, resizeFunction = generateResize(config.resize_timer), list = []; list.push(function () { _newArrowCheck(this, _this9); return callFn(config.onresize, $$.api); }.bind(this)); if (config.resize_auto) { list.push(function () { _newArrowCheck(this, _this9); state.resizing = !0; // https://github.com/naver/billboard.js/issues/2650 if (config.legend_show) { $$.updateSizes(); $$.updateLegend(); } $$.api.flush(!1); }.bind(this)); } list.push(function () { _newArrowCheck(this, _this9); callFn(config.onresized, $$.api); state.resizing = !1; }.bind(this)); // add resize functions list.forEach(function (v) { _newArrowCheck(this, _this9); return resizeFunction.add(v); }.bind(this)); $$.resizeFunction = resizeFunction; // attach resize event win.addEventListener("resize", $$.resizeFunction = resizeFunction); } /** * Call plugin hook * @param {string} phase The lifecycle phase * @param {Array} args Arguments * @private */; _proto.callPluginHook = function callPluginHook(phase) { for (var _this10 = this, _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } this.config.plugins.forEach(function (v) { _newArrowCheck(this, _this10); if (phase === "$beforeInit") { v.$$ = this; this.api.plugins.push(v); } v[phase].apply(v, args); }.bind(this)); }; return ChartInternal; }(); extend(ChartInternal.prototype, [ // common convert, data_data, load, category, internals_class, internals_color, domain, interactions_interaction, format, internals_legend, redraw, scale, shape, size, style, internals_text, internals_title, internals_tooltip, transform, type]); ;// CONCATENATED MODULE: ./src/config/config.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Load configuration option * @param {object} config User's generation config value * @private */ function loadConfig(config) { var _this = this; const thisConfig = this.config; let target, keys, read; const _find = function find() { _newArrowCheck(this, _this); const key = keys.shift(); if (key && target && isObjectType(target) && key in target) { target = target[key]; return _find(); } else if (!key) { return target; } return undefined; }.bind(this); Object.keys(thisConfig).forEach(function (key) { _newArrowCheck(this, _this); target = config; keys = key.split("_"); read = _find(); if (isDefined(read)) { thisConfig[key] = read; } }.bind(this)); // only should run in the ChartInternal context if (this.api) { this.state.orgConfig = config; } } ;// CONCATENATED MODULE: ./src/Chart/api/chart.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /* harmony default export */ var chart = ({ /** * Resize the chart. * @function resize * @instance * @memberof Chart * @param {object} size This argument should include width and height in pixels. * @param {number} [size.width] width value * @param {number} [size.height] height value * @example * // Resize to 640x480 * chart.resize({ * width: 640, * height: 480 * }); */ resize: function resize(size) { const $$ = this.internal, config = $$.config, state = $$.state; if (state.rendered) { config.size_width = size ? size.width : null; config.size_height = size ? size.height : null; state.resizing = !0; this.flush(!1); $$.resizeFunction(); } }, /** * Force to redraw. * - **NOTE:** When zoom/subchart is used, the zoomed state will be resetted. * @function flush * @instance * @memberof Chart * @param {boolean} [soft] For soft redraw. * @example * chart.flush(); * * // for soft redraw * chart.flush(true); */ flush: function flush(soft) { const $$ = this.internal, state = $$.state, zoomResetBtn = $$.$el.zoomResetBtn; if (state.rendered) { // reset possible zoom scale when is called from resize event // eslint-disable-next-line prefer-rest-params if (state.resizing) { var _$$$brush; // arguments[1] is given when is called from resize (_$$$brush = $$.brush) == null || _$$$brush.updateResize(); } else { var _$$$axis; // re-update config info (_$$$axis = $$.axis) == null || _$$$axis.setOrient(); } // hide possible reset zoom button // https://github.com/naver/billboard.js/issues/2201 zoomResetBtn == null || zoomResetBtn.style("display", "none"); $$.scale.zoom = null; soft ? $$.redraw({ withTransform: !0, withUpdateXDomain: !0, withUpdateOrgXDomain: !0, withLegend: !0 }) : $$.updateAndRedraw({ withLegend: !0, withTransition: !1, withTransitionForTransform: !1 }); // reset subchart selection & selection state if (!state.resizing && $$.brush) { $$.brush.getSelection().call($$.brush.move); $$.unselectRect(); } } else { $$.initToRender(!0); } }, /** * Reset the chart object and remove element and events completely. * @function destroy * @instance * @memberof Chart * @returns {null} * @example * chart.destroy(); */ destroy: function destroy() { var _this = this; const $$ = this.internal, _$$$$el = $$.$el, chart = _$$$$el.chart, style = _$$$$el.style, svg = _$$$$el.svg; if (notEmpty($$)) { $$.callPluginHook("$willDestroy"); $$.charts.splice($$.charts.indexOf(this), 1); // detach events $$.unbindAllEvents(); // clear timers && pending transition svg.select("*").interrupt(); $$.resizeFunction.clear(); win.removeEventListener("resize", $$.resizeFunction); chart.classed("bb", !1).style("position", null).selectChildren().remove(); // remove