UNPKG

zz-chart

Version:

Alauda Chart components by Alauda Frontend Team

1,667 lines (1,630 loc) 139 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var lodashEs = require('lodash-es'); var onChange = require('on-change'); var uPlot = require('uplot'); var d3 = require('d3'); var noImportant_js = require('aphrodite/no-important.js'); var placement = require('placement.js'); var tinycolor = require('tinycolor2'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var onChange__default = /*#__PURE__*/_interopDefaultLegacy(onChange); var uPlot__default = /*#__PURE__*/_interopDefaultLegacy(uPlot); var d3__namespace = /*#__PURE__*/_interopNamespace(d3); var placement__default = /*#__PURE__*/_interopDefaultLegacy(placement); var tinycolor__default = /*#__PURE__*/_interopDefaultLegacy(tinycolor); class Coordinate { constructor(ctrl) { this.name = "coordinate"; this.isTransposed = false; this.ctrl = ctrl; this.render(); } render() { this.setOption(); } update() { this.setOption(); } setOption() { var _a; this.option = lodashEs.get(this.ctrl.getOption(), this.name); if (this.option) { this.isTransposed = (_a = this.option) == null ? void 0 : _a.transposed; } } transpose() { this.isTransposed = true; } getOptions() { const option = lodashEs.get(this.ctrl.getOption(), this.name); if (typeof option === "object" && option.transposed) { this.isTransposed = option.transposed; } return this.isTransposed ? { scales: { y: { ori: 0 } }, axes: [ {}, { side: 2 } ] } : {}; } } const INTERACTIONS = /* @__PURE__ */ new Map(); function registerInteraction(name, interaction) { INTERACTIONS.set(name, interaction); } function getInteraction(name) { return INTERACTIONS.get(name); } const ACTIONS = /* @__PURE__ */ new Map(); function registerAction(name, action) { ACTIONS.set(name, action); } function getAction(name) { return ACTIONS.get(name); } function executeAction(actionObject, context) { const action = actionObject.action; const { methodName } = actionObject; if (action == null ? void 0 : action[methodName]) { action[methodName](context); } else { throw new Error(`Action(${action.name}) doesn't have a method called ${methodName}`); } } class Interaction { constructor(view, steps) { this.callbackCaches = /* @__PURE__ */ new Map(); this.getActionObject = (actionStr) => { const [actionName, methodName] = actionStr.split(":"); const Action = getAction(actionName); if (!Action) { throw new Error(`There is no action named ${actionName}`); } return { action: new Action(this.view), methodName }; }; this.view = view; this.steps = steps; } init() { this.initActionObject(); this.initEvents(); } initEvents() { const point = this.view.shapeComponents.get("point"); lodashEs.each(this.steps, (value, stepName) => { value.forEach((step) => { const callback = this.getActionCallback(stepName, step); const isPlot = step.trigger.includes("plot"); this.view.on(point && isPlot ? step.trigger.replace("plot", "element") : step.trigger, callback); }); }); } initActionObject() { const steps = this.steps; lodashEs.each(steps, (subSteps) => { lodashEs.each(subSteps, (step) => { step.actionObject = this.getActionObject(step.action); }); }); } getActionCallback(stepName, step) { const callbackCaches = this.callbackCaches; if (step.action) { const key = stepName; if (!callbackCaches.get(key)) { const actionCallback = (context) => { var _a; executeAction(step.actionObject, context); (_a = step.callback) == null ? void 0 : _a.call(step, context); }; callbackCaches.set(stepName, actionCallback); } return callbackCaches.get(stepName); } return null; } clearEvents() { const point = this.view.shapeComponents.get("point"); lodashEs.each(this.steps, (value) => { value.forEach((step) => { const isPlot = step.trigger.includes("plot"); this.view.off(point && isPlot ? step.trigger.replace("plot", "element") : step.trigger); }); }); } destroy() { this.clearEvents(); } } class Reactive { constructor(target, chart) { this.dep = new Dep(chart); this.source = target; this.createReactiveObject(this.source); } createReactiveObject(target) { this.reactiveObject = onChange__default["default"](target, (path, value, previousValue, applyData) => { this.dep.notify({ path, value, previousValue, applyData }); }); return this.reactiveObject; } unsubscribe() { var _a; (_a = onChange__default["default"]) == null ? void 0 : _a.unsubscribe(this.createReactiveObject); } } function reactive(source, chart) { return new Reactive(source, chart); } class Dep { constructor(chart) { this.ctrl = chart; } notify({ path, value, previousValue }) { const names = path.split("."); this.syncConfig(names, value, previousValue); this.update(names, value); } syncConfig(names, value, previousValue) { let option = value; if (lodashEs.isObjectLike(value)) { option = lodashEs.merge(previousValue, value); } const [str, ...name] = names; this.ctrl.setOption(str === "options" ? name : names, option); } update(names, value) { if (names.includes("data") && names.length === 1) { this.ctrl.data(value); } if (names.includes("options") && names.length > 1) { const component = this.ctrl.components.get(names[1]); component == null ? void 0 : component.update(); } } } const ShapeType = { Line: "line", Area: "area", Bar: "bar", Point: "point" }; const SHAPE_TYPES = Object.values(ShapeType); const PolarShapeType = { Pie: "pie", Gauge: "gauge" }; const POLAR_SHAPE_TYPES = Object.values(PolarShapeType); const isValidHex = (hex) => /^#([\dA-Fa-f]{3,4}){1,2}$/.test(hex); const convertHexUnitTo256 = (hexStr) => parseInt(hexStr.repeat(2 / hexStr.length), 16); const getAlphafloat = (a, alpha) => { if (typeof a !== "undefined") { return a / 255; } if (typeof alpha !== "number" || alpha < 0 || alpha > 1) { return 1; } return alpha; }; function convertRgba(hex, alpha = 1) { if (hex.includes("var")) { const varColorStr = hex.replace(/^rgb\(var\(*/, "").replace(/\)\)/, ""); const varColor = getComputedStyle(document.body).getPropertyValue(varColorStr); const [r2, g2, b2] = varColor.split(",").map((d) => lodashEs.trim(d)); return `rgba(${r2}, ${g2}, ${b2}, ${alpha})`; } if (!isValidHex(hex)) { return hex; } const chunkSize = Math.floor((hex.length - 1) / 3); const hexArr = hex.slice(1).match(new RegExp(`.{${chunkSize}}`, "g")); const [r, g, b, a] = hexArr.map(convertHexUnitTo256); return `rgba(${r}, ${g}, ${b}, ${getAlphafloat(a, alpha)})`; } function getElementSize(ele) { const style = getComputedStyle(ele); return { width: (ele.clientWidth || parseInt(style.width, 10)) - parseInt(style.paddingLeft, 10) - parseInt(style.paddingRight, 10), height: (ele.clientHeight || parseInt(style.height, 10)) - parseInt(style.paddingTop, 10) - parseInt(style.paddingBottom, 10) }; } function getChartSize(ele, width = 0, height = 0) { let w = width || 0; let h = height || 0; if (!w && !h && ele) { const size = getElementSize(ele); w = size.width || w; h = size.height || h; } return { width: w, height: h }; } function getElement(container) { return typeof container === "string" ? document.querySelector(container) : container; } function transformD3El(dom) { return d3.select(dom); } function getPixel(value) { return typeof +value === "number" && !isNaN(+value) ? `${value}px` : value; } function resizeObserver(el, fn) { const resizeObserver2 = new ResizeObserver(lodashEs.debounce(([entry]) => { const { width, height } = entry.contentRect; if (width !== 0 || height !== 0) { const size = { width, height }; fn(size); } }, 200)); resizeObserver2.observe(el); return resizeObserver2; } function createSvg(el, width, height) { return el.append("svg").style("width", width || "100%").style("height", height || "100%").style("overflow", "hidden").style("display", "block"); } function getPos(e, isRotated, rectDom) { const svgE = e.target; const { scrollLeft, scrollTop } = document.documentElement; return isRotated ? e.pageY - ((rectDom || svgE).getBoundingClientRect().top + scrollTop) : e.pageX - ((rectDom || svgE).getBoundingClientRect().left + scrollLeft); } function isPercentage(num) { return !lodashEs.isNumber(num) && num.endsWith("%"); } function removeSymbol(str) { return (str == null ? void 0 : str.replace(/\W+/g, "")) || str; } function isHtml(str) { return /<\/?[a-z][\S\s]*>/i.test(str); } function abs(value) { return Math.abs(value); } function rgbColor(color) { return `rgb(var(--ac-color-${color}))`; } function rgbaColor([color, opacity]) { return `rgba(var(--ac-color-${color}), ${opacity})`; } function cssVar(value) { return `var(--ac-${value})`; } const CHART_PREFIX = "achart"; const HYPHEN = "-"; const NOT_AVAILABLE = HYPHEN; const DEFAULT_COLORS = [ "#006eff", "#24b37a", "#8b37c1", "#ffbb00", "#d42d3d", "#1fc0cc", "#a5d936", "#d563c4", "#c55a05", "#6b8fbb", "#1292d2", "#36d940", "#ea0abb", "#ead925", "#b0b55c" ]; const DEFAULT_INTERACTIONS = [ "tooltip" /* TOOLTIP */, "legend-active" /* LEGEND_ACTIVE */ ]; function getChartColor(index) { const colorIndex = index % DEFAULT_COLORS.length; return DEFAULT_COLORS[colorIndex]; } function generateName(name) { return `${CHART_PREFIX}-${name}`; } const TEMPLATE_OPTIONS = { interpolate: /{([\S\s]+?)}/g }; function template(str, data) { return lodashEs.template(str, TEMPLATE_OPTIONS)(data); } let _context$1; function getCanvasContext$1() { if (!_context$1) { _context$1 = document.createElement("canvas").getContext("2d"); } return _context$1; } function getOpacityGradientFn(color, opacity) { return (plot, _seriesIdx) => { const ctx = getCanvasContext$1(); const gradient = makeDirectionalGradient(plot.scales.x.ori === ScaleOrientation.Horizontal ? GradientDirection.Down : GradientDirection.Left, plot.bbox, ctx); gradient.addColorStop(0, alpha(color, opacity)); gradient.addColorStop(1, alpha(color, 0)); return gradient; }; } function alpha(color, value) { if (color === "") { return "#000000"; } value = clamp(value); if (color[0] === "#") { if (color.length === 9) { color = color.substring(0, 7); } else if (color.length <= 5) { let c = "#"; for (let i = 1; i < 4; i++) { c += color[i] + color[i]; } color = c; } return color + Math.round(value * 255).toString(16).padStart(2, "0"); } else if (color[3] === "(") { return color.replace(")", `, ${value})`); } else if (color[4] === "(") { return color.substring(0, color.lastIndexOf(",")) + `, ${value})`; } const parts = decomposeColor(color); if (parts.type === "color") { parts.values[3] = `/${value}`; } else { parts.values[3] = value; } return recomposeColor(parts); } function recomposeColor(color) { const { type, colorSpace } = color; let values = color.values; if (type.indexOf("rgb") !== -1) { values = values.map((n, i) => i < 3 ? parseInt(n, 10) : n); } else if (type.indexOf("hsl") !== -1) { values[1] = `${values[1]}%`; values[2] = `${values[2]}%`; } if (type.indexOf("color") !== -1) { values = `${colorSpace} ${values.join(" ")}`; } else { values = `${values.join(", ")}`; } return `${type}(${values})`; } var GradientDirection = /* @__PURE__ */ ((GradientDirection2) => { GradientDirection2[GradientDirection2["Right"] = 0] = "Right"; GradientDirection2[GradientDirection2["Up"] = 1] = "Up"; GradientDirection2[GradientDirection2["Left"] = 2] = "Left"; GradientDirection2[GradientDirection2["Down"] = 3] = "Down"; return GradientDirection2; })(GradientDirection || {}); var ScaleOrientation = /* @__PURE__ */ ((ScaleOrientation2) => { ScaleOrientation2[ScaleOrientation2["Horizontal"] = 0] = "Horizontal"; ScaleOrientation2[ScaleOrientation2["Vertical"] = 1] = "Vertical"; return ScaleOrientation2; })(ScaleOrientation || {}); function makeDirectionalGradient(direction, bbox, ctx) { let x0 = 0, y0 = 0, x1 = 0, y1 = 0; if (direction === 3 /* Down */) { y0 = bbox.top; y1 = bbox.top + bbox.height; } else if (direction === 2 /* Left */) { x0 = bbox.left + bbox.width; x1 = bbox.left; } else if (direction === 1 /* Up */) { y0 = bbox.top + bbox.height; y1 = bbox.top; } else if (direction === 0 /* Right */) { x0 = bbox.left; x1 = bbox.left + bbox.width; } return ctx.createLinearGradient(x0, y0, x1, y1); } function decomposeColor(color) { if (typeof color !== "string") { return color; } if (color.charAt(0) === "#") { return decomposeColor(hexToRgb(color)); } const marker = color.indexOf("("); const type = color.substring(0, marker); if (["rgb", "rgba", "hsl", "hsla", "color"].indexOf(type) === -1) { throw new Error(`Unsupported '${color}' color. The following formats are supported: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()`); } let values = color.substring(marker + 1, color.length - 1); let colorSpace; if (type === "color") { values = values.split(" "); colorSpace = values.shift(); if (values.length === 4 && values[3].charAt(0) === "/") { values[3] = values[3].slice(1); } if (["srgb", "display-p3", "a98-rgb", "prophoto-rgb", "rec-2020"].indexOf(colorSpace) === -1) { throw new Error(`Unsupported ${colorSpace} color space. The following color spaces are supported: srgb, display-p3, a98-rgb, prophoto-rgb, rec-2020.`); } } else { values = values.split(","); } values = values.map((value) => parseFloat(value)); return { type, values, colorSpace }; } function hexToRgb(color) { color = color.slice(1); const re = new RegExp(`.{1,${color.length >= 6 ? 2 : 1}}`, "g"); let result = color.match(re); if (!result) { return ""; } let colors = Array.from(result); if (colors[0].length === 1) { colors = colors.map((n) => n + n); } return colors ? `rgb${colors.length === 4 ? "a" : ""}(${colors.map((n, index) => { return index < 3 ? parseInt(n, 16) : Math.round(parseInt(n, 16) / 255 * 1e3) / 1e3; }).join(", ")})` : ""; } function clamp(value, min = 0, max = 1) { if (process.env.NODE_ENV !== "production") { if (value < min || value > max) { console.error(`The value provided ${value} is out of range [${min}, ${max}].`); } } return Math.min(Math.max(min, value), max); } var __defProp$e = Object.defineProperty; var __defProps$9 = Object.defineProperties; var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$e = Object.getOwnPropertySymbols; var __hasOwnProp$e = Object.prototype.hasOwnProperty; var __propIsEnum$e = Object.prototype.propertyIsEnumerable; var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$e = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$e.call(b, prop)) __defNormalProp$e(a, prop, b[prop]); if (__getOwnPropSymbols$e) for (var prop of __getOwnPropSymbols$e(b)) { if (__propIsEnum$e.call(b, prop)) __defNormalProp$e(a, prop, b[prop]); } return a; }; var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b)); function getSeriesPathType(type, color, options, stepType) { var _a; const defaultType = uPlot__default["default"].paths.spline(); const defaultOptions = { width: (_a = options.width) != null ? _a : 1.5 }; const stroke = convertRgba(color, 1); return { [ShapeType.Line]: __spreadProps$9(__spreadValues$e({ stroke }, defaultOptions), { paths: stepType ? uPlot__default["default"].paths.stepped({ align: stepType === "start" ? 1 : -1 }) : defaultType }), [ShapeType.Area]: __spreadProps$9(__spreadValues$e({ paths: defaultType }, defaultOptions), { stroke, fill: getOpacityGradientFn(stroke, options.alpha || 0.8) }), [ShapeType.Bar]: __spreadProps$9(__spreadValues$e({}, defaultOptions), { paths: uPlot__default["default"].paths.bars(), fill: color }), [ShapeType.Point]: __spreadProps$9(__spreadValues$e({}, defaultOptions), { stroke, paths: uPlot__default["default"].paths.points() }) }[type] || __spreadProps$9(__spreadValues$e({}, defaultOptions), { paths: defaultType }); } let _context; const cache = /* @__PURE__ */ new Map(); const cacheLimit = 500; let ctxFontStyle = ""; const UPLOT_AXIS_FONT_SIZE = 12; function axesSpace(self, axisIdx, scaleMin) { const axis = self.axes[axisIdx]; const scale = self.scales[axis.scale]; if (axis.side !== 2 || !scale) { return 30; } const defaultSpacing = 40; if (scale.time) { return measureText(String(scaleMin), UPLOT_AXIS_FONT_SIZE).width + 18; } return defaultSpacing; } function getCanvasContext() { if (!_context) { _context = document.createElement("canvas").getContext("2d"); } return _context; } function measureText(text, fontSize = 12) { const fontStyle = `${fontSize}px 'Roboto'`; const cacheKey = text + fontStyle; const fromCache = cache.get(cacheKey); if (fromCache) { return fromCache; } const context = getCanvasContext(); if (ctxFontStyle !== fontStyle) { context.font = ctxFontStyle = fontStyle; } const metrics = context.measureText(text); if (cache.size === cacheLimit) { cache.clear(); } cache.set(cacheKey, metrics); return metrics; } const M_D_H_M = "{MM}-{DD} {HH}:{mm}"; const AXES_X_VALUES = [ [3600 * 365, "{YYYY}", null, null, null, null, null, null, 1], [3600 * 24 * 30, "{YYYY}-{MM}-{DD}", null, null, null, null, null, null, 1], [3600 * 24 * 7, "{MM}-{DD}", null, null, null, null, null, null, 1], [3600 * 24 * 3, M_D_H_M, null, null, null, null, null, null, 1], [3600 * 24, M_D_H_M, null, null, null, null, null, null, 1], [3600 * 12, M_D_H_M, null, null, null, null, null, null, 1], [3600, "{HH}:{mm}", null, null, null, null, null, null, 1], [60, "{HH}:{mm}", null, null, null, null, null, null, 1], [1, "{HH}:{mm}", null, null, null, null, null, null, 1], [1e-3, "{mm}:{ss}", null, null, null, null, null, null, 1] ]; const DEFAULT_FONT = '12px "Roboto", "Helvetica", "Arial", sans-serif'; const UPLOT_DEFAULT_OPTIONS = { padding: [16, 8, 0, 0], legend: { show: false, live: false }, scales: { y: { range: (_u, dataMin, dataMax) => { const maxV = Math.max(dataMax ? dataMax + 5 : dataMax, 1); return [dataMin || 0, maxV]; } } }, axes: [ { space: axesSpace, size: 20, border: { show: true, width: 1 }, font: DEFAULT_FONT, values: AXES_X_VALUES, grid: { show: false }, ticks: { width: 1, size: 5 } }, { font: DEFAULT_FONT, border: { show: true, width: 1 }, grid: { width: 1, dash: [4, 6] }, ticks: { width: 1, size: 5 } } ], cursor: { y: false, points: { show: false }, drag: { x: false, y: false, setScale: false, uni: 10 }, focus: { prox: 30 } } }; class BaseComponent { constructor(ctrl) { this.ctrl = ctrl; } destroy() { if (this.container) { this.container.innerHTML = ""; this.container.remove(); } } } function axisAutoSize(u, values, axisIdx, cycleNum) { const axis = u.axes[axisIdx]; if (cycleNum > 1) return axis._size; let axisSize = axis.ticks.size + axis.gap; const longestVal = (values != null ? values : []).reduce((acc, val) => val.length > acc.length ? val : acc, ""); if (longestVal !== "") { u.ctx.font = axis.font[0]; axisSize += u.ctx.measureText(longestVal).width / devicePixelRatio; } return Math.ceil(axisSize + 2); } function autoPadRight(right = 8) { return (self, _side, _sidesWithAxes, cycleNum) => { const xAxis = self.axes[0]; const xVals = xAxis._values; if (xVals != null) { if (cycleNum > 2) return self._padding[1]; const xSplits = xAxis._splits; const rightSplit = xSplits[xSplits.length - 1]; const rightSplitCoord = self.valToPos(rightSplit, "x"); const leftPlotEdge = self.bbox.left / devicePixelRatio; const rightPlotEdge = leftPlotEdge + self.bbox.width / devicePixelRatio; const rightChartEdge = rightPlotEdge + self._padding[1]; const pxPerChar = right; const rightVal = xVals[xVals.length - 1] + ""; const valHalfWidth = pxPerChar * (rightVal.length / 2); const rightValEdge = leftPlotEdge + rightSplitCoord + valHalfWidth; if (rightValEdge >= rightChartEdge) { return rightValEdge - rightPlotEdge; } } return right; }; } function pointWithin(px, py, rlft, rtop, rrgt, rbtm) { return px >= rlft && px <= rrgt && py >= rtop && py <= rbtm; } const MAX_OBJECTS = 10; const MAX_LEVELS = 4; class Quadtree { constructor(x, y, width, height, left) { this.o = []; this.split = () => { const { x, y, w: _w, h: _h, l: _l } = this; const w = _w / 2; const h = _h / 2; const l = _l + 1; this.q = [ new Quadtree(x + w, y, w, h, l), new Quadtree(x, y, w, h, l), new Quadtree(x, y + h, w, h, l), new Quadtree(x + w, y + h, w, h, l) ]; }; this.x = x; this.y = y; this.w = width; this.h = height; this.l = left || 0; } quads(x, y, w, h, cb) { const q = this.q; const hzMid = this.x + this.w / 2; const vtMid = this.y + this.h / 2; const startIsNorth = y < vtMid; const startIsWest = x < hzMid; const endIsEast = x + w > hzMid; const endIsSouth = y + h > vtMid; startIsNorth && endIsEast && cb(q[0]); startIsWest && startIsNorth && cb(q[1]); startIsWest && endIsSouth && cb(q[2]); endIsEast && endIsSouth && cb(q[3]); } add(o) { if (this.q != null) { this.quads(o.x, o.y, o.w, o.h, (q) => { q.add(o); }); } else { const os = this.o; os.push(o); if (os.length > MAX_OBJECTS && this.l < MAX_LEVELS) { this.split(); for (const oi of os) { this.quads(oi.x, oi.y, oi.w, oi.h, (q) => { q.add(oi); }); } this.o.length = 0; } } } getQ(x, y, w, h, cb) { const os = this.o; for (const o of os) cb(o); if (this.q != null) { this.quads(x, y, w, h, (q) => { q.getQ(x, y, w, h, cb); }); } } clear() { this.o.length = 0; this.q = null; } } var __defProp$d = Object.defineProperty; var __defProps$8 = Object.defineProperties; var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$d = Object.getOwnPropertySymbols; var __hasOwnProp$d = Object.prototype.hasOwnProperty; var __propIsEnum$d = Object.prototype.propertyIsEnumerable; var __pow$2 = Math.pow; var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$d = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$d.call(b, prop)) __defNormalProp$d(a, prop, b[prop]); if (__getOwnPropSymbols$d) for (var prop of __getOwnPropSymbols$d(b)) { if (__propIsEnum$d.call(b, prop)) __defNormalProp$d(a, prop, b[prop]); } return a; }; var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b)); const SPACE_BETWEEN = 1; const SPACE_AROUND = 2; const SPACE_EVENLY = 3; function roundDec(val, dec) { return Math.round(val * (dec = __pow$2(10, dec))) / dec; } const coord = (i, offs, iwid, gap) => roundDec(offs + i * (iwid + gap), 6); function distr(numItems, sizeFactor, justify, onlyIdx, each) { const space = 1 - sizeFactor; let gap = justify === SPACE_BETWEEN ? space / (numItems - 1) : justify === SPACE_AROUND ? space / numItems : justify === SPACE_EVENLY ? space / (numItems + 1) : 0; if (isNaN(gap) || gap === Infinity) gap = 0; const offs = justify === SPACE_BETWEEN ? 0 : justify === SPACE_AROUND ? gap / 2 : justify === SPACE_EVENLY ? gap : 0; const iwid = sizeFactor / numItems; const _iwid = roundDec(iwid, 6); if (onlyIdx == null) { for (let i = 0; i < numItems; i++) each(i, coord(i, offs, iwid, gap), _iwid); } else each(onlyIdx, coord(onlyIdx, offs, iwid, gap), _iwid); } function seriesBarsPlugin(opts) { let pxRatio; const { time, ignore = [], radius: _radius, ori: _ori, dir: _dir, stacked: _stacked, marginRatio, disp } = opts; const radius = _radius != null ? _radius : 0; const ori = _ori; const dir = _dir; const stacked = _stacked; const groupWidth = 0.9; const groupDistr = SPACE_BETWEEN; const barWidth = 1 - (marginRatio || 0); const barDistr = SPACE_BETWEEN; function distrTwo(groupCount, barCount, _groupWidth = groupWidth) { const out = Array.from({ length: barCount }, () => ({ offs: Array.from({ length: groupCount }).fill(0), size: Array.from({ length: groupCount }).fill(0) })); distr(groupCount, _groupWidth, groupDistr, null, (groupIdx, groupOffPct, groupDimPct) => { distr(barCount, barWidth, barDistr, null, (barIdx, barOffPct, barDimPct) => { out[barIdx].offs[groupIdx] = groupOffPct + groupDimPct * barOffPct; out[barIdx].size[groupIdx] = groupDimPct * barDimPct; }); }); return out; } function distrOne(groupCount, barCount) { const out = Array.from({ length: barCount }, () => ({ offs: Array.from({ length: groupCount }).fill(0), size: Array.from({ length: groupCount }).fill(0) })); distr(groupCount, groupWidth, groupDistr, null, (groupIdx, groupOffPct, groupDimPct) => { distr(barCount, barWidth, barDistr, null, (barIdx, _barOffPct, _barDimPct) => { out[barIdx].offs[groupIdx] = groupOffPct; out[barIdx].size[groupIdx] = groupDimPct; }); }); return out; } let barsPctLayout; let barsColors; let qt; const barsBuilder = uPlot__default["default"].paths.bars({ radius, disp: __spreadValues$d({ x0: { unit: 2, values: (_u, seriesIdx, _idx0, _idx1) => barsPctLayout[seriesIdx].offs }, size: { unit: 2, values: (_u, seriesIdx, _idx0, _idx1) => barsPctLayout[seriesIdx].size } }, disp), each: (u, seriesIdx, dataIdx, lft, top, wid, hgt) => { lft -= u.bbox.left; top -= u.bbox.top; qt.add({ x: lft, y: top, w: wid, h: hgt, sidx: seriesIdx, didx: dataIdx }); } }); function range(_u, _dataMin, dataMax) { const [min, max] = uPlot__default["default"].rangeNum(0, dataMax, 0.05, true); return [min || 0, max]; } return { hooks: { drawClear: (u) => { qt = qt || new Quadtree(0, 0, u.bbox.width, u.bbox.height); qt.clear(); u.series.forEach((s) => { s._paths = null; }); if (stacked) barsPctLayout = [null].concat(distrOne(u.data.length - 1 - ignore.length, u.data[0].length)); else if (u.series.length === 2) barsPctLayout = [null].concat(distrOne(u.data[0].length, 1)); else barsPctLayout = [null].concat(distrTwo(u.data[0].length, u.data.length - 1 - ignore.length, u.data[0].length === 1 ? 1 : groupWidth)); const { disp: disp2 } = opts; if ((disp2 == null ? void 0 : disp2.fill) != null) { barsColors = [null]; for (let i = 1; i < u.data.length; i++) { barsColors.push({ fill: disp2.fill.values(u, i), stroke: disp2.stroke.values(u, i) }); } } } }, opts: (_u, opts2) => { const { axes, series } = opts2; const yScaleOpts = { range, ori: ori === 0 ? 1 : 0 }; let hRect; uPlot__default["default"].assign(opts2, { select: { show: false }, cursor: { x: false, y: false, dataIdx: (u, seriesIdx) => { if (seriesIdx === 1) { hRect = null; const cx = u.cursor.left * pxRatio; const cy = u.cursor.top * pxRatio; qt.getQ(cx, cy, 1, 1, (o) => { if (pointWithin(cx, cy, o.x, o.y, o.x + o.w, o.y + o.h)) hRect = o; }); } return hRect && seriesIdx === hRect.sidx ? hRect.didx : null; }, points: { show: false } }, scales: { x: { distr: 2, ori, dir, range: (u) => { let min = 0; let max = Math.max(1, u.data[0].length - 1); let pctOffset = 0; distr(u.data[0].length, groupWidth, groupDistr, 0, (_di, lftPct, widPct) => { pctOffset = lftPct + widPct / 2; }); const rn = max - min; if (pctOffset === 0.5) min -= rn; else { const upScale = 1 / (1 - pctOffset * 2); const offset = (upScale * rn - rn) / 2; min -= offset; max += offset; } return [min, max]; } }, rend: yScaleOpts, size: yScaleOpts, mem: yScaleOpts, inter: yScaleOpts, toggle: yScaleOpts } }); if (ori === 1) { opts2.padding = [0, null, 0, null]; } const { xSplits } = getBarConfig({ dir, ori, xSpacing: dir === 1 ? 100 : -100 }); const values = time === false ? { values: (u) => u.data[0] } : {}; uPlot__default["default"].assign(axes[0], __spreadProps$8(__spreadValues$d({ splits: xSplits }, values), { gap: 15, size: ori === 0 ? 40 : 150, labelSize: 20, grid: { show: false }, ticks: { show: false }, side: ori === 0 ? 2 : 3 })); series.forEach((s, i) => { if (i > 0 && !ignore.includes(i)) { uPlot__default["default"].assign(s, { paths: barsBuilder, points: { show: false } }); } }); } }; } function getBarConfig(opts) { const { ori = 0, dir = 1, xSpacing = 0 } = opts; const isXHorizontal = ori === 0; const xSplits = (u) => { const dim = isXHorizontal ? u.bbox.width : u.bbox.height; const _dir = dir * (isXHorizontal ? 1 : -1); const dataLen = u.data[0].length; const lastIdx = dataLen - 1; let skipMod = 0; if (xSpacing !== 0) { const cssDim = dim / devicePixelRatio; const maxTicks = Math.abs(Math.floor(cssDim / (isXHorizontal ? xSpacing : xSpacing / 3))); skipMod = dataLen < maxTicks ? 0 : Math.ceil(dataLen / maxTicks); } const splits = []; u.data[0].forEach((_v, i) => { const shouldSkip = skipMod !== 0 && (xSpacing > 0 ? i : lastIdx - i) % skipMod > 0; if (!shouldSkip) { splits.push(i); } }); return _dir === 1 ? splits : splits.reverse(); }; return { xSplits }; } function stack(data, omit = () => false) { const data2 = []; let bands = []; const d0Len = data[0].length; const accuse = Array.from({ length: d0Len }); for (let i = 0; i < d0Len; i++) accuse[i] = 0; for (let i = 1; i < data.length; i++) data2.push(omit(i) ? data[i] : data[i].map((v, i2) => accuse[i2] += +v)); for (let i = 1; i < data.length; i++) !omit(i) && bands.push({ series: [data.findIndex((_s, j) => j > i && !omit(j)), i] }); bands = bands.filter((b) => b.series[1] > -1); return { data: [data[0]].concat(data2), bands }; } var __defProp$c = Object.defineProperty; var __getOwnPropSymbols$c = Object.getOwnPropertySymbols; var __hasOwnProp$c = Object.prototype.hasOwnProperty; var __propIsEnum$c = Object.prototype.propertyIsEnumerable; var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$c = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$c.call(b, prop)) __defNormalProp$c(a, prop, b[prop]); if (__getOwnPropSymbols$c) for (var prop of __getOwnPropSymbols$c(b)) { if (__propIsEnum$c.call(b, prop)) __defNormalProp$c(a, prop, b[prop]); } return a; }; class Axis extends BaseComponent { constructor() { super(...arguments); this.name = "axis"; } render() { const opt = this.ctrl.getOption(); this.option = lodashEs.get(opt, this.name, { x: {}, y: {} }); } update() { } getOptions() { return { axes: [this.getXOptions(), this.getYOptions()] }; } getXOptions() { const { formatter: xFormatter, show } = this.option.x || {}; const xValues = xFormatter ? (_u, splits) => splits.map((d) => { return lodashEs.isFunction(xFormatter) ? xFormatter(String(d)) : template(xFormatter, { value: d }); }) : AXES_X_VALUES; return { show: show !== false, values: xValues }; } getYOptions() { const { autoSize, formatter: yFormatter, show } = this.option.y || {}; const yValues = yFormatter ? (u, splits, axisIdx, tickSpace, tickIncr) => { const params = { u, splits, axisIdx, tickSpace, tickIncr }; return splits.map((d) => { return lodashEs.isFunction(yFormatter) ? yFormatter(String(d), params) : template(yFormatter, { value: d }); }); } : null; const ySize = autoSize === false ? {} : { size: axisAutoSize }; return __spreadValues$c({ show: show !== false, values: yValues }, ySize); } } var ChartEvent = /* @__PURE__ */ ((ChartEvent2) => { ChartEvent2["THEME_CHANGE"] = "theme:change"; ChartEvent2["HOOKS_REDRAW"] = "hooks:redraw"; ChartEvent2["U_PLOT_READY"] = "uPlot:ready"; ChartEvent2["U_PLOT_SET_CURSOR"] = "uPlot:setCursor"; ChartEvent2["PLOT_MOUSEMOVE"] = "plot:mousemove"; ChartEvent2["PLOT_MOUSELEAVE"] = "plot:mouseleave"; ChartEvent2["PLOT_CLICK"] = "plot:click"; ChartEvent2["PLOT_MOUSEDOWN"] = "plot:mousedown"; ChartEvent2["PLOT_MOUSEUP"] = "plot:mouseup"; ChartEvent2["ELEMENT_MOUSEMOVE"] = "element:mousemove"; ChartEvent2["ELEMENT_MOUSELEAVE"] = "element:mouseleave"; ChartEvent2["LEGEND_ITEM_CLICK"] = "legend-item:click"; ChartEvent2["LEGEND_ITEM_HOVER"] = "legend-item:hover"; ChartEvent2["SHAPE_CHANGE"] = "shape:change"; ChartEvent2["DATA_CHANGE"] = "data:change"; return ChartEvent2; })(ChartEvent || {}); var DIRECTION = /* @__PURE__ */ ((DIRECTION2) => { DIRECTION2["TOP"] = "top"; DIRECTION2["TOP_LEFT"] = "top-left"; DIRECTION2["TOP_RIGHT"] = "top-right"; DIRECTION2["BOTTOM"] = "bottom"; DIRECTION2["BOTTOM_LEFT"] = "bottom-left"; DIRECTION2["BOTTOM_RIGHT"] = "bottom-right"; DIRECTION2["NONE"] = "none"; return DIRECTION2; })(DIRECTION || {}); var ActionType = /* @__PURE__ */ ((ActionType2) => { ActionType2["TOOLTIP_SHOW"] = "tooltip:show"; ActionType2["TOOLTIP_HIDE"] = "tooltip:hide"; ActionType2["ELEMENT_ACTIVE"] = "element-active:active"; ActionType2["ELEMENT_RESET"] = "element-active:reset"; ActionType2["LEGEND_TOGGLE"] = "legend:toggle"; ActionType2["BRUSH_X_START"] = "brush-x:start"; ActionType2["BRUSH_X_END"] = "brush-x:end"; return ActionType2; })(ActionType || {}); const styles$4 = noImportant_js.StyleSheet.create({ top: { alignItems: "center", flexDirection: "column" }, "top-left": { alignItems: "flex-start", flexDirection: "column" }, "top-right": { flexDirection: "row" } }); class Header { get name() { return "header"; } constructor(ctrl, position = DIRECTION.TOP_RIGHT) { this.ctrl = ctrl; this.position = position; this.render(); } render() { this.create(); } create() { const headerName = generateName("header"); const header = this.ctrl.chartContainer.querySelector(`.${headerName}`); if (!this.container) { this.container = header || document.createElement("div"); if (header) { header.style.wordBreak = "break-all;"; } this.container.style.display = "flex"; this.container.style.justifyContent = "flex-end"; if (!header) { this.ctrl.chartContainer.append(this.container); } } this.container.className = `${generateName("header")} ${noImportant_js.css(styles$4[this.position])}`; } destroy() { this.sizeObserver.disconnect(); } } const symbolStyle = noImportant_js.StyleSheet.create({ symbol: { display: "inline-block", marginRight: 4 }, line: { width: 12, height: 2 }, square: { width: 12, height: 12 }, circle: { width: 12, height: 12, borderRadius: "50%" } }); const styles$3 = noImportant_js.StyleSheet.create({ ul: { listStyle: "none", padding: 0, margin: 0, display: "flex", flexWrap: "wrap" }, item: { padding: 0, display: "flex", alignItems: "center", cursor: "pointer", ":not(:last-child)": { marginRight: 12 } }, name: { display: "block", whiteSpace: "nowrap" }, legend: { display: "flex", marginTop: 8 }, bottom: { justifyContent: "center" }, "bottom-left": { justifyContent: "flex-start" }, "bottom-right": { justifyContent: "flex-end" } }); class Legend extends BaseComponent { constructor() { super(...arguments); this.inactivatedSet = /* @__PURE__ */ new Set(); } get name() { return "legend"; } render() { const opt = this.ctrl.getOption(); this.option = lodashEs.get(opt, this.name, {}); if (!this.container) { this.create(); } else { this.update(); } } update() { this.option = lodashEs.get(this.ctrl.getOption(), this.name); this.createItem(); } create() { if (lodashEs.isObject(this.option) || this.option === true) { const { position } = lodashEs.isBoolean(this.option) ? { position: DIRECTION.TOP_RIGHT } : this.option; let dom = this.ctrl.container; this.container = document.createElement("div"); this.container.className = generateName("legend"); if ((position == null ? void 0 : position.includes("top")) || !position) { const header = new Header(this.ctrl, (position == null ? void 0 : position.includes("top")) ? position : DIRECTION.TOP_RIGHT); dom = header.container; dom.append(this.container); this.createItem(); } else { this.ctrl.on(ChartEvent.U_PLOT_READY, () => { dom.append(this.container); this.container.className = `${generateName("legend")} ${noImportant_js.css(styles$3.legend)} ${noImportant_js.css(styles$3[position])}`; this.createItem(); }); } } } createItem() { if ((lodashEs.isObject(this.option) || this.option === true) && !lodashEs.get(this.option, "custom")) { this.container.innerHTML = ""; const ul = document.createElement("ul"); ul.className = noImportant_js.css(styles$3.ul); const data = this.getLegend(); for (const key of data.entries()) { const li = document.createElement("li"); const value = key[1]; li.className = noImportant_js.css(styles$3.item); li.innerHTML = ` <span class="${noImportant_js.css(symbolStyle.symbol)} ${noImportant_js.css(symbolStyle.line)}" style="background: ${value.color};"></span> <span class="${noImportant_js.css(styles$3.name)}">${value.name}</span>`; ul.append(li); li.addEventListener("click", () => { const activated = li.style.opacity === "1" || !li.style.opacity; li.style.opacity = activated ? "0.5" : "1"; value.activated = !activated; this.legendItemClick({ name: value.name, activated: !activated }); }); } this.container.append(ul); } } legendItemClick(props) { if (props.activated) { this.inactivatedSet.delete(props.name); } else { this.inactivatedSet.add(props.name); } this.ctrl.emit(ChartEvent.LEGEND_ITEM_CLICK, props); } getLegend() { const data = this.ctrl.getData(); return data.map(({ name, color }) => ({ name, color, activated: !this.inactivatedSet.has(name) })).filter((d) => d.name); } } const styles$2 = noImportant_js.StyleSheet.create({ title: { wordBreak: "break-all", width: "100%" } }); class Title extends BaseComponent { get name() { return "title"; } render() { const opt = this.ctrl.getOption(); this.option = lodashEs.get(opt, this.name); if (!this.headerContainer) { this.createTitle(); } else { this.update(); } } createTitle() { if (typeof this.option === "object") { this.container = document.createElement("div"); this.container.style.wordBreak = "break-all"; this.container.style.flex = "1"; this.container.className = `${generateName("title")} ${noImportant_js.css(styles$2.title)}`; this.update(); const header = new Header(this.ctrl); header.container.append(this.container); this.headerContainer = header.container; } } update() { this.option = lodashEs.get(this.ctrl.getOption(), this.name); if (this.container && !lodashEs.get(this.option, "custom")) { this.container.innerHTML = this.getTitleValue(); } } getTitleValue() { if (typeof this.option === "object") { const { text, formatter } = this.option; return (typeof formatter === "function" ? formatter(text) : template(formatter, { text })) || text; } return ""; } } const styles$1 = noImportant_js.StyleSheet.create({ overlay: { position: "absolute", visibility: "hidden", pointerEvents: "none", padding: "12px", boxShadow: "0 2px 8px #00000029", margin: 8, zIndex: 999, transition: "transform 0.1s ease-out 0s", fontSize: 12 }, "tooltip-title": { marginBottom: 8 }, "tooltip-list": { listStyle: "none", padding: 0, margin: 0 }, "tooltip-list-item": { listStyleType: "none", padding: "2px 8px", display: "flex", alignItems: "center" }, "tooltip-marker": { marginRight: 4 }, "tooltip-name": { maxWidth: "197px", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, "tooltip-value": { marginLeft: 30, flex: 1, textAlign: "right", whiteSpace: "nowrap" } }); class Tooltip extends BaseComponent { constructor() { super(...arguments); this.showTooltip = () => { this.container.style.visibility = "visible"; this.container.style.background = this.ctrl.getTheme().tooltip.background; this.container.style.color = this.ctrl.getTheme().tooltip.color; }; this.hideTooltip = () => { if (this.container) { this.container.style.visibility = "hidden"; } }; } get name() { return "tooltip"; } render() { const opt = this.ctrl.getOption(); this.option = lodashEs.get(opt, this.name, {}); this.create(); } update() { this.option = lodashEs.get(this.ctrl.getOption(), this.name); this.createItem(); } create() { if (this.option) { if (!this.container) { const overlay = document.createElement("div"); overlay.className = `${generateName("tooltip")} ${noImportant_js.css(styles$1.overlay)}`; (lodashEs.get(this.option, "popupContainer") || document.body).append(overlay); overlay.style.visibility = "hidden"; this.container = overlay; } this.createItem(); this.eventListener(); } } createItem(title, values) { const itemTpl = this.getTooltipItem(values); if (!itemTpl) { return; } const isEl = lodashEs.isElement(itemTpl); const list = `<ul class="${noImportant_js.css(styles$1["tooltip-list"])}">${itemTpl}</ul>`; this.container.innerHTML = ` ${this.getTooltipTitle(title, values)} ${isEl ? "" : list} `; if (isEl) { this.container.remove(); this.container.append(itemTpl); } } getTooltipTitle(title, values) { const { showTitle, titleFormatter } = this.option; if (String(showTitle) === "false" || !title) { return ""; } let tpl = title || NOT_AVAILABLE; if (lodashEs.isString(titleFormatter)) { tpl = template(titleFormatter, { title }); } if (lodashEs.isFunction(titleFormatter)) { tpl = titleFormatter(title, values); } return `<div class="${noImportant_js.css(styles$1["tooltip-title"])}">${tpl}</div>`; } getTooltipItem(values) { if (!values || !(values == null ? void 0 : values.length)) { return ""; } const { nameFormatter, valueFormatter, itemFormatter, sort } = this.option; let items = sort ? values.sort(sort) : values; if (itemFormatter) { const itemValue = itemFormatter(items); if (lodashEs.isString(itemValue)) { return itemValue; } if (lodashEs.isElement(itemValue)) { return itemValue.innerHTML; } if (lodashEs.isArray(itemValue)) { items = itemValue; } } return items == null ? void 0 : items.map((item) => { const value = this.handleTemplateString(item.value, valueFormatter, item); const name = this.handleTemplateString(String(item.name), nameFormatter, item); return `<li class="${noImportant_js.css(styles$1["tooltip-list-item"])}" style="background: ${item.activated ? this.ctrl.getTheme().tooltip.activeBg : "unset"}"> <span class="${noImportant_js.css(symbolStyle.symbol)} ${noImportant_js.css(symbolStyle.line)}" style="background: ${item.color};"></span> <span class="${generateName("tooltip-name")} ${noImportant_js.css(styles$1["tooltip-name"])}">${name || NOT_AVAILABLE}</span> <span class="${generateName("tooltip-value")} ${noImportant_js.css(styles$1["tooltip-value"])}">${lodashEs.isNil(value) ? NOT_AVAILABLE : value}</span> </li>`; }).join(""); } handleTemplateString(text, formatter, data) { let value = text; if (lodashEs.isString(formatter)) { value = template(formatter, { value: text }); } if (lodashEs.isFunction(formatter)) { value = formatter(value, data); } return value; } eventListener() { this.ctrl.on(ChartEvent.U_PLOT_SET_CURSOR, ({ anchor, title, values, position }) => { if (values == null ? void 0 : values.length) { placement__default["default"](anchor, this.container, { placement: position || "right" }); this.createItem(title, values); } }); } } const LOADED_COMPONENTS = /* @__PURE__ */ new Map(); function registerComponent(name, plugin) { LOADED_COMPONENTS.set(name, plugin); } function unregisterComponent(name) { LOADED_COMPONENTS.delete(name); } function getComponentNames() { return [...LOADED_COMPONENTS.keys()]; } function getComponent(name) { return LOADED_COMPONENTS.get(name); } class ViewStrategy { constructor(view) { this.components = []; this.usedComponent = getComponentNames(); this.ctrl = view; this.initComponent(); this.init(); } get options() { return this.ctrl.getOption(); } initComponent() { for (const name of this.component) { const Component = getComponent(name); if (Component) { this.components.push(new Component(this.ctrl)); } } } destroy() { this.components = []; } } class InternalViewStrategy extends ViewStrategy { get name() { return "internal"; } get component() { return ["title", "legend", "pie", "gauge"]; } init() { } render() { this.component.forEach((c) => { const comp = this.ctrl.shapeComponents.get(c); comp == null ? void 0 : comp.render(); }); } } class ViewStrategyManager { constructor() { this.strategy = /* @__PURE__ */ new Map(); } add(strategy) { this.strategy.set(strategy.name, strategy); } getStrategy(name) { return this.strategy.get(name); } getAllStrategy() { return [...this.strategy.values()]; } getComponent() { const all = this.getAllStrategy(); return all.flatMap((ctrl) => ctrl.components); } } var __defProp$b = Object.defineProperty; var __defProps$7 = Object.defineProperties; var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$b = Object.getOwnPropertySymbols; var __hasOwnProp$b = Object.prototype.hasOwnProperty; var __propIsEnum$b = Object.prot