billboard.js
Version:
Re-usable easy interface JavaScript chart library, based on D3 v4+
1,578 lines (1,534 loc) • 55.4 kB
JavaScript
/*!
* 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 4.0.1
* @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-scale"), require("d3-axis"), require("d3-selection"));
else if(typeof define === 'function' && define.amd)
define("bb", ["d3-interpolate", "d3-scale", "d3-axis", "d3-selection"], factory);
else if(typeof exports === 'object')
exports["bb"] = factory(require("d3-interpolate"), require("d3-scale"), require("d3-axis"), require("d3-selection"));
else
root["bb"] = root["bb"] || {}, root["bb"]["plugin"] = root["bb"]["plugin"] || {}, root["bb"]["plugin"]["stanford"] = factory(root["d3"], root["d3"], root["d3"], root["d3"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE__4__, __WEBPACK_EXTERNAL_MODULE__5__, __WEBPACK_EXTERNAL_MODULE__6__, __WEBPACK_EXTERNAL_MODULE__1__) {
return /******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/***/ (function(module) {
module.exports = __WEBPACK_EXTERNAL_MODULE__1__;
/***/ }),
/* 2 */,
/* 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__;
/***/ })
/******/ ]);
/************************************************************************/
/******/ // 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 needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
!function() {
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"default": function() { return /* binding */ Stanford; }
});
// 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__(4);
// 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__(5);
;// ./src/config/classes.ts
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
const $COMMON = {
button: "bb-button",
chart: "bb-chart",
empty: "bb-empty",
main: "bb-main",
target: "bb-target",
EXPANDED: "_expanded_",
dummy: "_dummy_"
};
const $ARC = {
arc: "bb-arc",
arcLabelLine: "bb-arc-label-line",
arcLabelLineText: "bb-arc-label-line-text",
arcRange: "bb-arc-range",
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",
axisXTooltip: "bb-axis-x-tooltip",
axisYTooltip: "bb-axis-y-tooltip",
axisY2Tooltip: "bb-axis-y2-tooltip",
axisTooltipX: "bb-axis-tooltip-x",
axisTooltipY: "bb-axis-tooltip-y"
};
const $BAR = {
bar: "bb-bar",
bars: "bb-bars",
chartBar: "bb-chart-bar",
chartBars: "bb-chart-bars",
barConnectLine: "bb-bar-connectLine"
};
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 $FUNNEL = {
funnel: "bb-funnel",
chartFunnel: "bb-chart-funnel",
chartFunnels: "bb-chart-funnels",
funnelBackground: "bb-funnel-background"
};
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",
textBorderRect: "bb-text-border",
textLabelImage: "bb-text-label-image",
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 = (__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, $COMMON), $ARC), $AREA), $AXIS), $BAR), $CANDLESTICK), $CIRCLE), $COLOR), $DRAG), $GAUGE), $LEGEND), $LINE), $EVENT), $FOCUS), $FUNNEL), $GRID), $LEVEL), $RADAR), $REGION), $SELECT), $SHAPE), $SUBCHART), $TEXT), $TOOLTIP), $TREEMAP), $ZOOM));
;// ./src/module/util/type-checks.ts
const isValue = (v) => v || v === 0;
const isFunction = (v) => typeof v === "function";
const isString = (v) => typeof v === "string";
const isNumber = (v) => typeof v === "number";
const isUndefined = (v) => typeof v === "undefined";
const isDefined = (v) => typeof v !== "undefined";
const isBoolean = (v) => typeof v === "boolean";
const ceil10 = (v) => Math.ceil(v / 10) * 10;
const asHalfPixel = (n) => Math.ceil(n) + 0.5;
const diffDomain = (d) => d[1] - d[0];
const isObjectType = (v) => typeof v === "object";
const isEmptyObject = (obj) => {
for (const x in obj) {
return false;
}
return true;
};
const isEmpty = (o) => isUndefined(o) || o === null || isString(o) && o.length === 0 || isObjectType(o) && !(o instanceof Date) && isEmptyObject(o) || isNumber(o) && isNaN(o);
const notEmpty = (o) => !isEmpty(o);
const isArray = (arr) => Array.isArray(arr);
const isObject = (obj) => obj && !(obj == null ? void 0 : obj.nodeType) && isObjectType(obj) && !isArray(obj);
;// ./src/config/config.ts
function loadConfig(config) {
const thisConfig = this.config;
let target;
let keys;
let read;
const find = () => {
const key = keys.shift();
if (key && target && isObjectType(target) && key in target) {
target = target[key];
return find();
} else if (!key) {
return target;
}
return void 0;
};
Object.keys(thisConfig).forEach((key) => {
target = config;
keys = key.split("_");
read = find();
if (isDefined(read)) {
thisConfig[key] = read;
}
});
if (this.api) {
this.state.orgConfig = config;
}
}
;// ./src/Plugin/Plugin.ts
var Plugin_defProp = Object.defineProperty;
var Plugin_defNormalProp = (obj, key, value) => key in obj ? Plugin_defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => Plugin_defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
class Plugin {
/**
* Constructor
* @param {Any} options config option object
* @private
*/
constructor(options = {}) {
__publicField(this, "$$");
__publicField(this, "options");
__publicField(this, "config");
this.options = options;
}
/**
* Load plugin config from options
* @private
*/
loadConfig() {
loadConfig.call(this, this.options);
}
/**
* Lifecycle hook for 'beforeInit' phase.
* @private
*/
$beforeInit() {
}
/**
* Lifecycle hook for 'init' phase.
* @private
*/
$init() {
}
/**
* Lifecycle hook for 'afterInit' phase.
* @private
*/
$afterInit() {
}
/**
* Lifecycle hook for 'redraw' phase.
* @private
*/
$redraw() {
}
/**
* Lifecycle hook for 'willDestroy' phase.
* @private
*/
$willDestroy() {
Object.keys(this).forEach((key) => {
this[key] = null;
delete this[key];
});
}
}
__publicField(Plugin, "version", "4.0.1");
// 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__(6);
;// ./src/Plugin/stanford/classes.ts
/* 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"
});
;// ./src/module/browser.ts
function getGlobal() {
return typeof globalThis === "object" && globalThis !== null && globalThis.Object === Object && globalThis || typeof self === "object" && self !== null && self.Object === Object && self || Function("return this")();
}
function getFallback(w) {
const hasRAF = typeof (w == null ? void 0 : w.requestAnimationFrame) === "function" && typeof (w == null ? void 0 : w.cancelAnimationFrame) === "function";
const hasRIC = typeof (w == null ? void 0 : w.requestIdleCallback) === "function" && typeof (w == null ? void 0 : w.cancelIdleCallback) === "function";
const request = (cb) => setTimeout(cb, 1);
const cancel = (id) => clearTimeout(id);
return [
hasRAF ? w.requestAnimationFrame : request,
hasRAF ? w.cancelAnimationFrame : cancel,
hasRIC ? w.requestIdleCallback : request,
hasRIC ? w.cancelIdleCallback : cancel
];
}
const win = getGlobal();
const doc = win == null ? void 0 : win.document;
const [
requestAnimationFrame,
cancelAnimationFrame,
requestIdleCallback,
cancelIdleCallback
] = getFallback(win);
;// ./src/module/sanitize.ts
const ALLOWED_TAGS = /* @__PURE__ */ new Set([
// HTML tags for tooltip/legend templates
"span",
"div",
"p",
"br",
"b",
"i",
"em",
"small",
"strong",
"mark",
"u",
"s",
"sub",
"sup",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"ul",
"ol",
"li",
"dl",
"dt",
"dd",
"table",
"thead",
"tbody",
"tfoot",
"tr",
"th",
"td",
"caption",
"colgroup",
"col",
"hr",
"pre",
"code",
"blockquote",
"abbr",
"ins",
"del",
"a",
"img",
"figure",
"figcaption",
// SVG tags for point patterns
"svg",
"g",
"path",
"circle",
"ellipse",
"rect",
"line",
"polyline",
"polygon",
"text",
"tspan",
"textPath",
"use",
"defs",
"symbol",
"clipPath",
"mask",
"linearGradient",
"radialGradient",
"stop",
"pattern",
"marker",
"title",
"desc"
]);
const ALLOWED_ATTRS = /* @__PURE__ */ new Set([
// Common attributes
"class",
"id",
"style",
"title",
"lang",
"dir",
// HTML specific
"href",
"src",
"alt",
"width",
"height",
"colspan",
"rowspan",
"scope",
"headers",
// SVG presentation attributes
"d",
"points",
"x",
"y",
"x1",
"x2",
"y1",
"y2",
"cx",
"cy",
"r",
"rx",
"ry",
"dx",
"dy",
"viewBox",
"preserveAspectRatio",
"transform",
"fill",
"fill-opacity",
"fill-rule",
"stroke",
"stroke-width",
"stroke-opacity",
"stroke-linecap",
"stroke-linejoin",
"stroke-dasharray",
"stroke-dashoffset",
"opacity",
"clip-path",
"clip-rule",
"mask",
"font-family",
"font-size",
"font-weight",
"font-style",
"text-anchor",
"dominant-baseline",
"offset",
"stop-color",
"stop-opacity",
"gradientUnits",
"gradientTransform",
"spreadMethod",
"patternUnits",
"patternTransform",
"marker-start",
"marker-mid",
"marker-end",
"markerWidth",
"markerHeight",
"refX",
"refY",
"xlink:href"
]);
const TAG_CASE_MAP = /* @__PURE__ */ new Map();
ALLOWED_TAGS.forEach((tag) => TAG_CASE_MAP.set(tag.toLowerCase(), tag));
const ATTR_CASE_MAP = /* @__PURE__ */ new Map();
ALLOWED_ATTRS.forEach((attr) => ATTR_CASE_MAP.set(attr.toLowerCase(), attr));
const ALLOWED_URI_PROTOCOLS = /* @__PURE__ */ new Set([
"http:",
"https:",
"mailto:"
]);
const URI_ATTRS = /* @__PURE__ */ new Set(["href", "src", "xlink:href"]);
const TAG_NAME_REGEX = /^<\/?([a-zA-Z][a-zA-Z0-9]*)/;
const CLOSING_TAG_REGEX = /^<\/([a-zA-Z][a-zA-Z0-9]*)\s*>$/;
const OPENING_TAG_REGEX = /^<([a-zA-Z][a-zA-Z0-9]*)([\s\S]*?)(\/?)>$/;
const ATTR_REGEX = /([a-zA-Z][\w:-]*)\s*(?:=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/g;
const URL_IN_STYLE_REGEX = /url\s*\(\s*["']?([^"')]+)["']?\s*\)/gi;
const DANGEROUS_CSS_PATTERNS = [
"expression(",
"behavior:",
"binding:",
"@import",
"@charset",
"-moz-binding:"
];
function decodeHTMLEntities(str) {
return str.replace(/:/gi, ":").replace(/&newline;/gi, "\n").replace(/&tab;/gi, " ").replace(/ /gi, " ").replace(/</gi, "<").replace(/>/gi, ">").replace(/&/gi, "&").replace(/"/gi, '"').replace(/'/gi, "'").replace(/&#(\d+);?/gi, (_, code) => String.fromCharCode(parseInt(code, 10))).replace(/&#x([0-9a-f]+);?/gi, (_, code) => String.fromCharCode(parseInt(code, 16)));
}
function isSafeURI(uri) {
const decoded = decodeHTMLEntities(uri).trim();
const normalized = decoded.replace(/[\s\u0000-\u001f]/g, "").toLowerCase();
if (!normalized || normalized.startsWith("#")) {
return true;
}
const schemeMatch = normalized.match(/^[^/?#]*:/);
if (schemeMatch) {
return ALLOWED_URI_PROTOCOLS.has(schemeMatch[0]);
}
return true;
}
function sanitizeStyleValue(style) {
const decoded = decodeHTMLEntities(style);
const cleaned = decoded.replace(/[\u0000-\u001f]/g, "");
URL_IN_STYLE_REGEX.lastIndex = 0;
let match;
while ((match = URL_IN_STYLE_REGEX.exec(cleaned)) !== null) {
if (!isSafeURI(match[1])) {
return null;
}
}
const normalizedLower = cleaned.toLowerCase().replace(/\s/g, "");
for (const pattern of DANGEROUS_CSS_PATTERNS) {
if (normalizedLower.includes(pattern)) {
return null;
}
}
return style;
}
const ATTR_ENCODE_MAP = {
'"': """,
"'": "'",
"`": "`"
};
const ATTR_ENCODE_REGEX = /["'`]/g;
function encodeAttrValue(value) {
return value.replace(ATTR_ENCODE_REGEX, (char) => ATTR_ENCODE_MAP[char]);
}
function sanitizeAttrValue(name, value, wasUnquoted = false) {
if (URI_ATTRS.has(name)) {
if (!isSafeURI(value)) {
return null;
}
return wasUnquoted ? encodeAttrValue(value) : value;
}
if (name === "style") {
const sanitizedStyle = sanitizeStyleValue(value);
if (sanitizedStyle === null) {
return null;
}
return wasUnquoted ? encodeAttrValue(sanitizedStyle) : sanitizedStyle;
}
const decoded = decodeHTMLEntities(value).toLowerCase().replace(/\s/g, "");
if (/\bon\w+=/.test(decoded)) {
return null;
}
return wasUnquoted ? encodeAttrValue(value) : value;
}
function extractTagName(tag) {
const match = tag.match(TAG_NAME_REGEX);
return match ? match[1].toLowerCase() : null;
}
function isAllowedTag(tag) {
const tagName = extractTagName(tag);
return tagName !== null && TAG_CASE_MAP.has(tagName);
}
function sanitizeTag(fullTag) {
var _a, _b, _c;
const closingMatch = fullTag.match(CLOSING_TAG_REGEX);
if (closingMatch) {
const lowerName = closingMatch[1].toLowerCase();
return `</${(_a = TAG_CASE_MAP.get(lowerName)) != null ? _a : lowerName}>`;
}
const openingMatch = fullTag.match(OPENING_TAG_REGEX);
if (!openingMatch) {
return "";
}
const [, tagName, attrString, selfClose] = openingMatch;
const lowerTagName = tagName.toLowerCase();
const canonicalTagName = (_b = TAG_CASE_MAP.get(lowerTagName)) != null ? _b : lowerTagName;
const allowedAttrs = [];
ATTR_REGEX.lastIndex = 0;
let attrMatch;
while ((attrMatch = ATTR_REGEX.exec(attrString)) !== null) {
const lowerAttrName = attrMatch[1].toLowerCase();
const doubleQuotedValue = attrMatch[2];
const singleQuotedValue = attrMatch[3];
const unquotedValue = attrMatch[4];
if (lowerAttrName.startsWith("on")) {
continue;
}
const canonicalAttrName = (_c = ATTR_CASE_MAP.get(lowerAttrName)) != null ? _c : lowerAttrName;
let attrValue;
let quoteChar;
if (doubleQuotedValue !== void 0) {
attrValue = doubleQuotedValue;
quoteChar = '"';
} else if (singleQuotedValue !== void 0) {
attrValue = singleQuotedValue;
quoteChar = "'";
} else if (unquotedValue !== void 0) {
attrValue = unquotedValue;
quoteChar = '"';
} else {
if (ATTR_CASE_MAP.has(lowerAttrName)) {
allowedAttrs.push(canonicalAttrName);
}
continue;
}
if (ATTR_CASE_MAP.has(lowerAttrName)) {
const wasUnquoted = unquotedValue !== void 0;
const sanitizedValue = sanitizeAttrValue(lowerAttrName, attrValue, wasUnquoted);
if (sanitizedValue !== null) {
allowedAttrs.push(`${canonicalAttrName}=${quoteChar}${sanitizedValue}${quoteChar}`);
}
}
}
const attrsStr = allowedAttrs.length > 0 ? ` ${allowedAttrs.join(" ")}` : "";
const selfCloseStr = selfClose ? "/>" : ">";
return `<${canonicalTagName}${attrsStr}${selfCloseStr}`;
}
function sanitize(str) {
if (typeof str !== "string" || !str || str.indexOf("<") === -1) {
return str;
}
return str.replace(
/<\/?[^>]*>|[^<>\s]+>/g,
(match) => {
if (match.startsWith("<!--")) {
return "";
}
if (!match.startsWith("<")) {
return match.slice(0, -1) + ">";
}
if (isAllowedTag(match)) {
return sanitizeTag(match);
}
return match.replace(/</g, "<");
}
);
}
;// ./src/module/util/object.ts
var object_defProp = Object.defineProperty;
var object_getOwnPropSymbols = Object.getOwnPropertySymbols;
var object_hasOwnProp = Object.prototype.hasOwnProperty;
var object_propIsEnum = Object.prototype.propertyIsEnumerable;
var object_defNormalProp = (obj, key, value) => key in obj ? object_defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var object_spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (object_hasOwnProp.call(b, prop))
object_defNormalProp(a, prop, b[prop]);
if (object_getOwnPropSymbols)
for (var prop of object_getOwnPropSymbols(b)) {
if (object_propIsEnum.call(b, prop))
object_defNormalProp(a, prop, b[prop]);
}
return a;
};
function _forEachValidItem(items, callback) {
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item !== null && isDefined(item)) {
callback(item, i);
}
}
}
function getOption(options, key, defaultValue) {
return isDefined(options[key]) ? options[key] : defaultValue;
}
function hasValue(dict, value) {
for (const key in dict) {
if (dict[key] === value) return true;
}
return false;
}
function callFn(fn, thisArg, ...args) {
const isFn = isFunction(fn);
isFn && fn.call(thisArg, ...args);
return isFn;
}
function endall(transition, cb) {
let n = 0;
const end = function(...args) {
!--n && cb.apply(this, args);
};
if ("duration" in transition) {
transition.each(() => ++n).on("end", end);
} else {
++n;
transition.call(end);
}
}
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
function camelize(str, separator = "-") {
return str.split(separator).map((v, i) => i ? v.charAt(0).toUpperCase() + v.slice(1).toLowerCase() : v.toLowerCase()).join("");
}
const toArray = (v) => [].slice.call(v);
function deepClone(...objectN) {
const clone = (v) => {
if (isArray(v)) {
return v.map(clone);
} else if (isObject(v) && v.constructor) {
const r = new v.constructor();
for (const k in v) {
r[k] = clone(v[k]);
}
return r;
}
return v;
};
return objectN.map((v) => clone(v)).reduce((a, c) => object_spreadValues(object_spreadValues({}, a), c));
}
function extend(target = {}, source) {
if (isArray(source)) {
source.forEach((v) => extend(target, v));
}
for (const p in source) {
if (/^\d+$/.test(p) || p in target) {
continue;
}
target[p] = source[p];
}
return target;
}
function getUnique(data) {
const isDate = data[0] instanceof Date;
const d = Array.from(new Set(isDate ? data.map(Number) : data));
return isDate ? d.map((v) => new Date(v)) : d;
}
function mergeArray(arr) {
return arr && arr.length ? arr.reduce((p, c) => p.concat(c)) : [];
}
function mergeObj(target, ...objectN) {
if (!objectN.length || objectN.length === 1 && !objectN[0]) {
return target;
}
const source = objectN.shift();
if (isObject(target) && isObject(source)) {
Object.keys(source).forEach((key) => {
if (!/^(__proto__|constructor|prototype)$/i.test(key)) {
const value = source[key];
if (value instanceof Date) {
target[key] = new Date(value.getTime());
} else if (isObject(value)) {
!target[key] && (target[key] = {});
target[key] = mergeObj(target[key], value);
} else {
target[key] = isArray(value) ? value.concat() : value;
}
}
});
}
return mergeObj(target, ...objectN);
}
function sortValue(data, isAsc = true) {
let fn;
if (data[0] instanceof Date) {
fn = isAsc ? (a, b) => a - b : (a, b) => b - a;
} else {
if (isAsc && !data.every(isNaN)) {
fn = (a, b) => a - b;
} else if (!isAsc) {
fn = (a, b) => a > b && -1 || a < b && 1 || a === b && 0;
}
}
return data.concat().sort(fn);
}
function getMinMax(type, data) {
let res = data.filter((v) => notEmpty(v));
if (res.length) {
if (isNumber(res[0])) {
let result = type === "min" ? Infinity : -Infinity;
for (const v of res) {
if (type === "min" ? v < result : v > result) {
result = v;
}
}
res = result;
} else if (res[0] instanceof Date) {
res = sortValue(res, type === "min")[0];
}
} else {
res = void 0;
}
return res;
}
const getRange = (start, end, step = 1) => {
const res = [];
const n = Math.max(0, Math.ceil((end - start) / step)) | 0;
for (let i = 0; i < n; i++) {
res.push(start + i * step);
}
return res;
};
let _transitionCounter = 0;
function getRandom(asStr = true) {
const id = ++_transitionCounter;
return asStr ? String(id) : id;
}
function findIndex(arr, v, start, end, isRotated) {
if (start > end) {
return -1;
}
const mid = Math.floor((start + end) / 2);
let { x, w = 0 } = arr[mid];
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);
}
function tplProcess(tpl, data) {
return sanitize(tpl.replace(/\{=([^}]+)\}/g, (_, key) => {
var _a;
return (_a = data[key]) != null ? _a : "";
}));
}
function parseDate(date) {
var _a;
let parsedDate;
if (date instanceof Date) {
parsedDate = date;
} else if (isString(date)) {
const { config, format } = this;
parsedDate = (_a = format.dataTime(config.data_xFormat)(date)) != null ? _a : new Date(date);
} else if (isNumber(date) && !isNaN(date)) {
parsedDate = /* @__PURE__ */ new Date(+date);
}
if (!parsedDate || isNaN(+parsedDate)) {
console && console.error && console.error(`Failed to parse x '${date}' to Date object`);
}
return parsedDate;
}
function parseShorthand(value) {
if (isObject(value) && !isString(value)) {
const obj = value;
return {
top: obj.top || 0,
right: obj.right || 0,
bottom: obj.bottom || 0,
left: obj.left || 0
};
}
const values = (isString(value) ? value.trim().split(/\s+/) : [value]).map((v) => +v || 0);
const [a, b = a, c = a, d = b] = values;
return { top: a, right: b, bottom: c, left: d };
}
function runUntil(fn, conditionFn) {
if (conditionFn() === false) {
requestAnimationFrame(() => runUntil(fn, conditionFn));
} else {
fn();
}
}
function toSet(items, keyFn = ((item) => item)) {
const set = /* @__PURE__ */ new Set();
_forEachValidItem(items, (item, i) => {
set.add(keyFn(item, i));
});
return set;
}
function toMap(items, keyFn, valueFn = ((item) => item)) {
const map = /* @__PURE__ */ new Map();
_forEachValidItem(items, (item, i) => {
map.set(keyFn(item, i), valueFn(item, i));
});
return map;
}
// 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);
;// ./src/module/util/dom.ts
const RE_CSS_BB = /\s?(bb-)/g;
const RE_CSS_DOTS = /\.+/g;
function getCssSelector(s) {
return s.replace(RE_CSS_BB, ".$1").replace(RE_CSS_DOTS, ".");
}
function _getRect(relativeViewport, node, forceEval = false) {
const _ = (n) => n[relativeViewport ? "getBoundingClientRect" : "getBBox"]();
const cacheKey = relativeViewport ? "rectClient" : "rectBBox";
if (forceEval) {
return _(node);
} else {
const needEvaluate = !(cacheKey in node) || node.hasAttribute("width") && node[cacheKey].width !== +(node.getAttribute("width") || 0);
return needEvaluate ? node[cacheKey] = _(node) : node[cacheKey];
}
}
function setTextValue(node, text, dy = [-1, 1], toMiddle = false) {
if (!node || !isString(text)) {
return;
}
if (text.indexOf("\n") === -1) {
node.text(text);
} else {
const diff = [node.text(), text].map((v) => v.replace(/[\s\n]/g, ""));
if (diff[0] !== diff[1]) {
const multiline = text.split("\n");
const len = toMiddle ? multiline.length - 1 : 1;
node.html("");
multiline.forEach((v, i) => {
node.append("tspan").attr("x", 0).attr("dy", `${i === 0 ? dy[0] * len : dy[1]}em`).text(v);
});
}
}
}
function getRectSegList(path) {
const { x, y, width, height } = getBBox(path, true);
return [
{ x, y: y + height },
// seg0
{ x, y },
// seg1
{ x: x + width, y },
// seg2
{ x: x + width, y: y + height }
// seg3
];
}
function getPathBox(path) {
const { width, height } = getBoundingRect(path);
const items = getRectSegList(path);
const x = items[0].x;
const y = Math.min(items[0].y, items[1].y);
return {
x,
y,
width,
height
};
}
function getPointer(event, element) {
var _a;
const touches = event && ((_a = event.touches || event.sourceEvent && event.sourceEvent.touches) == null ? void 0 : _a[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((v) => isNaN(v) ? 0 : v);
}
function getBoundingRect(node, forceEval = false) {
return _getRect(true, node, forceEval);
}
function getBBox(node, forceEval = false) {
return _getRect(false, node, forceEval);
}
function addCssRules(style, selector, prop) {
const { rootSelector = "", sheet } = style;
const rule = `${rootSelector} ${getCssSelector(selector)} {${prop.join(";")}}`;
return sheet[sheet.insertRule ? "insertRule" : "addRule"](
rule,
sheet.cssRules.length
);
}
function getCssRules(styleSheets) {
let rules = [];
styleSheets.forEach((sheet) => {
var _a;
try {
if (sheet.cssRules && sheet.cssRules.length) {
rules = rules.concat(toArray(sheet.cssRules));
}
} catch (e) {
(_a = win.console) == null ? void 0 : _a.warn(`Error while reading rules from ${sheet.href}: ${String(e)}`);
}
});
return rules;
}
function getScrollPosition(node) {
var _a, _b, _c, _d, _e, _f;
return {
x: ((_b = (_a = win.pageXOffset) != null ? _a : win.scrollX) != null ? _b : 0) + ((_c = node.scrollLeft) != null ? _c : 0),
y: ((_e = (_d = win.pageYOffset) != null ? _d : win.scrollY) != null ? _e : 0) + ((_f = node.scrollTop) != null ? _f : 0)
};
}
function getTransformCTM(node, x = 0, y = 0, inverse = true) {
const point = new DOMPoint(x, y);
const screen = node.getScreenCTM();
const res = point.matrixTransform(
inverse ? screen == null ? void 0 : screen.inverse() : screen
);
if (inverse === false) {
const rect = getBoundingRect(node);
res.x -= rect.x;
res.y -= rect.y;
}
return res;
}
function getTranslation(node) {
const transform = node ? node.transform : null;
const baseVal = transform && transform.baseVal;
return baseVal && baseVal.numberOfItems ? baseVal.getItem(0).matrix : { a: 0, b: 0, c: 0, d: 0, e: 0, f: 0 };
}
function getElementPos(element, type) {
var _a;
const attr = (_a = element == null ? void 0 : element.getAttribute) == null ? void 0 : _a.call(element, type);
if (attr) {
return parseFloat(attr);
}
const matrix = getTranslation(element);
return type === "x" ? matrix.e : matrix.f;
}
function hasViewBox(svg) {
const attr = svg.attr("viewBox");
return attr ? attr.trim().split(/[\s,]+/).length === 4 : false;
}
function hasStyle(node, condition, all = false) {
const isD3Node = !!node.node;
let has = false;
for (const [key, value] of Object.entries(condition)) {
has = isD3Node ? node.style(key) === value : node.style[key] === value;
if (all ? !has : has) {
break;
}
}
return has;
}
function isTabVisible() {
var _a, _b;
return ((_a = doc) == null ? void 0 : _a.hidden) === false || ((_b = doc) == null ? void 0 : _b.visibilityState) === "visible";
}
function convertInputType(mouse, touch) {
const { DocumentTouch, matchMedia, navigator } = win;
const hasPointerCoarse = matchMedia == null ? void 0 : matchMedia("(pointer:coarse)").matches;
let hasTouch = false;
if (touch) {
if (navigator && "maxTouchPoints" in navigator) {
hasTouch = navigator.maxTouchPoints > 0;
} else if ("ontouchmove" in win || DocumentTouch && doc instanceof DocumentTouch) {
hasTouch = true;
} else {
if (hasPointerCoarse) {
hasTouch = true;
} else {
const UA = navigator.userAgent;
hasTouch = /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) || /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA);
}
}
}
const hasMouse = mouse && !hasPointerCoarse && (matchMedia == null ? void 0 : matchMedia("(pointer:fine)").matches);
return hasMouse && "mouse" || hasTouch && "touch" || "mouse";
}
function scheduleRAFUpdate(rafState, callback) {
if (rafState.pendingRaf !== null) {
win.cancelAnimationFrame(rafState.pendingRaf);
rafState.pendingRaf = win.requestAnimationFrame(() => {
rafState.pendingRaf = null;
callback();
});
} else {
rafState.pendingRaf = win.requestAnimationFrame(() => {
rafState.pendingRaf = null;
});
callback();
}
}
const emulateEvent = {
mouse: (() => {
const getParams = () => ({
bubbles: false,
cancelable: false,
screenX: 0,
screenY: 0,
clientX: 0,
clientY: 0
});
try {
new MouseEvent("t");
return (el, eventType, params = getParams()) => {
el.dispatchEvent(new MouseEvent(eventType, params));
};
} catch (e) {
return (el, eventType, params = getParams()) => {
const mouseEvent = doc.createEvent("MouseEvent");
mouseEvent.initMouseEvent(
eventType,
params.bubbles,
params.cancelable,
win,
0,
// the event's mouse click count
params.screenX,
params.screenY,
params.clientX,
params.clientY,
false,
false,
false,
false,
0,
null
);
el.dispatchEvent(mouseEvent);
};
}
})(),
touch: (el, eventType, params) => {
const touchObj = new Touch(mergeObj({
identifier: Date.now(),
target: el,
radiusX: 2.5,
radiusY: 2.5,
rotationAngle: 10,
force: 0.5
}, params));
el.dispatchEvent(new TouchEvent(eventType, {
cancelable: true,
bubbles: true,
shiftKey: true,
touches: [touchObj],
targetTouches: [],
changedTouches: [touchObj]
}));
}
};
;// ./src/Plugin/stanford/ColorScale.ts
var ColorScale_defProp = Object.defineProperty;
var ColorScale_defNormalProp = (obj, key, value) => key in obj ? ColorScale_defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var ColorScale_publicField = (obj, key, value) => ColorScale_defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
function format(specifier) {
if (specifier === "d") {
return (n) => Math.round(n).toString();
}
return (n) => String(n);
}
class ColorScale {
constructor(owner) {
ColorScale_publicField(this, "owner");
ColorScale_publicField(this, "colorScale");
this.owner = owner;
}
drawColorScale() {
const { $$, config } = this.owner;
const target = $$.data.targets[0];
const height = $$.state.height - config.padding_bottom - config.padding_top;
const barWidth = config.scale_width;
const barHeight = 5;
const points = getRange(config.padding_bottom, height, barHeight);
const 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", (d, i) => i * barHeight).attr("x", 0).attr("width", barWidth).attr("height", barHeight).attr("fill", (d) => inverseScale(d));
const axisScale = (0,external_commonjs_d3_scale_commonjs2_d3_scale_amd_d3_scale_root_d3_.scaleSymlog)().domain([target.minEpochs, target.maxEpochs]).range([
points[0] + config.padding_top + points[points.length - 1] + barHeight - 1,
points[0] + config.padding_top
]);
const legendAxis = (0,external_commonjs_d3_axis_commonjs2_d3_axis_amd_d3_axis_root_d3_.axisRight)(axisScale);
const scaleFormat = config.scale_format;
if (scaleFormat === "pow10") {
legendAxis.tickValues([1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7]);
} else if (isFunction(scaleFormat)) {
legendAxis.tickFormat(scaleFormat);
} else {
legendAxis.tickFormat(format("d"));
}
const axis = this.colorScale.append("g").attr("class", "legend axis").attr("transform", `translate(${barWidth},0)`).call(legendAxis);
if (scaleFormat === "pow10") {
axis.selectAll(".tick text").text(null).filter((d) => d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1).text(10).append("tspan").attr("dy", "-.7em").text((d) => Math.round(Math.log(d) / Math.LN10));
}
this.colorScale.attr(
"transform",
`translate(${$$.state.current.width - this.xForColorScale()}, 0)`
);
}
xForColorScale() {
return this.owner.config.padding_right + getBBox(this.colorScale.node(), true).width;
}
getColorScalePadding() {
return this.xForColorScale() + this.owner.config.padding_left + 20;
}
}
;// ./src/Plugin/stanford/util.ts
function pointInRegion(point, region) {
const x = point.x;
const y = point.value;
let inside = false;
for (let i = 0, j = region.length - 1; i < region.length; j = i++) {
const xi = region[i].x;
const yi = region[i].y;
const xj = region[j].x;
const yj = region[j].y;
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
if (intersect) {
inside = !inside;
}
}
return inside;
}
function compareEpochs(a, b) {
if (a.epochs < b.epochs) {
return -1;
}
if (a.epochs > b.epochs) {
return 1;
}
return 0;
}
function getRegionArea(points) {
let area = 0;
let point1;
let point2;
for (let 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;
}
function getCentroid(points) {
const area = getRegionArea(points);
let x = 0;
let y = 0;
let f;
for (let i = 0, l = points.length, j = l - 1; i < l; j = i, i++) {
const point1 = points[i];
const 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
};
}
;// ./src/Plugin/stanford/Elements.ts
var Elements_defProp = Object.defineProperty;
var Elements_defNormalProp = (obj, key, value) => key in obj ? Elements_defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var Elements_publicField = (obj, key, value) => Elements_defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
class Elements {
constructor(owner) {
Elements_publicField(this, "owner");
this.owner = owner;
const 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);
}
updateStanfordLines(duration) {
const { $$ } = this.owner;
const { config, $el: { main } } = $$;
const isRotated = config.axis_rotated;
const xvCustom = this.xvCustom.bind($$);
const yvCustom = this.yvCustom.bind($$);
const stanfordLine = main.select(`.${stanford_classes.stanfordLines}`).style("shape-rendering", "geometricprecision").selectAll(`.${stanford_classes.stanfordLine}`).data(this.owner.config.lines);
stanfordLine.exit().transition().duration(duration).style("opacity", "0").remove();
const stanfordLineEnter = stanfordLine.enter().append("g");
stanfordLineEnter.append("line").style("opacity", "0");
stanfordLineEnter.merge(stanfordLine).attr("class", (d) => stanford_classes.stanfordLine + (d.class ? ` ${d.class}` : "")).select("line").transition().duration(duration).attr("x1", (d) => {
const v = isRotated ? yvCustom(d, "y1") : xvCustom(d, "x1");
return v;
}).attr("x2", (d) => isRotated ? yvCustom(d, "y2") : xvCustom(d, "x2")).attr("y1", (d) => {
const v = isRotated ? xvCustom(d, "x1") : yvCustom(d, "y1");
return v;
}).attr("y2", (d) => isRotated ? xvCustom(d, "x2") : yvCustom(d, "y2")).transition().style("opacity", null);
}
updateStanfordRegions(duration) {
const { $$ } = this.owner;
const { config, $el: { main } } = $$;
const isRotated = config.axis_rotated;
const xvCustom = this.xvCustom.bind($$);
const yvCustom = this.yvCustom.bind($$);
const countPointsInRegion = this.owner.countEpochsInRegion.bind($$);
let stanfordRegion = main.select(`.${stanford_classes.stanfordRegions}`).selectAll(`.${stanford_classes.stanfordRegion}`).data(this.owner.config.regions);
stanfordRegion.exit().transition().duration(duration).style("opacity", "0").remove();
const 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);
stanfordRegion.attr("class", (d) => stanford_classes.stanfordRegion + (d.class ? ` ${d.class}` : "")).select("polygon").transition().duration(duration).attr("points", (d) => d.points.map(
(value) => [
isRotated ? yvCustom(value, "y") : xvCustom(value, "x"),
isRotated ? xvCustom(value, "x") : yvCustom(value, "y")
].join(",")
).join(" ")).transition().style("opacity", (d) => String(d.opacity ? d.opacity : 0.2));
stanfordRegion.select("text").transition().duration(duration).attr(
"x",
(d) => isRotated ? yvCustom(getCentroid(d.points), "y") : xvCustom(getCentroid(d.points), "x")
).attr(
"y",
(d) => isRotated ? xvCustom(getCentroid(d.points), "x") : yvCustom(getCentroid(d.points), "y")
).text((d) => {
if (d.text) {
const { value, percentage } = countPointsInRegion(d.points);
return d.text(value, percentage);
}
return "";
}).attr("text-anchor", "middle").attr("dominant-baseline", "middle").transition().style("opacity", null);
}
updateStanfordElements(duration = 0) {
this.updateStanfordLines(duration);
this.updateStanfordRegions(duration);
}
xvCustom(d, xyValue) {
const $$ = this;
const { axis, config } = $$;
let 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 $$.scale.x(value);
}
yvCustom(d, xyValue) {
const $$ = this;
const yScale = d.axis && d.axis === "y2" ? $$.scale.y2 : $$.scale.y;
const value = xyValue ? d[xyValue] : $$.getBaseValue(d);
return yScale(value);
}
}
;// ./src/Plugin/stanford/Options.ts
class Options {
constructor() {
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: void 0,
/**
* 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: void 0,
scale_max: void 0,
scale_width: 20,
scale_format: void 0,
/**
* 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` | <optional> | Sets the opacity of the region as value between 0 and 1 |
* | text | Function | | <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 | | <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