UNPKG

ag-charts-core

Version:

Advanced Charting / Charts supporting Javascript / Typescript / React / Angular / Vue

1,607 lines (1,578 loc) 329 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; // packages/ag-charts-core/src/modules/moduleDefinition.ts var ModuleType = /* @__PURE__ */ /*#__PURE__*/ ((ModuleType2) => { ModuleType2["Chart"] = "chart"; ModuleType2["Axis"] = "axis"; ModuleType2["Series"] = "series"; ModuleType2["Plugin"] = "plugin"; ModuleType2["AxisPlugin"] = "axis:plugin"; ModuleType2["SeriesPlugin"] = "series:plugin"; ModuleType2["Preset"] = "preset"; return ModuleType2; })(ModuleType || {}); // packages/ag-charts-core/src/types/scales.ts function extractDomain(value) { return value.domain; } var ScaleAlignment = /* @__PURE__ */ /*#__PURE__*/ ((ScaleAlignment2) => { ScaleAlignment2[ScaleAlignment2["Leading"] = 0] = "Leading"; ScaleAlignment2[ScaleAlignment2["Trailing"] = 1] = "Trailing"; ScaleAlignment2[ScaleAlignment2["Interpolate"] = 2] = "Interpolate"; return ScaleAlignment2; })(ScaleAlignment || {}); // packages/ag-charts-core/src/structures/eventEmitter.ts var EventEmitter = class { constructor() { this.events = /* @__PURE__ */ new Map(); } /** * Registers an event listener. * @param eventName The event name to listen for. * @param listener The callback to be invoked on the event. * @returns A function to unregister the listener. */ on(eventName, listener) { if (!this.events.has(eventName)) { this.events.set(eventName, /* @__PURE__ */ new Set()); } this.events.get(eventName)?.add(listener); return () => this.off(eventName, listener); } /** * Unregisters an event listener. * @param eventName The event name to stop listening for. * @param listener The callback to be removed. */ off(eventName, listener) { const eventListeners = this.events.get(eventName); if (eventListeners) { eventListeners.delete(listener); if (eventListeners.size === 0) { this.events.delete(eventName); } } } /** * Emits an event to all registered listeners. * @param eventName The name of the event to emit. * @param event The event payload. */ emit(eventName, event) { const listeners = this.events.get(eventName); if (listeners) { for (const callback2 of listeners) { callback2(event); } } } /** * Clears all listeners for a specific event or all events if no event name is provided. * @param eventName (Optional) The name of the event to clear listeners for. If not provided, all listeners for all events are cleared. */ clear(eventName) { if (eventName) { this.events.delete(eventName); } else { this.events.clear(); } } }; // packages/ag-charts-core/src/structures/lruCache.ts var LRUCache = class { constructor(maxCacheSize) { this.maxCacheSize = maxCacheSize; this.store = /* @__PURE__ */ new Map(); if (maxCacheSize <= 0) { throw new Error("LRUCache size must be greater than 0"); } } get(key) { if (!this.store.has(key)) return; const value = this.store.get(key); this.store.delete(key); this.store.set(key, value); return value; } has(key) { return this.store.has(key); } set(key, value) { this.store.set(key, value); if (this.store.size > this.maxCacheSize) { this.store.delete(this.store.keys().next().value); } return value; } clear() { this.store.clear(); } }; // packages/ag-charts-core/src/logging/debugLogger.ts var debugLogger_exports = {}; __export(debugLogger_exports, { Time: () => Time, check: () => check, create: () => create, inDevelopmentMode: () => inDevelopmentMode }); // packages/ag-charts-core/src/utils/data/arrays.ts function toArray(value) { if (value === void 0) { return []; } return Array.isArray(value) ? value : [value]; } function unique(array2) { return Array.from(new Set(array2)); } function groupBy(array2, iteratee) { return array2.reduce((result, item) => { const groupKey = iteratee(item); result[groupKey] ?? (result[groupKey] = []); result[groupKey].push(item); return result; }, {}); } function arraysEqual(a, b) { if (a == null || b == null || a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (Array.isArray(a[i]) && Array.isArray(b[i])) { if (!arraysEqual(a[i], b[i])) { return false; } } else if (a[i] !== b[i]) { return false; } } return true; } function circularSliceArray(data, size, offset = 0) { if (data.length === 0) { return []; } const result = []; for (let i = 0; i < size; i++) { result.push(data.at((i + offset) % data.length)); } return result; } function sortBasedOnArray(baseArray, orderArray) { const orderMap = /* @__PURE__ */ new Map(); for (const [index, item] of orderArray.entries()) { orderMap.set(item, index); } return baseArray.sort((a, b) => { const indexA = orderMap.get(a) ?? Infinity; const indexB = orderMap.get(b) ?? Infinity; return indexA - indexB; }); } function dropFirstWhile(array2, cond) { let i = 0; while (i < array2.length && cond(array2[i])) { i += 1; } const deleteCount = i; if (deleteCount !== 0) array2.splice(0, deleteCount); } function dropLastWhile(array2, cond) { let i = array2.length - 1; while (i >= 0 && cond(array2[i])) { i -= 1; } const deleteCount = array2.length - 1 - i; if (deleteCount !== 0) array2.splice(array2.length - deleteCount, deleteCount); } function distribute(min, max, maxCount) { const values = [min]; const step = Math.round((max - min) / (maxCount - 1)); if (step > 0) { for (let i = min + step; i < max; i += step) { const length2 = values.push(i); if (length2 >= maxCount - 1) break; } } values.push(max); return values; } // packages/ag-charts-core/src/utils/dom/globalsProxy.ts var verifiedGlobals = {}; if (typeof globalThis.window !== "undefined") { verifiedGlobals.window = globalThis.window; } if (typeof document !== "undefined") { verifiedGlobals.document = document; } else if (typeof globalThis.global !== "undefined") { verifiedGlobals.document = globalThis.document; } function getDocument(propertyName) { return propertyName ? verifiedGlobals.document?.[propertyName] : verifiedGlobals.document; } function getWindow(propertyName) { return propertyName ? verifiedGlobals.window?.[propertyName] : verifiedGlobals.window; } function setDocument(document2) { verifiedGlobals.document = document2; } function setWindow(window) { verifiedGlobals.window = window; } function getOffscreenCanvas() { return verifiedGlobals.window?.OffscreenCanvas ?? globalThis.OffscreenCanvas; } function getPath2D() { return verifiedGlobals.window?.Path2D ?? globalThis.Path2D; } function getDOMMatrix() { return verifiedGlobals.window?.DOMMatrix ?? globalThis.DOMMatrix; } function getImage() { return verifiedGlobals.window?.Image ?? globalThis.Image; } function getResizeObserver() { return verifiedGlobals.window?.ResizeObserver ?? globalThis.ResizeObserver; } var ELEMENT_NODE = 1; var DOCUMENT_FRAGMENT_NODE = 11; function isNode(obj) { return obj != null && typeof obj.nodeType === "number"; } function isElement(obj) { return obj != null && obj.nodeType === ELEMENT_NODE; } function isDocumentFragment(obj) { return obj != null && obj.nodeType === DOCUMENT_FRAGMENT_NODE; } function isHTMLElement(obj) { return obj != null && obj.nodeType === ELEMENT_NODE && "style" in obj; } // packages/ag-charts-core/src/logging/logger.ts var logger_exports = {}; __export(logger_exports, { error: () => error, errorOnce: () => errorOnce, log: () => log, logGroup: () => logGroup, reset: () => reset, table: () => table, warn: () => warn, warnOnce: () => warnOnce }); var doOnceCache = /* @__PURE__ */ /*#__PURE__*/ new Set(); function log(...logContent) { console.log(...logContent); } function warn(message, ...logContent) { console.warn(`AG Charts - ${message}`, ...logContent); } function error(message, ...logContent) { if (typeof message === "object") { console.error(`AG Charts error`, message, ...logContent); } else { console.error(`AG Charts - ${message}`, ...logContent); } } function table(...logContent) { console.table(...logContent); } function guardOnce(messageOrError, prefix, cb) { let message; if (messageOrError instanceof Error) { message = messageOrError.message; } else if (typeof messageOrError === "string") { message = messageOrError; } else if (typeof messageOrError === "object") { message = JSON.stringify(messageOrError); } else { message = String(messageOrError); } const cacheKey = `${prefix}: ${message}`; if (doOnceCache.has(cacheKey)) return; cb(messageOrError); doOnceCache.add(cacheKey); } function warnOnce(messageOrError, ...logContent) { guardOnce(messageOrError, "Logger.warn", (message) => warn(message, ...logContent)); } function errorOnce(messageOrError, ...logContent) { guardOnce(messageOrError, "Logger.error", (message) => error(message, ...logContent)); } function reset() { doOnceCache.clear(); } function isPromise(value) { return typeof value === "object" && value !== null && "then" in value; } function logGroup(name, cb) { console.groupCollapsed(name); let syncCleanup = true; try { const result = cb(); if (isPromise(result)) { syncCleanup = false; return result.finally(() => { console.groupEnd(); }); } return result; } finally { if (syncCleanup) { console.groupEnd(); } } } // packages/ag-charts-core/src/logging/debugLogger.ts var LongTimePeriodThreshold = 2e3; var timeOfLastLog = /*#__PURE__*/ Date.now(); function logTimeGap() { const timeSinceLastLog = Date.now() - timeOfLastLog; if (timeSinceLastLog > LongTimePeriodThreshold) { const prettyDuration = (Math.floor(timeSinceLastLog / 100) / 10).toFixed(1); log(`**** ${prettyDuration}s since last log message ****`); } timeOfLastLog = Date.now(); } function create(...debugSelectors) { const resultFn = (...logContent) => { if (check(...debugSelectors)) { if (typeof logContent[0] === "function") { logContent = toArray(logContent[0]()); } logTimeGap(); log(...logContent); } }; return Object.assign(resultFn, { check: () => check(...debugSelectors), group: (name, cb) => { if (check(...debugSelectors)) { return logGroup(name, cb); } return cb(); } }); } function check(...debugSelectors) { if (debugSelectors.length === 0) { debugSelectors.push(true); } const chartDebug = toArray(getWindow("agChartsDebug")); return chartDebug.some((selector) => debugSelectors.includes(selector)); } function inDevelopmentMode(fn) { if (check("dev")) { return fn(); } } function Time(name, opts = {}) { const { logResult = true, logStack = false, logArgs = false, logData } = opts; return function(_target, _propertyKey, descriptor) { const method = descriptor.value; descriptor.value = function(...args) { const start2 = performance.now(); const result = method.apply(this, args); const duration = performance.now() - start2; const logMessage = { duration }; if (logResult) logMessage.result = result; if (logArgs) logMessage.args = args; if (logStack) logMessage.stack = new Error("Stack trace for timing debug").stack; if (logData) logMessage.logData = logData(this); log(name, logMessage); return result; }; }; } // packages/ag-charts-core/src/logging/debugMetrics.ts var debugMetrics_exports = {}; __export(debugMetrics_exports, { flush: () => flush, record: () => record }); var metrics = /* @__PURE__ */ /*#__PURE__*/ new Map(); function record(key, value) { if (!check("scene:stats:verbose")) return; metrics.set(key, value); } function flush() { const result = Object.fromEntries(metrics); metrics.clear(); return result; } // packages/ag-charts-core/src/modules/enterpriseRegistry.ts var enterpriseRegistry = {}; // packages/ag-charts-core/src/modules/moduleRegistry.ts var moduleRegistry_exports = {}; __export(moduleRegistry_exports, { RegistryMode: () => RegistryMode, getAxisModule: () => getAxisModule, getChartModule: () => getChartModule, getPresetModule: () => getPresetModule, getSeriesModule: () => getSeriesModule, hasModule: () => hasModule, ifRegistryChanged: () => ifRegistryChanged, isEnterprise: () => isEnterprise, isIntegrated: () => isIntegrated, isModuleType: () => isModuleType, isUmd: () => isUmd, listModules: () => listModules, listModulesByType: () => listModulesByType, register: () => register, registerModules: () => registerModules, reset: () => reset2, setRegistryMode: () => setRegistryMode }); // packages/ag-charts-core/src/modules/registryMode.ts var RegistryMode = /* @__PURE__ */ /*#__PURE__*/ ((RegistryMode2) => { RegistryMode2["Enterprise"] = "enterprise"; RegistryMode2["Integrated"] = "integrated"; RegistryMode2["UMD"] = "umd"; return RegistryMode2; })(RegistryMode || {}); var registeredModes = /* @__PURE__ */ /*#__PURE__*/ new Set(); function setRegistryMode(registryFlag) { registeredModes.add(registryFlag); } function clearRegistryModes() { registeredModes.clear(); } function isEnterprise() { return registeredModes.has("enterprise" /* Enterprise */); } function isIntegrated() { return registeredModes.has("integrated" /* Integrated */); } function isUmd() { return registeredModes.has("umd" /* UMD */); } // packages/ag-charts-core/src/modules/moduleRegistry.ts var registeredModules = /* @__PURE__ */ /*#__PURE__*/ new Map(); var registryRevision = 0; function registerModuleDefinition(def) { registeredModules.set(def.name, def); registryRevision++; if (def.dependencies) { for (const dependency of def.dependencies) { register(dependency); } } } function ifRegistryChanged(lastSeen, callback2) { if (registryRevision !== lastSeen) { callback2(); } return registryRevision; } function register(def) { const existingDefinition = registeredModules.get(def.name); if (!existingDefinition) { registerModuleDefinition(def); return; } if (existingDefinition.version === def.version) { if (!existingDefinition.enterprise && def.enterprise) { registerModuleDefinition(def); } return; } throw new Error( [ `AG Charts - Module '${def.name}' already registered with different version:`, `${existingDefinition.version} vs ${def.version}`, ``, `Check your package.json for conflicting dependencies - depending on your package manager`, `one of these commands may help:`, `- npm ls ag-charts-community`, `- yarn why ag-charts-community` ].join("\n") ); } function registerModules(definitions) { for (const definition of definitions.flat()) { register(definition); } } function reset2() { clearRegistryModes(); registeredModules.clear(); registryRevision++; } function hasModule(moduleName) { return registeredModules.has(moduleName); } function* listModules() { for (const definition of registeredModules.values()) { yield definition; } } function* listModulesByType(moduleType) { for (const definition of registeredModules.values()) { if (isModuleType(moduleType, definition)) { yield definition; } } } function getAxisModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("axis" /* Axis */, definition)) { return definition; } } function getChartModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("chart" /* Chart */, definition)) { return definition; } throw new Error( `AG Charts - Unknown chart type; Check options are correctly structured and series types are specified` ); } function getPresetModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("preset" /* Preset */, definition)) { return definition; } } function getSeriesModule(moduleName) { const definition = registeredModules.get(moduleName); if (isModuleType("series" /* Series */, definition)) { return definition; } } function isModuleType(moduleType, definition) { return definition?.type === moduleType; } // packages/ag-charts-core/src/state/cleanupRegistry.ts var CleanupRegistry = class { constructor() { this.callbacks = /* @__PURE__ */ new Set(); } flush() { for (const cb of this.callbacks) { cb(); } this.callbacks.clear(); } merge(registry) { for (const cb of registry.callbacks) { this.callbacks.add(cb); } } register(...callbacks) { for (const cb of callbacks) { if (!cb) continue; this.callbacks.add(cb); } } }; // packages/ag-charts-core/src/modules/moduleInstance.ts var AbstractModuleInstance = class { constructor() { this.cleanup = new CleanupRegistry(); } destroy() { this.cleanup.flush(); } }; // packages/ag-charts-core/src/module/dynamicContext.ts function asDynamicContext(impl) { return impl; } var state = /* @__PURE__ */ /*#__PURE__*/ new WeakMap(); function internal(impl) { const s = state.get(impl); if (!s) throw new Error("AG Charts - DynamicContext: missing internal state."); return s; } var DynamicContextImpl = class _DynamicContextImpl { constructor(parent) { const s = { cleanup: new CleanupRegistry(), self: asDynamicContext(this), resolving: /* @__PURE__ */ new Set(), children: /* @__PURE__ */ new Set(), refs: /* @__PURE__ */ new Set(), parent, destroyed: false }; state.set(this, s); if (parent) { internal(parent).children.add(this); } } get cleanup() { return internal(this).cleanup; } constant(name, value) { this.assertNotDestroyed(); Object.defineProperty(this, name, { value, configurable: true, enumerable: true }); return internal(this).self; } ref(name, value) { this.assertNotDestroyed(); const s = internal(this); s.refs.add(name); Object.defineProperty(this, name, { value, configurable: true, enumerable: true }); return s.self; } service(name, fn) { this.assertNotDestroyed(); Object.defineProperty(this, name, { configurable: true, enumerable: true, get: () => { const value = this.resolve(name, fn); Object.defineProperty(this, name, { value, configurable: true, enumerable: true }); return value; } }); return internal(this).self; } factory(name, fn) { this.assertNotDestroyed(); Object.defineProperty(this, name, { configurable: true, enumerable: true, get: () => this.resolve(name, fn) }); return internal(this).self; } has(name) { return name in this; } child() { const c = new _DynamicContextImpl(this); Object.setPrototypeOf(c, this); return asDynamicContext(c); } destroy() { const s = internal(this); if (s.destroyed) return; s.destroyed = true; for (const c of s.children) { c.destroy(); } s.children.clear(); const keys = Object.keys(this); for (let i = keys.length - 1; i >= 0; i--) { const key = keys[i]; if (s.refs.has(key)) continue; const descriptor = Object.getOwnPropertyDescriptor(this, key); if (descriptor?.value != null && typeof descriptor.value === "object") { descriptor.value.destroy?.(); } } s.cleanup.flush(); if (s.parent) { internal(s.parent).children.delete(this); } } resolve(name, fn) { const s = internal(this); if (s.destroyed) { throw new Error(`AG Charts - DynamicContext: cannot resolve '${name}' on a destroyed context.`); } if (s.resolving.has(name)) { throw new Error(`AG Charts - DynamicContext: circular dependency detected while resolving '${name}'.`); } s.resolving.add(name); try { return fn(s.self); } finally { s.resolving.delete(name); } } assertNotDestroyed() { if (internal(this).destroyed) { throw new Error("AG Charts - DynamicContext: cannot register on a destroyed context."); } } }; function createDynamicContext() { return asDynamicContext(new DynamicContextImpl()); } // packages/ag-charts-core/src/utils/data/numbers.ts function clamp(min, value, max) { return Math.min(max, Math.max(min, value)); } function inRange(value, range2, epsilon = 1e-10) { return value >= range2[0] - epsilon && value <= range2[1] + epsilon; } function isNumberEqual(a, b, epsilon = 1e-10) { return a === b || Math.abs(a - b) < epsilon; } function isNegative(value) { return Math.sign(value) === -1 || Object.is(value, -0); } function isInteger(value) { return value % 1 === 0; } function roundTo(value, decimals = 2) { const base = 10 ** decimals; return Math.round(value * base) / base; } function ceilTo(value, decimals = 2) { const base = 10 ** decimals; return Math.ceil(value * base) / base; } function modulus(n, m) { return Math.floor(n % m + (n < 0 ? Math.abs(m) : 0)); } function countFractionDigits(value) { if (Math.floor(value) === value) { return 0; } let valueString = String(value); let exponent = 0; if (value < 1e-6 || value >= 1e21) { let exponentString; [valueString, exponentString] = valueString.split("e"); if (exponentString != null) { exponent = Number(exponentString); } } const decimalPlaces2 = valueString.split(".")[1]?.length ?? 0; return Math.max(decimalPlaces2 - exponent, 0); } // packages/ag-charts-core/src/scale/colorScaleUtil.ts function findNextDefinedStop(fills, from3) { for (let j = from3 + 1; j < fills.length; j++) { if (fills[j]?.stop != null) return j; } return fills.length - 1; } function resolveStopPositions(fills, d0, d1, isDiscrete) { const stops = new Array(fills.length); let previousDefinedStopIndex = 0; let nextDefinedStopIndex = -1; for (let i = 0; i < fills.length; i++) { if (i >= nextDefinedStopIndex) { nextDefinedStopIndex = findNextDefinedStop(fills, i); } const stop = fills[i]?.stop; if (stop == null) { const stop0 = fills[previousDefinedStopIndex]?.stop; const stop1 = fills[nextDefinedStopIndex]?.stop; const value0 = stop0 ?? d0; const value1 = stop1 ?? d1; const offset = isDiscrete && stop0 == null ? 1 : 0; stops[i] = value0 + (value1 - value0) * (i - previousDefinedStopIndex + offset) / (nextDefinedStopIndex - previousDefinedStopIndex + offset); } else { stops[i] = stop; previousDefinedStopIndex = i; } } return stops; } function formatColorScaleBinLabel(bin, index, bins, formatValueFn) { if (bin.name != null) { return bin.name; } const isLast = index === bins.length - 1; if (Number.isInteger(bin.start) && Number.isInteger(bin.end) && !isLast && bin.end - bin.start >= 1) { return `${formatValueFn(bin.start, 0)}\u2013${formatValueFn(bin.end - 1, 0)}`; } return `${formatValueFn(bin.start)}\u2013${formatValueFn(bin.end)}`; } function computeColorBins(fills, domain, mode) { if (fills.length === 0) { return { domain: [], range: [], bins: [] }; } const [d0, d1] = domain; const isDiscrete = mode === "discrete"; const resolvedStops = resolveStopPositions(fills, d0, d1, isDiscrete); const resolvedColors = fills.map((fill) => fill.color); if (isDiscrete) { return buildDiscreteBins(resolvedStops, resolvedColors, fills, d0, d1); } return { domain: resolvedStops, range: resolvedColors, bins: [] }; } function buildDiscreteBins(stops, colors, fills, d0, d1) { const domain = []; const range2 = []; const bins = []; for (let i = 0; i < fills.length; i++) { const binStart = i === 0 ? d0 : stops[i - 1]; const binEnd = stops[i]; const clampedStart = clamp(d0, binStart, d1); const clampedEnd = Math.max(clampedStart, clamp(d0, binEnd, d1)); domain.push(clampedStart); range2.push(colors[i]); bins.push({ start: clampedStart, end: clampedEnd, color: colors[i], name: fills[i].name }); } domain.push(bins.at(-1).end); return { domain, range: range2, bins }; } function deriveNormalizedStops(colorScale) { const { domain, range: range2, mode, displayDomain } = colorScale; if (range2.length === 0) return []; const [d0, d1] = displayDomain ?? [domain[0], domain.at(-1)]; const extent2 = d1 - d0 || 1; if (mode === "discrete") { const stops = []; for (let i = 0; i < range2.length; i++) { const start2 = clamp(0, (domain[i] - d0) / extent2, 1); const end2 = clamp(0, (domain[i + 1] - d0) / extent2, 1); if (end2 < start2) continue; stops.push({ stop: start2, color: range2[i] }); if (end2 > start2) stops.push({ stop: end2, color: range2[i] }); } return stops; } if (domain.length < range2.length) { const count = Math.max(range2.length - 1, 1); return range2.map((color2, i) => ({ stop: i / count, color: color2 })); } return domain.map((v, i) => ({ stop: (v - d0) / extent2, color: range2[i] })); } function formatColorBinLabel(start2, end2, index, count, formatValue2) { const bin = { start: start2, end: end2, color: "" }; return formatColorScaleBinLabel(bin, index, { length: count }, formatValue2); } function findDiscreteColorBinLabel(colorScale, fills, value, formatValueFn) { const { domain, range: range2, mode } = colorScale; if (mode !== "discrete" || range2.length === 0) return void 0; let i = 0; while (i < range2.length - 1 && value >= domain[i + 1]) i++; return fills[i]?.name ?? formatColorBinLabel(domain[i], domain[i + 1], i, range2.length, formatValueFn); } function discreteColorStops(colorStops) { return colorStops.flatMap((colorStop2, i) => { const { stop } = colorStop2; const nextColor = colorStops.at(i + 1)?.color; return nextColor == null ? [colorStop2] : [colorStop2, { stop, color: nextColor }]; }); } // packages/ag-charts-types/src/chart/navigatorOptions.ts var __MINI_CHART_SERIES_OPTIONS = void 0; var __VERIFY_MINI_CHART_SERIES_OPTIONS = void 0; /*#__PURE__*/ (() => { __VERIFY_MINI_CHART_SERIES_OPTIONS = __MINI_CHART_SERIES_OPTIONS; })(); // packages/ag-charts-types/src/chart/themeOptions.ts var __THEME_OVERRIDES = void 0; var __VERIFY_THEME_OVERRIDES = void 0; /*#__PURE__*/ (() => { __VERIFY_THEME_OVERRIDES = __THEME_OVERRIDES; })(); // packages/ag-charts-types/src/presets/gauge/commonOptions.ts var __THEMEABLE_OPTIONS = void 0; var __VERIFY_THEMEABLE_OPTIONS = void 0; /*#__PURE__*/ (() => { __VERIFY_THEMEABLE_OPTIONS = __THEMEABLE_OPTIONS; })(); var __AXIS_LABEL_OPTIONS = void 0; var __VERIFY_AXIS_LABEL_OPTIONS = void 0; /*#__PURE__*/ (() => { __VERIFY_AXIS_LABEL_OPTIONS = __AXIS_LABEL_OPTIONS; })(); // packages/ag-charts-core/src/types/text.ts var EllipsisChar = "\u2026"; var LineSplitter = /\r?\n/g; var TrimEdgeGuard = "\u200B"; var TrimCharsRegex = /[\s.,;:-]{1,5}$/; // packages/ag-charts-core/src/utils/dom/domUtil.ts var styleDeclaration; function parseColor(color2) { if (styleDeclaration == null) { const OptionConstructor = getWindow("Option"); styleDeclaration = new OptionConstructor().style; } styleDeclaration.color = color2; const result = styleDeclaration.color || null; styleDeclaration.color = ""; return result; } function isDirectionRtl(element) { return element?.ownerDocument.defaultView?.getComputedStyle(element).direction === "rtl"; } function setElementBBox(element, bbox) { if (!element) return; const { x, y, width: width2, height: height2 } = normalizeBounds(bbox); setPixelValue(element.style, "width", width2); setPixelValue(element.style, "height", height2); setPixelValue(element.style, "left", x); setPixelValue(element.style, "top", y); } function getElementBBox(element) { const styleWidth = Number.parseFloat(element.style.width); const styleHeight = Number.parseFloat(element.style.height); const styleX = Number.parseFloat(element.style.left); const styleY = Number.parseFloat(element.style.top); const width2 = Number.isFinite(styleWidth) ? styleWidth : element.offsetWidth; const height2 = Number.isFinite(styleHeight) ? styleHeight : element.offsetHeight; const x = Number.isFinite(styleX) ? styleX : element.offsetLeft; const y = Number.isFinite(styleY) ? styleY : element.offsetTop; return { x, y, width: width2, height: height2 }; } function focusCursorAtEnd(element) { element.focus({ preventScroll: true }); if (element.lastChild?.textContent == null) return; const { ownerDocument } = element; const range2 = ownerDocument.createRange(); range2.setStart(element.lastChild, element.lastChild.textContent.length); range2.setEnd(element.lastChild, element.lastChild.textContent.length); const selection = ownerDocument.defaultView?.getSelection(); selection?.removeAllRanges(); selection?.addRange(range2); } function isInputPending() { const navigator = getWindow("navigator"); if ("scheduling" in navigator) { const scheduling = navigator.scheduling; if ("isInputPending" in scheduling) { return scheduling.isInputPending({ includeContinuous: true }); } } return false; } function getIconClassNames(icon) { return `ag-charts-icon ag-charts-icon-${icon}`; } function normalizeBounds(bbox) { let { x, y, width: width2, height: height2 } = bbox; if ((width2 == null || width2 > 0) && (height2 == null || height2 > 0)) { return bbox; } if (x != null && width2 != null && width2 < 0) { width2 = -width2; x = x - width2; } if (y != null && height2 != null && height2 < 0) { height2 = -height2; y = y - height2; } return { x, y, width: width2, height: height2 }; } function setPixelValue(style, key, value) { if (value == null) { style.removeProperty(key); } else { style.setProperty(key, `${value}px`); } } // packages/ag-charts-core/src/utils/types/typeGuards.ts function isDefined(val) { return val != null; } function isArray(value) { return Array.isArray(value); } function isBoolean(value) { return typeof value === "boolean"; } function isDate(value) { return value instanceof Date; } function isValidDate(value) { return isDate(value) && !Number.isNaN(Number(value)); } function isRegExp(value) { return value instanceof RegExp; } function isFunction(value) { return typeof value === "function"; } function isObject(value) { return typeof value === "object" && value !== null && !isArray(value); } function isObjectLike(value) { return isArray(value) || isPlainObject(value); } function isPlainObject(value) { return typeof value === "object" && value !== null && value.constructor?.name === "Object"; } function isEmptyObject(value) { if (typeof value !== "object" || value === null) return false; for (const _ in value) { return false; } return true; } function isString(value) { return typeof value === "string"; } function isNumber(value) { return typeof value === "number"; } function isFiniteNumber(value) { return Number.isFinite(value); } function isHtmlElement(value) { return value != null && value.nodeType === 1 && "style" in value; } function isEnumKey(enumObject, enumKey) { return isString(enumKey) && Object.keys(enumObject).includes(enumKey); } function isEnumValue(enumObject, enumValue) { return Object.values(enumObject).includes(enumValue); } function isSymbol(value) { return typeof value === "symbol"; } function isColor(value) { return isString(value) && (value === "none" || parseColor(value) != null); } function isKeyOf(value, container) { return value in container; } // packages/ag-charts-core/src/utils/text/textUtils.ts function toFontString({ fontSize, fontStyle, fontWeight: fontWeight2, fontFamily }) { let fontString = ""; if (fontStyle && fontStyle !== "normal") { fontString += `${fontStyle} `; } if (fontWeight2 && fontWeight2 !== "normal" && fontWeight2 !== 400) { fontString += `${fontWeight2 === 700 ? "bold" : fontWeight2} `; } fontString += `${fontSize}px`; fontString += ` ${fontFamily}`; return fontString; } function calcLineHeight(fontSize, lineHeightRatio = 1.15) { return Math.round(fontSize * lineHeightRatio); } function toTextString(value) { return String(value ?? ""); } function coerceTextValue(value) { if (isNumber(value) || isDate(value)) return toTextString(value); return value; } function appendEllipsis(text) { return preserveArabicJoining(text.replace(TrimCharsRegex, "")) + EllipsisChar; } var RIGHT_JOIN_ONLY = /* @__PURE__ */ /*#__PURE__*/ new Set([ 1575, // Alef ا 1577, // Teh Marbuta ة 1583, // Dal د 1584, // Thal ذ 1585, // Ra ر 1586, // Zain ز 1608 // Waw و ]); function isDualJoiningArabic(code) { return code >= 1568 && code <= 1610 && !RIGHT_JOIN_ONLY.has(code); } function preserveArabicJoining(text) { if (!text) return text; const lastCode = text.codePointAt(text.length - 1); if (isDualJoiningArabic(lastCode)) { return text + "\u200D"; } return text; } function guardTextEdges(str) { return TrimEdgeGuard + str + TrimEdgeGuard; } function unguardTextEdges(str) { return str.replaceAll(TrimEdgeGuard, ""); } function isTruncated(value) { return isArray(value) ? isSegmentTruncated(value.at(-1)) : isTextTruncated(toTextString(value)); } function isTextTruncated(str) { return str.endsWith(EllipsisChar); } function isSegmentTruncated(segment) { return toTextString(segment?.text).endsWith(EllipsisChar); } var graphemeSegmenter = /*#__PURE__*/ (() => (typeof Intl !== "undefined" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : void 0))(); function graphemeSegments(text) { if (graphemeSegmenter) { return Array.from(graphemeSegmenter.segment(text), (s) => s.segment); } return Array.from(text); } // packages/ag-charts-core/src/utils/data/strings.ts function joinFormatted(values, conjunction = "and", format = String, maxItems = Infinity) { if (values.length === 0) { return ""; } else if (values.length === 1) { return format(values[0]); } values = values.map(format); const lastValue = values.pop(); if (values.length >= maxItems) { const remainingCount = values.length - (maxItems - 1); return `${values.slice(0, maxItems - 1).join(", ")}, and ${remainingCount} more ${conjunction} ${lastValue}`; } return `${values.join(", ")} ${conjunction} ${lastValue}`; } function stringifyValue(value, maxLength = Infinity) { if (typeof value === "number") { if (Number.isNaN(value)) { return "NaN"; } else if (value === Infinity) { return "Infinity"; } else if (value === -Infinity) { return "-Infinity"; } } const strValue = JSON.stringify(value) ?? typeof value; if (strValue.length > maxLength) { return `${strValue.slice(0, maxLength)}... (+${strValue.length - maxLength} characters)`; } return strValue; } function countLines(text) { let count = 1; for (let i = 0; i < text.length; i++) { if (text.codePointAt(i) === 10) { count++; } } return count; } function levenshteinDistance(a, b) { if (a === b) return 0; const [shorter, longer] = a.length < b.length ? [a, b] : [b, a]; const m = shorter.length; const n = longer.length; let prevRow = new Array(m + 1).fill(0).map((_, i) => i); let currRow = new Array(m + 1); for (let i = 1; i <= n; i++) { currRow[0] = i; for (let j = 1; j <= m; j++) { const cost = longer[i - 1] === shorter[j - 1] ? 0 : 1; currRow[j] = Math.min( prevRow[j] + 1, // Deletion currRow[j - 1] + 1, // Insertion prevRow[j - 1] + cost // Substitution ); } [prevRow, currRow] = [currRow, prevRow]; } return prevRow[m]; } function kebabCase(a) { return a.replaceAll(KEBAB_CASE_REGEX, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase()); } var KEBAB_CASE_REGEX = /[A-Z]+(?![a-z])|[A-Z]/g; function toPlainText(text, fallback = "") { if (text == null) { return fallback; } else if (isArray(text)) { return text.map((segment) => toTextString(segment.text)).join(""); } else if (isString(text)) { return text; } else { return String(text); } } // packages/ag-charts-core/src/utils/functions.ts function debounce(callback2, waitMs = 0, options) { const { leading = false, trailing = true, maxWait = Infinity } = options ?? {}; let timerId; let startTime; if (maxWait < waitMs) { throw new Error("Value of maxWait cannot be lower than waitMs."); } function debounceCallback(...args) { if (leading && !startTime) { startTime = Date.now(); timerId = setTimeout(() => startTime = null, waitMs); callback2(...args); return; } let adjustedWaitMs = waitMs; if (maxWait !== Infinity && startTime) { const elapsedTime = Date.now() - startTime; if (waitMs > maxWait - elapsedTime) { adjustedWaitMs = maxWait - elapsedTime; } } clearTimeout(timerId); startTime ?? (startTime = Date.now()); timerId = setTimeout(() => { startTime = null; if (trailing) { callback2(...args); } }, adjustedWaitMs); } return Object.assign(debounceCallback, { cancel() { clearTimeout(timerId); startTime = null; } }); } function throttle(callback2, waitMs, options) { const { leading = true, trailing = true } = options ?? {}; let timerId; let lastArgs; let shouldWait = false; function timeoutHandler() { if (trailing && lastArgs) { timerId = setTimeout(timeoutHandler, waitMs); callback2(...lastArgs); } else { shouldWait = false; } lastArgs = null; } function throttleCallback(...args) { if (shouldWait) { lastArgs = args; } else { shouldWait = true; timerId = setTimeout(timeoutHandler, waitMs); if (leading) { callback2(...args); } else { lastArgs = args; } } } return Object.assign(throttleCallback, { cancel() { clearTimeout(timerId); shouldWait = false; lastArgs = null; } }); } function safeCall(callback2, args, errorPath = "") { try { return callback2(...args); } catch (error2) { const postfix = errorPath ? ` \`${errorPath}\`` : ""; warnOnce(`Uncaught exception in user callback${postfix}`, error2); } } // packages/ag-charts-core/src/state/validation.ts var descriptionSymbol = /*#__PURE__*/ Symbol("description"); var requiredSymbol = /*#__PURE__*/ Symbol("required"); var markedSymbol = /*#__PURE__*/ Symbol("marked"); var undocumentedSymbol = /*#__PURE__*/ Symbol("undocumented"); var enterpriseSymbol = /*#__PURE__*/ Symbol("enterprise"); var deprecatedSymbol = /*#__PURE__*/ Symbol("deprecated"); var unionSymbol = /*#__PURE__*/ Symbol("union"); var similarOptionsMap = /*#__PURE__*/ [ ["placement", "position"], ["padding", "spacing", "gap"], ["color", "fill", "stroke"], ["whisker", "wick"], ["src", "url"], ["width", "thickness"], ["show", "visible", "enabled"] ].reduce((map, words) => { for (const word of words) { map.set(word.toLowerCase(), new Set(words.filter((w) => w !== word))); } return map; }, /* @__PURE__ */ new Map()); var ErrorType = /* @__PURE__ */ /*#__PURE__*/ ((ErrorType2) => { ErrorType2["Enterprise"] = "enterprise"; ErrorType2["Invalid"] = "invalid"; ErrorType2["Required"] = "required"; ErrorType2["Unknown"] = "unknown"; return ErrorType2; })(ErrorType || {}); function extendPath(path, key) { if (isFiniteNumber(key)) { return `${path}[${key}]`; } return path ? `${path}.${key}` : key; } var ValidationError = class { constructor(type, description, value, path, key) { this.type = type; this.description = description; this.value = value; this.path = path; this.key = key; } setUnionType(unionType, path) { if (this.path.startsWith(path)) { const suffix = this.path.slice(path.length); this.altPath = `${path}[type=${unionType}]${suffix}`; } } getPrefix() { const { altPath: path = this.path, key } = this; if (!path && !key) return "Value"; return `Option \`${key ? extendPath(path, key) : path}\``; } toString() { const { description = "unknown", type, value } = this; if (type === "required" /* Required */ && value == null) { return `${this.getPrefix()} is required and has not been provided; expecting ${description}, ignoring.`; } if (type === "enterprise" /* Enterprise */) { return `${this.getPrefix()} is an AG Charts Enterprise feature; ignoring.`; } return `${this.getPrefix()} cannot be set to \`${stringifyValue(value, 50)}\`; expecting ${description}, ignoring.`; } }; var UnknownError = class extends ValidationError { constructor(suggestions, value, path, key) { super("unknown" /* Unknown */, void 0, value, path, key); this.suggestions = suggestions; this.key = key; } getPrefix() { return `Unknown option \`${extendPath(this.altPath ?? this.path, this.key)}\``; } getPostfix() { const suggestions = joinFormatted(findSuggestions(this.key, this.suggestions), "or", (val) => `\`${val}\``); return suggestions ? `; Did you mean ${suggestions}? Ignoring.` : ", ignoring."; } toString() { return `${this.getPrefix()}${this.getPostfix()}`; } }; function validate(options, optionsDefs2, path = "", opts = {}) { if (!isObject(options)) { return { cleared: null, invalid: [new ValidationError("required" /* Required */, "an object", options, path)] }; } const cleared = {}; const invalid = []; const optionsKeys = new Set(Object.keys(options)); const unusedKeys = []; if (unionSymbol in optionsDefs2) { const validTypes = Object.keys(optionsDefs2); const defaultType = optionsDefs2[unionSymbol]; if (options.type != null && validTypes.includes(options.type) || options.type == null && defaultType != null) { const { type = defaultType, ...rest } = options; const nestedResult = validate(rest, optionsDefs2[type], path, opts); Object.assign(cleared, { type }, nestedResult.cleared); for (const error2 of nestedResult.invalid) { error2.setUnionType(type, path); } invalid.push(...nestedResult.invalid); } else { const keywords = joinFormatted(validTypes, "or", (val) => `'${val}'`); invalid.push( new ValidationError("required" /* Required */, `a keyword such as ${keywords}`, options.type, path, "type") ); } return { cleared, invalid }; } for (const key of Object.keys(optionsDefs2)) { const validatorOrDefs = optionsDefs2[key]; const required3 = validatorOrDefs[requiredSymbol]; const value = options[key]; optionsKeys.delete(key); if (value === void 0) { if (!validatorOrDefs[undocumentedSymbol]) { unusedKeys.push(key); } if (!required3) continue; } const keyPath = extendPath(path, key); if (isFunction(validatorOrDefs)) { const context = { options, path: keyPath, silentAdvisories: opts.silentAdvisories }; const validatorResult = validatorOrDefs(value, context); const objectResult = typeof validatorResult === "object"; if (objectResult) { invalid.push(...validatorResult.invalid); if (validatorResult.valid) { cleared[key] = validatorResult.cleared; continue; } else if (hasRequiredInPath(validatorResult.invalid, keyPath)) { continue; } } else if (validatorResult) { cleared[key] = value; continue; } invalid.push( new ValidationError( required3 ? "required" /* Required */ : "invalid" /* Invalid */, validatorOrDefs[descriptionSymbol], value, path, key ) ); } else { const nestedResult = validate(value, validatorOrDefs, keyPath, opts); if (nestedResult.cleared != null) { cleared[key] = nestedResult.cleared; } invalid.push(...nestedResult.invalid); } } for (const key of optionsKeys) { const value = options[key]; if (value === void 0) continue; invalid.push(new UnknownError(unusedKeys, value, path, key)); } return { cleared, invalid }; } function findSuggestions(value, suggestions, maxDistance = 2) { const lowerCaseValue = value.toLowerCase(); const similarValues = similarOptionsMap.get(lowerCaseValue); return suggestions.filter((key) => { const lowerCaseKey = key.toLowerCase(); return similarValues?.has(key) === true || lowerCaseKey.includes(lowerCaseValue) || levenshteinDistance(lowerCaseValue, lowerCaseKey) <= maxDistance; }); } function attachDescription(validatorOrDefs, description) { if (isFunction(validatorOrDefs)) { let clonedValidator2 = function(value, context) { return validatorOrDefs(value, context); }; var clonedValidator = clonedValidator2; clonedValidator2[descriptionSymbol] = description; return clonedValidator2; } else { return { ...validatorOrDefs, [descriptionSymbol]: description }; } } function required(validatorOrDefs) { if (validatorOrDefs[enterpriseSymbol]) { throw new Error( "`required()` cannot wrap an `enterprise()` validator; enterprise options must remain optional." ); } return Object.assign( isFunction(validatorOrDefs) ? (value, context) => validatorOrDefs(value, context) : optionsDefs(validatorOrDefs), { [requiredSymbol]: true, [descriptionSymbol]: validatorOrDefs[descriptionSymbol] } ); } function undocumented(validatorOrDefs) { return Object.assign( isFunction(validatorOrDefs) ? (value, context) => validatorOrDefs(value, context) : optionsDefs(validatorOrDefs), { [undocumentedSymbol]: true, [descriptionSymbol]: validatorOrDefs[descriptionSymbol] } ); } function enterprise(validatorOrDefs) { if (validatorOrDefs[requiredSymbol]) { throw new Error( "`enterprise()` cannot wrap a `required()` validator; enterprise options must remain optional." ); } const inner = isFunction(validatorOrDefs) ? validatorOrDefs : optionsDefs(validatorOrDefs); const description = validatorOrDefs[descriptionSymbol]; const gated = (value, context) => { if (value !== void 0 && !isEnterprise()) { warnOnce(new ValidationError("enterprise" /* Enterprise */, description, value, context.path).toString()); return { valid: true, cleared: null, invalid: [] }; } return inner(value, context); }; return Object.assign(gated, { [enterpriseSymbol]: true, [descriptionSymbol]: description }); } function deprecated(validatorOrDefs, message) { const inner = isFunction(validatorOrDefs) ? validatorOrDefs : optionsDefs(validatorOrDefs); const description = validatorOrDefs[descriptionSymbol]; const gated = (value, context) => { if (value !== void 0 && !context.silentAdvisories) { warnOnce(`Option \`${context.path}\` is deprecated. ${message}`); } return inner(value, context); }; return Object.assign(gated, { [deprecatedSymbol]: message, [descriptionSymbol]: description }); } var optionsDefs = (defs, description = "an object", failAll = false) => attachDescription((value, context) => { const result = validate(value, defs, context.path, { silentAdvisories: context.silentAdvisories }); const valid = !hasRequiredInPath(result.invalid, context.path); return { valid, cleared: valid || !failAll ? result.cleared : null, invalid: result.invalid }; }, description); var typeUnion = (defs, description, defaultType) => ({ ...defs, [descriptionSymbol]: description, [unionSymbol]: defaultType }); var and = (...validators) => attachDescription( (value, context) => { const invalid = []; for (const validator of validators) { const result = validator(value, context); if (typeof result === "object") { invalid.push(...result.invalid); if (!result.valid) { return { valid: false, cleared: value, invalid }; } value = result.cleared; } else if (!result) { return false; } } return { valid: true, cleared: value, invalid }; }, joinFormatted( validators.filter((v) => !v[undocumentedSymbol]).map((v) => v[descriptionSymbol]).filter(isDefined), "and" ) ); var or = (...validators) => attachDescription( (value, context) => { for (const validator of validators) { const result = validator(value, context); if (typeof result === "object" ? result.valid : result) { return result; } } return false; }, joinFormatted( validators.filter((v) => !v[undocumentedSymbol]).map((v) => v[descriptionSymbol]).filter(isDefined), "or" ) ); var isComparable = (value) => isFiniteNumber(value) || isValidDate(value); var isValidDateValue = (value) => isDate(value) || (isFiniteNumber(value) || isString(value)) && isValidDate(new Date(value)); var array = /*#__PURE__*/ attachDescription(isArray, "an array"); var boolean = /*#__PURE__*/ attachDescription(isBoolean, "a boolean"); var