UNPKG

billboard.js

Version:

Re-usable easy interface JavaScript chart library, based on D3 v4+

1,782 lines (1,542 loc) 60 kB
/*! * 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.3.3 * @requires billboard.js * @summary billboard.js plugin */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("d3-interpolate"), require("d3-color"), require("d3-scale"), require("d3-selection"), require("d3-brush"), require("d3-axis"), require("d3-format")); else if(typeof define === 'function' && define.amd) define("bb", ["d3-interpolate", "d3-color", "d3-scale", "d3-selection", "d3-brush", "d3-axis", "d3-format"], factory); else if(typeof exports === 'object') exports["bb"] = factory(require("d3-interpolate"), require("d3-color"), require("d3-scale"), require("d3-selection"), require("d3-brush"), require("d3-axis"), require("d3-format")); else root["bb"] = root["bb"] || {}, root["bb"]["plugin"] = root["bb"]["plugin"] || {}, root["bb"]["plugin"]["stanford"] = factory(root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"], root["d3"]); })(this, function(__WEBPACK_EXTERNAL_MODULE__5__, __WEBPACK_EXTERNAL_MODULE__6__, __WEBPACK_EXTERNAL_MODULE__7__, __WEBPACK_EXTERNAL_MODULE__1__, __WEBPACK_EXTERNAL_MODULE__3__, __WEBPACK_EXTERNAL_MODULE__8__, __WEBPACK_EXTERNAL_MODULE__9__) { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ /* 0 */, /* 1 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__1__; /***/ }), /* 2 */, /* 3 */ /***/ (function(module) { module.exports = __WEBPACK_EXTERNAL_MODULE__3__; /***/ }), /* 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__; /***/ }) /******/ ]); /************************************************************************/ /******/ // 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); } /******/ }(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. !function() { // EXPORTS __webpack_require__.d(__webpack_exports__, { "default": function() { return /* binding */ Stanford; } }); ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } // EXTERNAL MODULE: external {"commonjs":"d3-interpolate","commonjs2":"d3-interpolate","amd":"d3-interpolate","root":"d3"} var external_commonjs_d3_interpolate_commonjs2_d3_interpolate_amd_d3_interpolate_root_d3_ = __webpack_require__(5); // EXTERNAL MODULE: external {"commonjs":"d3-color","commonjs2":"d3-color","amd":"d3-color","root":"d3"} var external_commonjs_d3_color_commonjs2_d3_color_amd_d3_color_root_d3_ = __webpack_require__(6); // 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__(7); ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } ;// CONCATENATED MODULE: ./src/config/classes.ts function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1, source; i < arguments.length; i++) { source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * CSS class names definition * @private */ var $COMMON = { button: "bb-button", chart: "bb-chart", empty: "bb-empty", main: "bb-main", target: "bb-target", EXPANDED: "_expanded_" }; var $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" }; var $AREA = { area: "bb-area", areas: "bb-areas" }; var $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" }; var $BAR = { bar: "bb-bar", bars: "bb-bars", chartBar: "bb-chart-bar", chartBars: "bb-chart-bars" }; var $CANDLESTICK = { candlestick: "bb-candlestick", candlesticks: "bb-candlesticks", chartCandlestick: "bb-chart-candlestick", chartCandlesticks: "bb-chart-candlesticks", valueDown: "bb-value-down", valueUp: "bb-value-up" }; var $CIRCLE = { chartCircles: "bb-chart-circles", circle: "bb-circle", circles: "bb-circles" }; var $COLOR = { colorPattern: "bb-color-pattern", colorScale: "bb-colorscale" }; var $DRAG = { dragarea: "bb-dragarea", INCLUDED: "_included_" }; var $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" }; var $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" }; var $LINE = { chartLine: "bb-chart-line", chartLines: "bb-chart-lines", line: "bb-line", lines: "bb-lines" }; var $EVENT = { eventRect: "bb-event-rect", eventRects: "bb-event-rects", eventRectsMultiple: "bb-event-rects-multiple", eventRectsSingle: "bb-event-rects-single" }; var $FOCUS = { focused: "bb-focused", defocused: "bb-defocused", legendItemFocused: "bb-legend-item-focused", xgridFocus: "bb-xgrid-focus", ygridFocus: "bb-ygrid-focus" }; var $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" }; var $RADAR = { chartRadar: "bb-chart-radar", chartRadars: "bb-chart-radars", level: "bb-level", levels: "bb-levels" }; var $REGION = { region: "bb-region", regions: "bb-regions" }; var $SELECT = { selectedCircle: "bb-selected-circle", selectedCircles: "bb-selected-circles", SELECTED: "_selected_" }; var $SHAPE = { shape: "bb-shape", shapes: "bb-shapes" }; var $SUBCHART = { brush: "bb-brush", subchart: "bb-subchart" }; var $TEXT = { chartText: "bb-chart-text", chartTexts: "bb-chart-texts", text: "bb-text", texts: "bb-texts", title: "bb-title", TextOverlapping: "text-overlapping" }; var $TOOLTIP = { tooltip: "bb-tooltip", tooltipContainer: "bb-tooltip-container", tooltipName: "bb-tooltip-name" }; var $ZOOM = { buttonZoomReset: "bb-zoom-reset", zoomBrush: "bb-zoom-brush" }; /* harmony default export */ var classes = (_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, $COMMON), $ARC), $AREA), $AXIS), $BAR), $CANDLESTICK), $CIRCLE), $COLOR), $DRAG), $GAUGE), $LEGEND), $LINE), $EVENT), $FOCUS), $GRID), $RADAR), $REGION), $SELECT), $SHAPE), $SUBCHART), $TEXT), $TOOLTIP), $ZOOM)); // 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__(1); // 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/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 */ var win = function () { var root = 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; return root || Function("return this")(); }(); /* eslint-enable no-new-func, no-undef */ // fallback for non-supported environments win.requestIdleCallback = win.requestIdleCallback || function (cb) { return setTimeout(cb, 1); }; win.cancelIdleCallback = win.cancelIdleCallback || function (id) { return clearTimeout(id); }; var doc = win == null ? void 0 : win.document; ;// CONCATENATED MODULE: ./src/module/util.ts function util_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function util_objectSpread(target) { for (var i = 1, source; i < arguments.length; i++) { source = null != arguments[i] ? arguments[i] : {}; i % 2 ? util_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : util_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license * @ignore */ var isValue = function (v) { return v || v === 0; }, isFunction = function (v) { return typeof v === "function"; }, isString = function (v) { return typeof v === "string"; }, isNumber = function (v) { return typeof v === "number"; }, isUndefined = function (v) { return typeof v === "undefined"; }, isDefined = function (v) { return typeof v !== "undefined"; }, isboolean = function (v) { return typeof v === "boolean"; }, ceil10 = function (v) { return Math.ceil(v / 10) * 10; }, asHalfPixel = function (n) { return Math.ceil(n) + .5; }, diffDomain = function (d) { return d[1] - d[0]; }, isObjectType = function (v) { return typeof v === "object"; }, isEmpty = function (o) { return isUndefined(o) || o === null || isString(o) && o.length === 0 || isObjectType(o) && !(o instanceof Date) && Object.keys(o).length === 0 || isNumber(o) && isNaN(o); }, notEmpty = function (o) { return !isEmpty(o); }, isArray = function (arr) { return Array.isArray(arr); }, isObject = function (obj) { return obj && !(obj != null && obj.nodeType) && isObjectType(obj) && !isArray(obj); }; /** * 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 found = !1; Object.keys(dict).forEach(function (key) { return dict[key] === value && (found = !0); }); 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) { for (var isFn = isFunction(fn), _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 n = 0, 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 () { return ++n; }).on("end", end); } else { ++n; transition.call(end); } } /** * Replace tag sign to html entity * @param {string} str Target string value * @returns {string} * @private */ function sanitise(str) { return isString(str) ? str.replace(/</g, "&lt;").replace(/>/g, "&gt;") : 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) { 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 { var diff = [node.text(), text].map(function (v) { return v.replace(/[\s\n]/g, ""); }); if (diff[0] !== diff[1]) { var multiline = text.split("\n"), len = toMiddle ? multiline.length - 1 : 1; // reset possible text node.html(""); multiline.forEach(function (v, i) { node.append("tspan").attr("x", 0).attr("dy", (i === 0 ? dy[0] * len : dy[1]) + "em").text(v); }); } } } /** * Substitution of SVGPathSeg API polyfill * @param {SVGGraphicsElement} path Target svg element * @returns {Array} * @private */ function getRectSegList(path) { /* * seg1 ---------- seg2 * | | * | | * | | * seg0 ---------- seg3 * */ var _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) { var _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, touches = event && ((_ref = event.touches || event.sourceEvent && event.sourceEvent.touches) == null ? void 0 : _ref[0]), pointer = (0,external_commonjs_d3_selection_commonjs2_d3_selection_amd_d3_selection_root_d3_.pointer)(touches || event, element); return pointer.map(function (v) { return isNaN(v) ? 0 : v; }); } /** * Return brush selection array * @param {object} ctx Current instance * @returns {d3.brushSelection} * @private */ function getBrushSelection(ctx) { var event = ctx.event, $el = ctx.$el, main = $el.subchart.main || $el.main, 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) { var 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; } var rand = 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; } var mid = Math.floor((start + end) / 2), _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) { var 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() { for (var clone = function (v) { if (isObject(v) && v.constructor) { var r = new v.constructor(); for (var k in v) { r[k] = clone(v[k]); } return r; } return v; }, _len3 = arguments.length, objectN = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { objectN[_key3] = arguments[_key3]; } return objectN.map(function (v) { return clone(v); }).reduce(function (a, c) { return util_objectSpread(util_objectSpread({}, a), c); }); } /** * Extend target from source object * @param {object} target Target object * @param {object|Array} source Source object * @returns {object} * @private */ function extend(target, source) { if (target === void 0) { target = {}; } if (isArray(source)) { source.forEach(function (v) { return extend(target, v); }); } // exclude name with only numbers for (var 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 */ var capitalize = function (str) { return str.charAt(0).toUpperCase() + str.slice(1); }; /** * Camelize from kebob style string * @param {string} str Target string * @param {string} separator Separator string * @returns {string} camelized string * @private */ function camelize(str, separator) { if (separator === void 0) { separator = "-"; } return str.split(separator).map(function (v, i) { return i ? v.charAt(0).toUpperCase() + v.slice(1).toLowerCase() : v.toLowerCase(); }).join(""); } /** * Convert to array * @param {object} v Target to be converted * @returns {Array} * @private */ var toArray = function (v) { return [].slice.call(v); }; /** * Get css rules for specified stylesheets * @param {Array} styleSheets The stylesheets to get the rules from * @returns {Array} * @private */ function getCssRules(styleSheets) { var rules = []; styleSheets.forEach(function (sheet) { try { if (sheet.cssRules && sheet.cssRules.length) { rules = rules.concat(toArray(sheet.cssRules)); } } catch (e) { console.error("Error while reading rules from " + sheet.href + ": " + e.toString()); } }); return rules; } /** * Gets the SVGMatrix of an SVGGElement * @param {SVGElement} node Node element * @returns {SVGMatrix} matrix * @private */ function getTranslation(node) { var 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 isDate = data[0] instanceof Date, d = (isDate ? data.map(Number) : data).filter(function (v, i, self) { return self.indexOf(v) === i; }); return isDate ? d.map(function (v) { return new Date(v); }) : d; } /** * Merge array * @param {Array} arr Source array * @returns {Array} * @private */ function mergeArray(arr) { return arr && arr.length ? arr.reduce(function (p, c) { return p.concat(c); }) : []; } /** * 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 _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; } var source = objectN.shift(); if (isObject(target) && isObject(source)) { Object.keys(source).forEach(function (key) { var value = source[key]; if (isObject(value)) { target[key] || (target[key] = {}); target[key] = mergeObj(target[key], value); } else { target[key] = isArray(value) ? value.concat() : value; } }); } 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) { if (isAsc === void 0) { isAsc = !0; } var fn; if (data[0] instanceof Date) { fn = isAsc ? function (a, b) { return a - b; } : function (a, b) { return b - a; }; } else { if (isAsc && !data.every(isNaN)) { fn = function (a, b) { return a - b; }; } else if (!isAsc) { fn = function (a, b) { return a > b && -1 || a < b && 1 || a === b && 0; }; } } 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 res = data.filter(function (v) { return notEmpty(v); }); 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 */ var getRange = function (start, end, step) { if (step === void 0) { step = 1; } var res = [], n = Math.max(0, Math.ceil((end - start) / step)) | 0; for (var i = start; i < n; i++) { res.push(start + i * step); } return res; }, emulateEvent = { mouse: function () { var getParams = function () { return { bubbles: !1, cancelable: !1, screenX: 0, screenY: 0, clientX: 0, clientY: 0 }; }; try { // eslint-disable-next-line no-new new MouseEvent("t"); return function (el, eventType, params) { if (params === void 0) { params = getParams(); } el.dispatchEvent(new MouseEvent(eventType, params)); }; } catch (e) { // Polyfills DOM4 MouseEvent return function (el, eventType, params) { if (params === void 0) { params = getParams(); } var mouseEvent = 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); }; } }(), touch: function touch(el, eventType, params) { var 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] })); } }; // 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) { var res = tpl; for (var 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) { var parsedDate; if (date instanceof Date) { parsedDate = date; } else if (isString(date)) { var config = this.config, format = this.format; parsedDate = format.dataTime(config.data_xFormat)(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 !doc.hidden; } /** * 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 hasTouch = !1; if (touch) { // Some Edge desktop return true: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/20417074/ if (win.navigator && "maxTouchPoints" in win.navigator) { hasTouch = win.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 || win.DocumentTouch && doc instanceof win.DocumentTouch) { hasTouch = !0; } else { // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#avoiding_user_agent_detection var mQ = win.matchMedia && matchMedia("(pointer:coarse)"); if (mQ && mQ.media === "(pointer:coarse)") { hasTouch = !!mQ.matches; } } } var hasMouse = mouse && !hasTouch ? "onmouseover" in win : !1; return hasMouse && "mouse" || hasTouch && "touch" || null; } ;// 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 thisConfig = this.config, target, keys, read, find = function () { var key = keys.shift(); if (key && target && isObjectType(target) && key in target) { target = target[key]; return find(); } else if (!key) { return target; } return undefined; }; Object.keys(thisConfig).forEach(function (key) { target = config; keys = key.split("_"); read = find(); if (isDefined(read)) { thisConfig[key] = read; } }); } ;// CONCATENATED MODULE: ./src/Plugin/Plugin.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Base class to generate billboard.js plugin * @class Plugin */ /** * Version info string for plugin * @name version * @static * @memberof Plugin * @type {string} * @example * bb.plugin.stanford.version; // ex) 1.9.0 */ var Plugin = /*#__PURE__*/function () { /** * Constructor * @param {Any} options config option object * @private */ function Plugin(options) { if (options === void 0) { options = {}; } this.$$ = void 0; this.options = void 0; this.options = options; } /** * Lifecycle hook for 'beforeInit' phase. * @private */ var _proto = Plugin.prototype; _proto.$beforeInit = function $beforeInit() {} /** * Lifecycle hook for 'init' phase. * @private */ ; _proto.$init = function $init() {} /** * Lifecycle hook for 'afterInit' phase. * @private */ ; _proto.$afterInit = function $afterInit() {} /** * Lifecycle hook for 'redraw' phase. * @private */ ; _proto.$redraw = function $redraw() {} /** * Lifecycle hook for 'willDestroy' phase. * @private */ ; _proto.$willDestroy = function $willDestroy() { var _this = this; Object.keys(this).forEach(function (key) { _this[key] = null; delete _this[key]; }); }; return Plugin; }(); Plugin.version = "3.3.3"; ;// CONCATENATED MODULE: ./src/Plugin/stanford/Options.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Stanford diagram plugin option class * @class StanfordOptions * @param {Options} options Stanford plugin options * @augments Plugin * @returns {StanfordOptions} * @private */ var Options = function () { return { /** * Set the color of the color scale. This function receives a value between 0 and 1, and should return a color. * @name colors * @memberof plugin-stanford * @type {Function} * @default undefined * @example * colors: d3.interpolateHslLong( * d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5) * ) */ colors: undefined, /** * Specify the key of epochs values in the data. * @name epochs * @memberof plugin-stanford * @type {Array} * @default [] * @example * epochs: [ 1, 1, 2, 2, ... ] */ epochs: [], /** * Show additional lines anywhere on the chart. * - Each line object should consist with following options: * * | Key | Type | Description | * | --- | --- | --- | * | x1 | Number | Starting position on the x axis | * | y1 | Number | Starting position on the y axis | * | x2 | Number | Ending position on the x axis | * | y2 | Number | Ending position on the y axis | * | class | String | Optional value. Set a custom css class to this line. | * @type {Array} * @memberof plugin-stanford * @default [] * @example * lines: [ * { x1: 0, y1: 0, x2: 65, y2: 65, class: "line1" }, * { x1: 0, x2: 65, y1: 40, y2: 40, class: "line2" } * ] */ lines: [], /** * Set scale values * @name scale * @memberof plugin-stanford * @type {object} * @property {object} [scale] scale object * @property {number} [scale.min=undefined] Minimum value of the color scale. Default: lowest value in epochs * @property {number} [scale.max=undefined] Maximum value of the color scale. Default: highest value in epochs * @property {number} [scale.width=20] Width of the color scale * @property {string|Function} [scale.format=undefined] Format of the axis of the color scale. Use 'pow10' to format as powers of 10 or a custom function. Example: d3.format("d") * @example * scale: { * max: 10000, * min: 1, * width: 500, * * // specify 'pow10' to format as powers of 10 * format: "pow10", * * // or specify a format function * format: function(x) { * return x +"%"; * } * }, */ scale_min: undefined, scale_max: undefined, scale_width: 20, scale_format: undefined, /** * The padding for color scale element * @name padding * @memberof plugin-stanford * @type {object} * @property {object} [padding] padding object * @property {number} [padding.top=0] Top padding value. * @property {number} [padding.right=0] Right padding value. * @property {number} [padding.bottom=0] Bottom padding value. * @property {number} [padding.left=0] Left padding value. * @example * padding: { * top: 15, * right: 0, * bottom: 0, * left: 0 * }, */ padding_top: 0, padding_right: 0, padding_bottom: 0, padding_left: 0, /** * Show additional regions anywhere on the chart. * - Each region object should consist with following options: * * | Key | Type | Default | Attributes | Description | * | --- | --- | --- | --- | --- | * | points | Array | | | Accepts a group of objects that has x and y.<br>These points should be added in a counter-clockwise fashion to make a closed polygon. | * | opacity | Number | `0.2` | &lt;optional> | Sets the opacity of the region as value between 0 and 1 | * | text | Function | | &lt;optional> | This function receives a value and percentage of the number of epochs in this region.<br>Return a string to place text in the middle of the region. | * | class | String | | &lt;optional> | Se a custom css class to this region, use the fill property in css to set a background color. | * @name regions * @memberof plugin-stanford * @type {Array} * @default [] * @example * regions: [ * { * points: [ // add points counter-clockwise * { x: 0, y: 0 }, * { x: 40, y: 40 }, * { x: 0, y: 40 }, * ], * text: function (value, percentage) { * return `Normal Operations: ${value} (${percentage}%)`; * }, * opacity: 0.2, // 0 to 1 * class: "test-polygon1" * }, * ... * ] */ regions: [] }; }; ;// CONCATENATED MODULE: ./src/Plugin/stanford/classes.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * CSS class names definition * @private */ /* harmony default export */ var stanford_classes = ({ colorScale: "bb-colorscale", stanfordElements: "bb-stanford-elements", stanfordLine: "bb-stanford-line", stanfordLines: "bb-stanford-lines", stanfordRegion: "bb-stanford-region", stanfordRegions: "bb-stanford-regions" }); ;// CONCATENATED MODULE: ./src/Plugin/stanford/util.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license * @ignore */ /** * Check if point is in region * @param {object} point Point * @param {Array} region Region * @returns {boolean} * @private */ function pointInRegion(point, region) { // thanks to: http://bl.ocks.org/bycoffe/5575904 // ray-casting algorithm based on // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html var x = point.x, y = point.value, inside = !1; for (var i = 0, j = region.length - 1; i < region.length; j = i++) { var xi = region[i].x, yi = region[i].y, xj = region[j].x, yj = region[j].y; if (yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) { inside = !inside; } } return inside; } /** * Compare epochs * @param {object} a Target * @param {object} b Source * @returns {number} * @private */ function compareEpochs(a, b) { if (a.epochs < b.epochs) { return -1; } if (a.epochs > b.epochs) { return 1; } return 0; } /** * Get region area * @param {Array} points Points * @returns {number} * @private */ function getRegionArea(points) { // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript var area = 0, point1, point2; for (var i = 0, l = points.length, j = l - 1; i < l; j = i, i++) { point1 = points[i]; point2 = points[j]; area += point1.x * point2.y; area -= point1.y * point2.x; } area /= 2; return area; } /** * Get centroid * @param {Array} points Points * @returns {object} * @private */ function getCentroid(points) { var area = getRegionArea(points), x = 0, y = 0, f; for (var i = 0, l = points.length, j = l - 1; i < l; j = i, i++) { var point1 = points[i], point2 = points[j]; f = point1.x * point2.y - point2.x * point1.y; x += (point1.x + point2.x) * f; y += (point1.y + point2.y) * f; } f = area * 6; return { x: x / f, y: y / f }; } ;// CONCATENATED MODULE: ./src/Plugin/stanford/Elements.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ // @ts-nocheck /** * Stanford diagram plugin element class * @class ColorScale * @param {Stanford} owner Stanford instance * @private */ var Elements = /*#__PURE__*/function () { function Elements(owner) { this.owner = void 0; this.owner = owner; // MEMO: Avoid blocking eventRect var elements = owner.$$.$el.main.select(".bb-chart").append("g").attr("class", stanford_classes.stanfordElements); elements.append("g").attr("class", stanford_classes.stanfordLines); elements.append("g").attr("class", stanford_classes.stanfordRegions); } var _proto = Elements.prototype; _proto.updateStanfordLines = function updateStanfordLines(duration) { var $$ = this.owner.$$, config = $$.config, main = $$.$el.main, isRotated = config.axis_rotated, xvCustom = this.xvCustom.bind($$), yvCustom = this.yvCustom.bind($$), stanfordLine = main.select("." + stanford_classes.stanfordLines).style("shape-rendering", "geometricprecision").selectAll("." + stanford_classes.stanfordLine).data(this.owner.config.lines); // exit stanfordLine.exit().transition().duration(duration).style("opacity", "0").remove(); // enter var stanfordLineEnter = stanfordLine.enter().append("g"); stanfordLineEnter.append("line").style("opacity", "0"); stanfordLineEnter.merge(stanfordLine).attr("class", function (d) { return stanford_classes.stanfordLine + (d.class ? " " + d.class : ""); }).select("line").transition().duration(duration).attr("x1", function (d) { return isRotated ? yvCustom(d, "y1") : xvCustom(d, "x1"); }).attr("x2", function (d) { return isRotated ? yvCustom(d, "y2") : xvCustom(d, "x2"); }).attr("y1", function (d) { return isRotated ? xvCustom(d, "x1") : yvCustom(d, "y1"); }).attr("y2", function (d) { return isRotated ? xvCustom(d, "x2") : yvCustom(d, "y2"); }).transition().style("opacity", null); }; _proto.updateStanfordRegions = function updateStanfordRegions(duration) { var $$ = this.owner.$$, config = $$.config, main = $$.$el.main, isRotated = config.axis_rotated, xvCustom = this.xvCustom.bind($$), yvCustom = this.yvCustom.bind($$), countPointsInRegion = this.owner.countEpochsInRegion.bind($$), stanfordRegion = main.select("." + stanford_classes.stanfordRegions).selectAll("." + stanford_classes.stanfordRegion).data(this.owner.config.regions); // exit stanfordRegion.exit().transition().duration(duration).style("opacity", "0").remove(); // enter var stanfordRegionEnter = stanfordRegion.enter().append("g"); stanfordRegionEnter.append("polygon").style("opacity", "0"); stanfordRegionEnter.append("text").attr("transform", isRotated ? "rotate(-90)" : "").style("opacity", "0"); stanfordRegion = stanfordRegionEnter.merge(stanfordRegion); // update stanfordRegion.attr("class", function (d) { return stanford_classes.stanfordRegion + (d.class ? " " + d.class : ""); }).select("polygon").transition().duration(duration).attr("points", function (d) { return d.points.map(function (value) { return [isRotated ? yvCustom(value, "y") : xvCustom(value, "x"), isRotated ? xvCustom(value, "x") : yvCustom(value, "y")].join(","); }).join(" "); }).transition().style("opacity", function (d) { return (d.opacity ? d.opacity : .2) + ""; }); stanfordRegion.select("text").transition().duration(duration).attr("x", function (d) { return isRotated ? yvCustom(getCentroid(d.points), "y") : xvCustom(getCentroid(d.points), "x"); }).attr("y", function (d) { return isRotated ? xvCustom(getCentroid(d.points), "x") : yvCustom(getCentroid(d.points), "y"); }).text(function (d) { if (d.text) { var _countPointsInRegion = countPointsInRegion(d.points), value = _countPointsInRegion.value, percentage = _countPointsInRegion.percentage; return d.text(value, percentage); } return ""; }).attr("text-anchor", "middle").attr("dominant-baseline", "middle").transition().style("opacity", null); }; _proto.updateStanfordElements = function updateStanfordElements(duration) { if (duration === void 0) { duration = 0; } this.updateStanfordLines(duration); this.updateStanfordRegions(duration); }; _proto.xvCustom = function xvCustom(d, xyValue) { var $$ = this, axis = $$.axis, config = $$.config, value = xyValue ? d[xyValue] : $$.getBaseValue(d); if (axis.isTimeSeries()) { value = parseDate.call($$, value); } else if (axis.isCategorized() && isString(value)) { value = config.axis_x_categories.indexOf(d.value); } return Math.ceil($$.scale.x(value)); }; _proto.yvCustom = function yvCustom(d, xyValue) { var $$ = this, yScale = d.axis && d.axis === "y2" ? $$.scale.y2 : $$.scale.y, value = xyValue ? d[xyValue] : $$.getBaseValue(d); return Math.ceil(yScale(value)); }; return Elements; }(); // EXTERNAL MODULE: external {"commonjs":"d3-axis","commonjs2":"d3-axis","amd":"d3-axis","root":"d3"} var external_commonjs_d3_axis_commonjs2_d3_axis_amd_d3_axis_root_d3_ = __webpack_require__(8); // EXTERNAL MODULE: external {"commonjs":"d3-format","commonjs2":"d3-format","amd":"d3-format","root":"d3"} var external_commonjs_d3_format_commonjs2_d3_format_amd_d3_format_root_d3_ = __webpack_require__(9); ;// CONCATENATED MODULE: ./src/Plugin/stanford/ColorScale.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Stanford diagram plugin color scale class * @class ColorScale * @param {Stanford} owner Stanford instance * @private */ var ColorScale = /*#__PURE__*/function () { function ColorScale(owner) { this.owner = void 0; this.colorScale = void 0; this.owner = owner; } var _proto = ColorScale.prototype; _proto.drawColorScale = function drawColorScale() { var _this$owner = this.owner, $$ = _this$owner.$$, config = _this$owner.config, target = $$.data.targets[0], height = $$.state.height - config.padding_bottom - config.padding_top, barWidth = config.scale_width, barHeight = 5, points = getRange(config.padding_bottom, height, barHeight), inverseScale = (0,external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleSequential)(target.colors).domain([points[points.length - 1], points[0]]); if (this.colorScale) { this.colorScale.remove(); } this.colorScale = $$.$el.svg.append("g").attr("width", 50).attr("height", height).attr("class", stanford_classes.colorScale); this.colorScale.append("g").attr("transform", "translate(0, " + config.padding_top + ")").selectAll("bars").data(points).enter().append("rect").attr("y", function (d, i) { return i * barHeight; }).attr("x", 0).attr("width", barWidth).attr("height", barHeight).attr("fill", function (d) { return inverseScale(d); }); // Legend Axis var axisScale = (0,external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleLog)().domain([target.minEpochs, target.maxEpochs]).range([points[0] + config.padding_top + points[points.length - 1] + barHeight - 1, points[0] + config.padding_top]), legendAxis = (0,external_commonjs_d3_axis_commonjs2_d3_axis_amd_d3_axis_root_d3_.axisRight)(axisScale), scaleFormat = config.scale_format; if (scaleFormat === "pow10") { legendAxis.tickValues([1, 10