(function (g, f) { if ("object" == typeof exports && "object" == typeof module) { module.exports = f(); } else if ("function" == typeof define && define.amd) { define("agCharts", [], f); } else if ("object" == typeof exports) { exports["agCharts"] = f(); } else { g["agCharts"] = f(); } }(this, () => { var exports = {}; var module = { exports }; if (typeof require === 'undefined') { function require(name) { throw new Error('Unknown module: ' + name); } } "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from3, except, desc) => { if (from3 && typeof from3 === "object" || typeof from3 === "function") { for (let key of __getOwnPropNames(from3)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc(from3, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); 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/globals/logger.ts var logger_exports = {}; __export(logger_exports, { error: () => error, errorOnce: () => errorOnce, log: () => log, logGroup: () => logGroup, reset: () => reset, table: () => table, warn: () => warn, warnOnce: () => warnOnce }); 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 warnOnce(message, ...logContent) { const cacheKey = `Logger.warn: ${message}`; if (doOnceCache.has(cacheKey)) return; warn(message, ...logContent); doOnceCache.add(cacheKey); } function errorOnce(message, ...logContent) { const cacheKey = `Logger.error: ${message}`; if (doOnceCache.has(cacheKey)) return; error(message, ...logContent); doOnceCache.add(cacheKey); } function reset() { doOnceCache.clear(); } function logGroup(name, cb) { console.groupCollapsed(name); try { return cb(); } finally { console.groupEnd(); } } var doOnceCache; var init_logger = __esm({ "packages/ag-charts-core/src/globals/logger.ts"() { "use strict"; doOnceCache = /* @__PURE__ */ new Set(); } }); // packages/ag-charts-core/src/interfaces/moduleDefinition.ts var init_moduleDefinition = __esm({ "packages/ag-charts-core/src/interfaces/moduleDefinition.ts"() { "use strict"; } }); // packages/ag-charts-core/src/globals/moduleRegistry.ts var ModuleRegistry; var init_moduleRegistry = __esm({ "packages/ag-charts-core/src/globals/moduleRegistry.ts"() { "use strict"; ModuleRegistry = class { static [Symbol.iterator]() { return this.registeredModules.values(); } static register(definition) { const existingDefinition = this.registeredModules.get(definition.name); if (existingDefinition && (existingDefinition.enterprise || !definition.enterprise)) { throw new Error(`AG Charts - Module '${definition.name}' already registered`); } this.registeredModules.set(definition.name, definition); } static registerMany(definitions) { for (const definition of definitions) { this.register(definition); } } static reset() { this.registeredModules.clear(); } static detectChartDefinition(options) { return this.detectDefinition("chart" /* Chart */, options); } static detectSeriesDefinition(options) { return this.detectDefinition("series" /* Series */, options); } static detectDefinition(moduleType, options) { for (const definition of this.registeredModules.values()) { if (definition.type === moduleType && definition.detect(options)) { return definition; } } throw new Error( `AG Charts - Unknown ${moduleType} type; Check options are correctly structured and series types are specified` ); } }; ModuleRegistry.registeredModules = /* @__PURE__ */ new Map(); } }); // packages/ag-charts-core/src/globals/index.ts var init_globals = __esm({ "packages/ag-charts-core/src/globals/index.ts"() { "use strict"; init_logger(); init_moduleRegistry(); } }); // packages/ag-charts-core/src/interfaces/globalTypes.ts var init_globalTypes = __esm({ "packages/ag-charts-core/src/interfaces/globalTypes.ts"() { "use strict"; } }); // packages/ag-charts-core/src/classes/eventEmitter.ts var EventEmitter; var init_eventEmitter = __esm({ "packages/ag-charts-core/src/classes/eventEmitter.ts"() { "use strict"; 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) { this.events.get(eventName)?.forEach((callback2) => 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/utils/arrays.ts function toArray(value) { if (typeof value === "undefined") { 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, offset4 = 0) { if (data.length === 0) { return []; } const result = []; for (let i = 0; i < size; i++) { result.push(data.at((i + offset4) % data.length)); } return result; } function sortBasedOnArray(baseArray, orderArray) { const orderMap = /* @__PURE__ */ new Map(); orderArray.forEach((item, index) => { orderMap.set(item, index); }); return baseArray.sort((a, b) => { const indexA = orderMap.get(a) ?? Infinity; const indexB = orderMap.get(b) ?? Infinity; return indexA - indexB; }); } var init_arrays = __esm({ "packages/ag-charts-core/src/utils/arrays.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/binarySearch.ts function findMaxIndex(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value) { found = index; min = index + 1; } else { max = index - 1; } } return found; } function findMinIndex(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value) { found = index; max = index - 1; } else { min = index + 1; } } return found; } function findMinValue(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value == null) { min = index + 1; } else { found = value; max = index - 1; } } return found; } var init_binarySearch = __esm({ "packages/ag-charts-core/src/utils/binarySearch.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/diff.ts function diffArrays(previous, current) { const size = Math.max(previous.length, current.length); const added = /* @__PURE__ */ new Set(); const removed = /* @__PURE__ */ new Set(); for (let i = 0; i < size; i++) { const prev = previous[i]; const curr = current[i]; if (prev === curr) continue; if (removed.has(curr)) { removed.delete(curr); } else if (curr) { added.add(curr); } if (added.has(prev)) { added.delete(prev); } else if (prev) { removed.add(prev); } } return { changed: added.size > 0 || removed.size > 0, added, removed }; } var init_diff = __esm({ "packages/ag-charts-core/src/utils/diff.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/functions.ts 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; } }); } var init_functions = __esm({ "packages/ag-charts-core/src/utils/functions.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/iterators.ts function* iterate(...iterators) { for (const iterator of iterators) { yield* iterator; } } function toIterable(value) { return value != null && typeof value === "object" && Symbol.iterator in value ? value : [value]; } function first(iterable) { for (const value of iterable) { return value; } throw new Error("AG Charts - no first() value found"); } var init_iterators = __esm({ "packages/ag-charts-core/src/utils/iterators.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/strings.ts function joinFormatted(values, conjunction = "and", format = String, maxItems = Infinity) { 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) { switch (typeof value) { case "undefined": return "undefined"; case "number": if (isNaN(value)) { return "NaN"; } else if (value === Infinity) { return "Infinity"; } else if (value === -Infinity) { return "-Infinity"; } default: value = JSON.stringify(value); if (value.length > maxLength) { return `${value.slice(0, maxLength)}... (+${value.length - maxLength} characters)`; } return value; } } function countLines(text3) { let count = 1; for (let i = 0; i < text3.length; i++) { if (text3.charCodeAt(i) === 10) { count++; } } return count; } var init_strings = __esm({ "packages/ag-charts-core/src/utils/strings.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/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) && !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 isPlainObject(value) { return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype; } 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 typeof window !== "undefined" && value instanceof HTMLElement; } function isEnumValue(enumObject, enumValue) { return Object.values(enumObject).includes(enumValue); } function isSymbol(value) { return typeof value === "symbol"; } var init_typeGuards = __esm({ "packages/ag-charts-core/src/utils/typeGuards.ts"() { "use strict"; } }); // packages/ag-charts-core/src/utils/validation.ts function validate(options, optionsDefs, path = "") { if (!isObject(options)) { return { valid: null, errors: [{ path, value: options, message: validateMessage(path, options, "an object") }] }; } const optionsKeys = new Set(Object.keys(options)); const errors = []; const valid = {}; function extendPath(key) { if (isArray(optionsDefs)) { return `${path}[${key}]`; } return path ? `${path}.${key}` : key; } for (const [key, validatorOrDefs] of Object.entries(optionsDefs)) { optionsKeys.delete(key); const value = options[key]; if (!validatorOrDefs[requiredSymbol] && typeof value === "undefined") continue; if (isFunction(validatorOrDefs)) { if (validatorOrDefs(value, options)) { valid[key] = value; } else { errors.push({ key, path, value, message: validateMessage(extendPath(key), value, validatorOrDefs) }); } } else { const nestedResult = validate(value, validatorOrDefs, extendPath(key)); valid[key] = nestedResult.valid; errors.push(...nestedResult.errors); } } for (const key of optionsKeys) { errors.push({ key, path, unknown: true, message: `Unknown option \`${extendPath(key)}\`, ignoring.` }); } return { valid, errors }; } function validateMessage(path, value, validatorOrDefs) { const description = isString(validatorOrDefs) ? validatorOrDefs : validatorOrDefs[descriptionSymbol]; const expecting = description ? `; expecting ${description}` : ""; const prefix = path ? `Option \`${path}\`` : "Value"; return `${prefix} cannot be set to \`${stringifyValue(value)}\`${expecting}, ignoring.`; } function attachDescription(validator, description) { return Object.assign((value, context) => validator(value, context), { [descriptionSymbol]: description }); } function union(...allowed) { if (isObject(allowed[0])) { allowed = Object.values(allowed[0]); } const keywords = joinFormatted(allowed, "or", (value) => `'${value}'`, 6); return attachDescription((value) => allowed.includes(value), `a keyword such as ${keywords}`); } var descriptionSymbol, requiredSymbol, and, or, array, boolean, callback, number, object, string, date, numberMin, numberRange, positiveNumber, ratio, isComparable, lessThan, arrayOf; var init_validation = __esm({ "packages/ag-charts-core/src/utils/validation.ts"() { "use strict"; init_strings(); init_typeGuards(); descriptionSymbol = Symbol("description"); requiredSymbol = Symbol("required"); and = (...validators) => attachDescription( (value, context) => validators.every((validator) => validator(value, context)), validators.map((v) => v[descriptionSymbol]).filter(Boolean).join(" and ") ); or = (...validators) => attachDescription( (value, context) => validators.some((validator) => validator(value, context)), validators.map((v) => v[descriptionSymbol]).filter(Boolean).join(" or ") ); array = attachDescription(isArray, "an array"); boolean = attachDescription(isBoolean, "a boolean"); callback = attachDescription(isFunction, "a function"); number = attachDescription(isFiniteNumber, "a number"); object = attachDescription(isObject, "an object"); string = attachDescription(isString, "a string"); date = attachDescription( (value) => isDate(value) || (isFiniteNumber(value) || isString(value)) && isValidDate(new Date(value)), "a date" ); numberMin = (min, inclusive = true) => attachDescription( (value) => isFiniteNumber(value) && (value > min || inclusive && value === min), `a number greater than ${inclusive ? "or equal to " : ""}${min}` ); numberRange = (min, max) => attachDescription( (value) => isFiniteNumber(value) && value >= min && value <= max, `a number between ${min} and ${max} inclusive` ); positiveNumber = numberMin(0); ratio = numberRange(0, 1); isComparable = (value) => isFiniteNumber(value) || isValidDate(value); lessThan = (otherField) => attachDescription( (value, context) => !isComparable(value) || !isComparable(context[otherField]) || value < context[otherField], `to be less than ${otherField}` ); arrayOf = (validator, description) => attachDescription( (value, context) => isArray(value) && value.every((v) => validator(v, context)), description ?? `${validator[descriptionSymbol]} array` ); } }); // packages/ag-charts-core/src/main.ts var init_main = __esm({ "packages/ag-charts-core/src/main.ts"() { "use strict"; init_globals(); init_globalTypes(); init_moduleDefinition(); init_eventEmitter(); init_arrays(); init_binarySearch(); init_diff(); init_functions(); init_iterators(); init_strings(); init_typeGuards(); init_validation(); } }); // packages/ag-charts-community/src/core/globalsProxy.ts 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(window2) { verifiedGlobals.window = window2; } var verifiedGlobals; var init_globalsProxy = __esm({ "packages/ag-charts-community/src/core/globalsProxy.ts"() { "use strict"; verifiedGlobals = {}; if (typeof window !== "undefined") { verifiedGlobals.window = window; } else if (typeof global !== "undefined") { verifiedGlobals.window = global.window; } if (typeof document !== "undefined") { verifiedGlobals.document = document; } else if (typeof global !== "undefined") { verifiedGlobals.document = global.document; } } }); // packages/ag-charts-community/src/core/domElements.ts function createElement(tagName, className, style) { const element2 = getDocument().createElement(tagName); if (typeof className === "object") { style = className; className = void 0; } if (className) { for (const name of className.split(" ")) { element2.classList.add(name); } } if (style) { Object.assign(element2.style, style); } return element2; } function createSvgElement(elementName) { return getDocument().createElementNS("http://www.w3.org/2000/svg", elementName); } var init_domElements = __esm({ "packages/ag-charts-community/src/core/domElements.ts"() { "use strict"; init_globalsProxy(); } }); // packages/ag-charts-community/src/core/domDownload.ts function downloadUrl(dataUrl, fileName) { const body = getDocument("body"); const element2 = createElement("a", { display: "none" }); element2.href = dataUrl; element2.download = fileName; body.appendChild(element2); element2.click(); setTimeout(() => body.removeChild(element2)); } var init_domDownload = __esm({ "packages/ag-charts-community/src/core/domDownload.ts"() { "use strict"; init_domElements(); init_globalsProxy(); } }); // packages/ag-charts-community/src/core/index.ts var init_core = __esm({ "packages/ag-charts-community/src/core/index.ts"() { "use strict"; init_domDownload(); init_domElements(); init_globalsProxy(); } }); // packages/ag-charts-community/src/util/id.ts function resetIds() { ID_MAP.clear(); } function createId(instance) { const constructor = instance.constructor; const className = Object.hasOwn(constructor, "className") ? constructor.className : constructor.name; if (!className) { throw new Error(`The ${constructor} is missing the 'className' property.`); } const nextId = (ID_MAP.get(className) ?? 0) + 1; ID_MAP.set(className, nextId); return `${className}-${nextId}`; } function generateUUID() { return crypto.randomUUID?.() ?? generateUUIDv4(); } function generateUUIDv4() { const uuidArray = new Uint8Array(16); crypto.getRandomValues(uuidArray); uuidArray[6] = uuidArray[6] & 15 | 64; uuidArray[8] = uuidArray[8] & 63 | 128; let uuid = ""; for (let i = 0; i < uuidArray.length; i++) { if (i === 4 || i === 6 || i === 8 || i === 10) { uuid += "-"; } uuid += uuidArray[i].toString(16).padStart(2, "0"); } return uuid; } var ID_MAP; var init_id = __esm({ "packages/ag-charts-community/src/util/id.ts"() { "use strict"; ID_MAP = /* @__PURE__ */ new Map(); } }); // packages/ag-charts-community/src/util/bboxinterface.ts function containsPoint(bbox, x, y) { return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; } function isEmpty(bbox) { return bbox == null || bbox.height === 0 || bbox.width === 0 || isNaN(bbox.height) || isNaN(bbox.width); } function normalize(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 }; } var BBoxValues; var init_bboxinterface = __esm({ "packages/ag-charts-community/src/util/bboxinterface.ts"() { "use strict"; BBoxValues = { containsPoint, isEmpty, normalize }; } }); // packages/ag-charts-community/src/util/interpolating.ts var interpolate, isInterpolating; var init_interpolating = __esm({ "packages/ag-charts-community/src/util/interpolating.ts"() { "use strict"; interpolate = Symbol("interpolate"); isInterpolating = (x) => x[interpolate] != null; } }); // packages/ag-charts-community/src/util/nearest.ts function nearestSquared(x, y, objects, maxDistanceSquared = Infinity) { const result = { nearest: void 0, distanceSquared: maxDistanceSquared }; for (const obj of objects) { const thisDistance = obj.distanceSquared(x, y); if (thisDistance === 0) { return { nearest: obj, distanceSquared: 0 }; } else if (thisDistance < result.distanceSquared) { result.nearest = obj; result.distanceSquared = thisDistance; } } return result; } function nearestSquaredInContainer(x, y, container, maxDistanceSquared = Infinity) { const { x: tx = x, y: ty = y } = container.transformPoint?.(x, y) ?? {}; const result = { nearest: void 0, distanceSquared: maxDistanceSquared }; for (const child of container.children) { const { nearest, distanceSquared: distanceSquared2 } = child.nearestSquared(tx, ty, result.distanceSquared); if (distanceSquared2 === 0) { return { nearest, distanceSquared: distanceSquared2 }; } else if (distanceSquared2 < result.distanceSquared) { result.nearest = nearest; result.distanceSquared = distanceSquared2; } } return result; } var init_nearest = __esm({ "packages/ag-charts-community/src/util/nearest.ts"() { "use strict"; } }); // packages/ag-charts-community/src/util/number.ts function clamp(min, value, max) { return Math.min(max, Math.max(min, value)); } function clampArray(value, array2) { const [min, max] = findMinMax(array2); return clamp(min, value, max); } function findMinMax(array2) { if (array2.length === 0) return []; const result = [Infinity, -Infinity]; for (const val of array2) { if (val < result[0]) result[0] = val; if (val > result[1]) result[1] = val; } return result; } function findRangeExtent(array2) { const [min, max] = findMinMax(array2); return max - min; } function inRange(value, range4, epsilon2 = 1e-10) { return value >= range4[0] - epsilon2 && value <= range4[1] + epsilon2; } function isNumberEqual(a, b, epsilon2 = 1e-10) { return a === b || Math.abs(a - b) < epsilon2; } function isNegative(value) { return Math.sign(value) === -1 || Object.is(value, -0); } function isInteger(value) { return value % 1 === 0; } function round(value, decimals = 2) { const base = 10 ** decimals; return Math.round(value * base) / base; } function mod(n, m) { return Math.floor(n % m + (n < 0 ? 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); } var init_number = __esm({ "packages/ag-charts-community/src/util/number.ts"() { "use strict"; } }); // packages/ag-charts-community/src/scene/bbox.ts var _BBox, BBox; var init_bbox = __esm({ "packages/ag-charts-community/src/scene/bbox.ts"() { "use strict"; init_bboxinterface(); init_interpolating(); init_nearest(); init_number(); _BBox = class _BBox { constructor(x, y, width2, height2) { this.x = x; this.y = y; this.width = width2; this.height = height2; } static fromDOMRect({ x, y, width: width2, height: height2 }) { return new _BBox(x, y, width2, height2); } static merge(boxes) { let left = Infinity; let top = Infinity; let right = -Infinity; let bottom = -Infinity; for (const box of boxes) { if (box.x < left) { left = box.x; } if (box.y < top) { top = box.y; } if (box.x + box.width > right) { right = box.x + box.width; } if (box.y + box.height > bottom) { bottom = box.y + box.height; } } return new _BBox(left, top, right - left, bottom - top); } static nearestBox(x, y, boxes) { return nearestSquared(x, y, boxes); } toDOMRect() { return { x: this.x, y: this.y, width: this.width, height: this.height, top: this.y, left: this.x, right: this.x + this.width, bottom: this.y + this.height, toJSON() { return {}; } }; } clone() { const { x, y, width: width2, height: height2 } = this; return new _BBox(x, y, width2, height2); } equals(other) { return this.x === other.x && this.y === other.y && this.width === other.width && this.height === other.height; } containsPoint(x, y) { return BBoxValues.containsPoint(this, x, y); } intersection(other) { if (!this.collidesBBox(other)) return; const newX1 = clamp(other.x, this.x, other.x + other.width); const newY1 = clamp(other.y, this.y, other.y + other.height); const newX2 = clamp(other.x, this.x + this.width, other.x + other.width); const newY2 = clamp(other.y, this.y + this.height, other.y + other.height); return new _BBox(newX1, newY1, newX2 - newX1, newY2 - newY1); } collidesBBox(other) { return this.x < other.x + other.width && this.x + this.width > other.x && this.y < other.y + other.height && this.y + this.height > other.y; } computeCenter() { return { x: this.x + this.width / 2, y: this.y + this.height / 2 }; } isFinite() { return Number.isFinite(this.x) && Number.isFinite(this.y) && Number.isFinite(this.width) && Number.isFinite(this.height); } distanceSquared(x, y) { if (this.containsPoint(x, y)) { return 0; } const dx2 = x - clamp(this.x, x, this.x + this.width); const dy2 = y - clamp(this.y, y, this.y + this.height); return dx2 * dx2 + dy2 * dy2; } shrink(amount, position) { if (typeof amount === "number") { this.applyMargin(amount, position); } else { for (const [key, value] of Object.entries(amount)) { this.applyMargin(value, key); } } if (this.width < 0) { this.width = 0; } if (this.height < 0) { this.height = 0; } return this; } grow(amount, position) { if (typeof amount === "number") { this.applyMargin(-amount, position); } else { for (const [key, value] of Object.entries(amount)) { this.applyMargin(-value, key); } } return this; } applyMargin(value, position) { switch (position) { case "top": this.y += value; case "bottom": this.height -= value; break; case "left": this.x += value; case "right": this.width -= value; break; case "vertical": this.y += value; this.height -= value * 2; break; case "horizontal": this.x += value; this.width -= value * 2; break; case void 0: this.x += value; this.y += value; this.width -= value * 2; this.height -= value * 2; break; } } translate(x, y) { this.x += x; this.y += y; return this; } [interpolate](other, d) { return new _BBox( this.x * (1 - d) + other.x * d, this.y * (1 - d) + other.y * d, this.width * (1 - d) + other.width * d, this.height * (1 - d) + other.height * d ); } }; _BBox.zero = Object.freeze(new _BBox(0, 0, 0, 0)); _BBox.NaN = Object.freeze(new _BBox(NaN, NaN, NaN, NaN)); BBox = _BBox; } }); // packages/ag-charts-community/src/scene/changeDetectable.ts function SceneChangeDetection(opts) { return function(target, key) { const privateKey = `__${key}`; if (target[key]) { return; } prepareGetSet(target, key, privateKey, opts); }; } function prepareGetSet(target, key, privateKey, opts) { const { type = "normal", changeCb, convertor, checkDirtyOnAssignment = false } = opts ?? {}; const requiredOpts = { type, changeCb, checkDirtyOnAssignment, convertor }; let setter; switch (type) { case "normal": setter = buildNormalSetter(privateKey, requiredOpts); break; case "transform": setter = buildTransformSetter(privateKey); break; case "path": setter = buildPathSetter(privateKey); break; } setter = buildCheckDirtyChain( buildChangeCallbackChain(buildConvertorChain(setter, requiredOpts), requiredOpts), requiredOpts ); const getter = function() { return this[privateKey]; }; Object.defineProperty(target, key, { set: setter, get: getter, enumerable: true, configurable: true }); } function buildConvertorChain(setterFn, opts) { const { convertor } = opts; if (convertor) { return function(value) { setterFn.call(this, convertor(value)); }; } return setterFn; } function buildChangeCallbackChain(setterFn, opts) { const { changeCb } = opts; if (changeCb) { return function(value) { const change = setterFn.call(this, value); if (change !== NO_CHANGE) { changeCb.call(this, this); } return change; }; } return setterFn; } function buildCheckDirtyChain(setterFn, opts) { const { checkDirtyOnAssignment } = opts; if (checkDirtyOnAssignment) { return function(value) { const change = setterFn.call(this, value); if (value?._dirty === true) { this.markDirty(); } return change; }; } return setterFn; } function buildNormalSetter(privateKey, opts) { const { changeCb } = opts; return function(value) { const oldValue = this[privateKey]; if (value !== oldValue) { this[privateKey] = value; this.markDirty(); changeCb?.(this); return value; } return NO_CHANGE; }; } function buildTransformSetter(privateKey) { return function(value) { const oldValue = this[privateKey]; if (value !== oldValue) { this[privateKey] = value; this.markDirtyTransform(); return value; } return NO_CHANGE; }; } function buildPathSetter(privateKey) { return function(value) { const oldValue = this[privateKey]; if (value !== oldValue) { this[privateKey] = value; if (!this._dirtyPath) { this._dirtyPath = true; this.markDirty(); } return value; } return NO_CHANGE; }; } var NO_CHANGE; var init_changeDetectable = __esm({ "packages/ag-charts-community/src/scene/changeDetectable.ts"() { "use strict"; NO_CHANGE = Symbol("no-change"); } }); // packages/ag-charts-community/src/scene/node.ts var PointerEvents, _Node, Node; var init_node = __esm({ "packages/ag-charts-community/src/scene/node.ts"() { "use strict"; init_main(); init_core(); init_id(); init_changeDetectable(); PointerEvents = /* @__PURE__ */ ((PointerEvents13) => { PointerEvents13[PointerEvents13["All"] = 0] = "All"; PointerEvents13[PointerEvents13["None"] = 1] = "None"; return PointerEvents13; })(PointerEvents || {}); _Node = class _Node { constructor(options) { /** Unique number to allow creation order to be easily determined. */ this.serialNumber = _Node._nextSerialNumber++; this.childNodeCounts = { groups: 0, nonGroups: 0, thisComplexity: 0, complexity: 0 }; /** Unique node ID in the form `ClassName-NaturalNumber`. */ this.id = createId(this); this.pointerEvents = 0 /* All */; this._dirty = true; this.dirtyZIndex = false; /** * To simplify the type system (especially in Selections) we don't have the `Parent` node * (one that has children). Instead, we mimic HTML DOM, where any node can have children. * But we still need to distinguish regular leaf nodes from container leafs somehow. */ this.isContainerNode = false; this.visible = true; this.zIndex = 0; this.name = options?.name; this.tag = options?.tag ?? NaN; this.zIndex = options?.zIndex ?? 0; } static toSVG(node, width2, height2) { const svg = node?.toSVG(); if (svg == null || !svg.elements.length && !svg.defs?.length) return; const root = createSvgElement("svg"); root.setAttribute("width", String(width2)); root.setAttribute("height", String(height2)); root.setAttribute("viewBox", `0 0 ${width2} ${height2}`); if (svg.defs?.length) { const defs = createSvgElement("defs"); defs.append(...svg.defs); root.append(defs); } root.append(...svg.elements); return root.outerHTML; } static *extractBBoxes(nodes, skipInvisible) { for (const n of nodes) { if (!skipInvisible || n.visible && !n.transitionOut) { const bbox = n.getBBox(); if (bbox) yield bbox; } } } /** * Some arbitrary data bound to the node. */ get datum() { return this._datum ?? this.parentNode?.datum; } set datum(datum) { if (this._datum !== datum) { this._previousDatum = this._datum; this._datum = datum; } } get previousDatum() { return this._previousDatum; } get layerManager() { return this._layerManager; } get dirty() { return this._dirty; } /** Perform any pre-rendering initialization. */ preRender(renderCtx, thisComplexity = 1) { this.childNodeCounts.groups = 0; this.childNodeCounts.nonGroups = 1; this.childNodeCounts.complexity = thisComplexity; this.childNodeCounts.thisComplexity = thisComplexity; for (const child of this.children()) { const childCounts = child.preRender(renderCtx); this.childNodeCounts.groups += childCounts.groups; this.childNodeCounts.nonGroups += childCounts.nonGroups; this.childNodeCounts.complexity += childCounts.complexity; } return this.childNodeCounts; } render(renderCtx) { const { stats } = renderCtx; this._dirty = false; if (renderCtx.debugNodeSearch) { const idOrName = this.name ?? this.id; if (renderCtx.debugNodeSearch.some((v) => typeof v === "string" ? v === idOrName : v.test(idOrName))) { renderCtx.debugNodes[this.name ?? this.id] = this; } } if (stats) { stats.nodesRendered++; stats.opsPerformed += this.childNodeCounts.thisComplexity; } } _setLayerManager(value) { this._layerManager = value; this._debug = value?.debug; for (const child of this.children()) { child._setLayerManager(value); } } sortChildren(compareFn) { this.dirtyZIndex = false; if (!this.childNodes) return; const sortedChildren = [...this.childNodes].sort(compareFn); this.childNodes.clear(); for (const child of sortedChildren) { this.childNodes.add(child); } } *traverseUp(includeSelf) { let node = this; if (includeSelf) { yield node; } while (node = node.parentNode) { yield node; } } *children() { if (!this.childNodes) return; for (const child of this.childNodes) { yield child; } } *descendants() { for (const child of this.children()) { yield child; yield* child.descendants(); } } /** * Checks if the node is a leaf (has no children). */ isLeaf() { return !this.childNodes?.size; } /** * Checks if the node is the root (has no parent). */ isRoot() { return !this.parentNode; } /** * Appends one or more new node instances to this parent. * If one needs to: * - move a child to the end of the list of children * - move a child from one parent to another (including parents in other scenes) * one should use the {@link insertBefore} method instead. * @param nodes A node or nodes to append. */ append(nodes) { this.childNodes ?? (this.childNodes = /* @__PURE__ */ new Set()); for (const node of toIterable(nodes)) { node.parentNode?.removeChild(node); this.childNodes.add(node); node.parentNode = this; node._setLayerManager(this.layerManager); } this.invalidateCachedBBox(); this.dirtyZIndex = true; this.markDirty(); } appendChild(node) { this.append(node); return node; } removeChild(node) { if (!this.childNodes?.delete(node)) { return false; } delete node.parentNode; node._setLayerManager(); this.invalidateCachedBBox(); this.dirtyZIndex = true; this.markDirty(); return true; } remove() { return this.parentNode?.removeChild(this) ?? false; } clear() { for (const child of this.children()) { delete child.parentNode; child._setLayerManager(); } this.childNodes?.clear(); this.invalidateCachedBBox(); } destroy() { this.parentNode?.removeChild(this); } setProperties(styles, pickKeys) { if (pickKeys) { for (const key of pickKeys) { this[key] = styles[key]; } } else { Object.assign(this, styles); } return this; } containsPoint(_x, _y) { return false; } /** * Hit testing method. * Recursively checks if the given point is inside this node or any of its children. * Returns the first matching node or `undefined`. * Nodes that render later (show on top) are hit tested first. */ pickNode(x, y, _localCoords = false) { if (!this.visible || this.pointerEvents === 1 /* None */ || !this.containsPoint(x, y)) { return; } const children = [...this.children()]; if (children.length > 1e3) { for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; const containsPoint3 = child.containsPoint(x, y); const hit = containsPoint3 ? child.pickNode(x, y) : void 0; if (hit) { return hit; } } } else if (children.length) { for (let i = children.length - 1; i >= 0; i--) { const hit = children[i].pickNode(x, y); if (hit) { return hit; } } } else if (!this.isContainerNode) { return this; } } invalidateCachedBBox() { if (this.cachedBBox != null) { this.cachedBBox = void 0; this.parentNode?.invalidateCachedBBox(); } } getBBox() { if (this.cachedBBox == null) { this.cachedBBox = Object.freeze(this.computeBBox()); } return this.cachedBBox; } computeBBox() { return; } markDirty() { const { _dirty } = this; const noParentCachedBBox = this.cachedBBox == null; if (noParentCachedBBox && _dirty) return; this.invalidateCachedBBox(); this._dirty = true; if (this.parentNode) { this.parentNode.markDirty(); } } markClean() { if (!this._dirty) return; this._dirty = false; for (const child of this.children()) { child.markClean(); } } onZIndexChange() { const { parentNode } = this; if (parentNode) { parentNode.dirtyZIndex = true; } } toSVG() { return; } }; _Node._nextSerialNumber = 0; __decorateClass([ SceneChangeDetection() ], _Node.prototype, "visible", 2); __decorateClass([ SceneChangeDetection({ changeCb: (target) => target.onZIndexChange() }) ], _Node.prototype, "zIndex", 2); Node = _Node; } }); // packages/ag-charts-community/src/util/color.ts var lerp, srgbToLinear, srgbFromLinear, _Color, Color; var init_color = __esm({ "packages/ag-charts-community/src/util/color.ts"() { "use strict"; init_number(); lerp = (x, y, t) => x * (1 - t) + y * t; srgbToLinear = (value) => { const sign = value < 0 ? -1 : 1; const abs = Math.abs(value); if (abs <= 0.04045) return value / 12.92; return sign * ((abs + 0.055) / 1.055) ** 2.4; }; srgbFromLinear = (value) => { const sign = value < 0 ? -1 : 1; const abs = Math.abs(value); if (abs > 31308e-7) { return sign * (1.055 * abs ** (1 / 2.4) - 0.055); } return 12.92 * value; }; _Color = class _Color { /** * Every color component should be in the [0, 1] range. * Some easing functions (such as elastic easing) can overshoot the target value by some amount. * So, when animating colors, if the source or target color components are already near * or at the edge of the allowed [0, 1] range, it is possible for the intermediate color * component value to end up outside of that range mid-animation. For this reason the constructor * performs range checking/constraining. * @param r Red component. * @param g Green component. * @param b Blue component. * @param a Alpha (opacity) component. */ constructor(r, g, b, a = 1) { this.r = clamp(0, r || 0, 1); this.g = clamp(0, g || 0, 1); this.b = clamp(0, b || 0, 1); this.a = clamp(0, a || 0, 1); } /** * A color string can be in one of the following formats to be valid: * - #rgb * - #rrggbb * - rgb(r, g, b) * - rgba(r, g, b, a) * - CSS color name such as 'white', 'orange', 'cyan', etc. */ static validColorString(str) { if (str.indexOf("#") >= 0) { return !!_Color.parseHex(str); } if (str.indexOf("rgb") >= 0) { return !!_Color.stringToRgba(str); } return _Color.nameToHex.has(str.toLowerCase()); } /** * The given string can be in one of the following formats: * - #rgb * - #rrggbb * - rgb(r, g, b) * - rgba(r, g, b, a) * - CSS color name such as 'white', 'orange', 'cyan', etc. * @param str */ static fromString(str) { if (str.indexOf("#") >= 0) { return _Color.fromHexString(str); } const hex = _Color.nameToHex.get(str.toLowerCase()); if (hex) { return _Color.fromHexString(hex); } if (str.indexOf("rgb") >= 0) { return _Color.fromRgbaString(str); } throw new Error(`Invalid color string: '${str}'`); } // See https://drafts.csswg.org/css-color/#hex-notation static parseHex(input) { input = input.replace(/ /g, "").slice(1); let parts; switch (input.length) { case 6: case 8: parts = []; for (let i = 0; i < input.length; i += 2) { parts.push(parseInt(`${input[i]}${input[i + 1]}`, 16)); } break; case 3: case 4: parts = input.split("").map((p) => parseInt(p, 16)).map((p) => p + p * 16); break; } if (parts?.length >= 3 && parts.every((p) => p >= 0)) { if (parts.length === 3) { parts.push(255); } return parts; } } static fromHexString(str) { const values = _Color.parseHex(str); if (values) { const [r, g, b, a] = values; return new _Color(r / 255, g / 255, b / 255, a / 255); } throw new Error(`Malformed hexadecimal color string: '${str}'`); } static stringToRgba(str) { let po = -1; let pc = -1; for (let i = 0; i < str.length; i++) { const c = str[i]; if (po === -1 && c === "(") { po = i; } else if (c === ")") { pc = i; break; } } if (po === -1 || pc === -1) return; const contents = str.substring(po + 1, pc); const parts = contents.split(","); const rgba = []; for (let i = 0; i < parts.length; i++) { const part = parts[i]; let value = parseFloat(part); if (!Number.isFinite(value)) { return; } if (part.indexOf("%") >= 0) { value = clamp(0, value, 100); value /= 100; } else if (i === 3) { value = clamp(0, value, 1); } else { value = clamp(0, value, 255); value /= 255; } rgba.push(value); } return rgba; } static fromRgbaString(str) { const rgba = _Color.stringToRgba(str); if (rgba) { if (rgba.length === 3) { return new _Color(rgba[0], rgba[1], rgba[2]); } else if (rgba.length === 4) { return new _Color(rgba[0], rgba[1], rgba[2], rgba[3]); } } throw new Error(`Malformed rgb/rgba color string: '${str}'`); } static fromArray(arr) { if (arr.length === 4) { return new _Color(arr[0], arr[1], arr[2], arr[3]); } if (arr.length === 3) { return new _Color(arr[0], arr[1], arr[2]); } throw new Error("The given array should contain 3 or 4 color components (numbers)."); } static fromHSB(h, s, b, alpha = 1) { const rgb = _Color.HSBtoRGB(h, s, b); return new _Color(rgb[0], rgb[1], rgb[2], alpha); } static fromHSL(h, s, l, alpha = 1) { const rgb = _Color.HSLtoRGB(h, s, l); return new _Color(rgb[0], rgb[1], rgb[2], alpha); } static fromOKLCH(l, c, h, alpha = 1) { const rgb = _Color.OKLCHtoRGB(l, c, h); return new _Color(rgb[0], rgb[1], rgb[2], alpha); } static padHex(str) { return str.length === 1 ? "0" + str : str; } toHexString() { let hex = "#" + _Color.padHex(Math.round(this.r * 255).toString(16)) + _Color.padHex(Math.round(this.g * 255).toString(16)) + _Color.padHex(Math.round(this.b * 255).toString(16)); if (this.a < 1) { hex += _Color.padHex(Math.round(this.a * 255).toString(16)); } return hex; } toRgbaString(fractionDigits = 3) { const components = [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255)]; const k = Math.pow(10, fractionDigits); if (this.a !== 1) { components.push(Math.round(this.a * k) / k); return `rgba(${components.join(", ")})`; } return `rgb(${components.join(", ")})`; } toString() { if (this.a === 1) { return this.toHexString(); } return this.toRgbaString(); } toHSB() { return _Color.RGBtoHSB(this.r, this.g, this.b); } static RGBtoOKLCH(r, g, b) { const LSRGB0 = srgbToLinear(r); const LSRGB1 = srgbToLinear(g); const LSRGB2 = srgbToLinear(b); const LMS0 = Math.cbrt(0.4122214708 * LSRGB0 + 0.5363325363 * LSRGB1 + 0.0514459929 * LSRGB2); const LMS1 = Math.cbrt(0.2119034982 * LSRGB0 + 0.6806995451 * LSRGB1 + 0.1073969566 * LSRGB2); const LMS2 = Math.cbrt(0.0883024619 * LSRGB0 + 0.2817188376 * LSRGB1 + 0.6299787005 * LSRGB2); const OKLAB0 = 0.2104542553 * LMS0 + 0.793617785 * LMS1 - 0.0040720468 * LMS2; const OKLAB1 = 1.9779984951 * LMS0 - 2.428592205 * LMS1 + 0.4505937099 * LMS2; const OKLAB2 = 0.0259040371 * LMS0 + 0.7827717662 * LMS1 - 0.808675766 * LMS2; const hue = Math.atan2(OKLAB2, OKLAB1) * 180 / Math.PI; const OKLCH0 = OKLAB0; const OKLCH1 = Math.hypot(OKLAB1, OKLAB2); const OKLCH2 = hue >= 0 ? hue : hue + 360; return [OKLCH0, OKLCH1, OKLCH2]; } static OKLCHtoRGB(l, c, h) { const OKLAB0 = l; const OKLAB1 = c * Math.cos(h * Math.PI / 180); const OKLAB2 = c * Math.sin(h * Math.PI / 180); const LMS0 = (OKLAB0 + 0.3963377774 * OKLAB1 + 0.2158037573 * OKLAB2) ** 3; const LMS1 = (OKLAB0 - 0.1055613458 * OKLAB1 - 0.0638541728 * OKLAB2) ** 3; const LMS2 = (OKLAB0 - 0.0894841775 * OKLAB1 - 1.291485548 * OKLAB2) ** 3; const LSRGB0 = 4.0767416621 * LMS0 - 3.3077115913 * LMS1 + 0.2309699292 * LMS2; const LSRGB1 = -1.2684380046 * LMS0 + 2.6097574011 * LMS1 - 0.3413193965 * LMS2; const LSRGB2 = -0.0041960863 * LMS0 - 0.7034186147 * LMS1 + 1.707614701 * LMS2; const SRGB0 = srgbFromLinear(LSRGB0); const SRGB1 = srgbFromLinear(LSRGB1); const SRGB2 = srgbFromLinear(LSRGB2); return [SRGB0, SRGB1, SRGB2]; } static RGBtoHSL(r, g, b) { const min = Math.min(r, g, b); const max = Math.max(r, g, b); const l = (max + min) / 2; let h; let s; if (max === min) { h = 0; s = 0; } else { const delta4 = max - min; s = l > 0.5 ? delta4 / (2 - max - min) : delta4 / (max + min); if (max === r) { h = (g - b) / delta4 + (g < b ? 6 : 0); } else if (max === g) { h = (b - r) / delta4 + 2; } else { h = (r - g) / delta4 + 4; } h *= 360 / 6; } return [h, s, l]; } static HSLtoRGB(h, s, l) { h = (h % 360 + 360) % 360; if (s === 0) { return [l, l, l]; } const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; function hueToRgb(t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; } const r = hueToRgb(h / 360 + 1 / 3); const g = hueToRgb(h / 360); const b = hueToRgb(h / 360 - 1 / 3); return [r, g, b]; } /** * Converts the given RGB triple to an array of HSB (HSV) components. */ static RGBtoHSB(r, g, b) { const min = Math.min(r, g, b); const max = Math.max(r, g, b); const S = max === 0 ? 0 : (max - min) / max; let H = 0; if (min !== max) { const delta4 = max - min; const rc = (max - r) / delta4; const gc = (max - g) / delta4; const bc = (max - b) / delta4; if (r === max) { H = bc - gc; } else if (g === max) { H = 2 + rc - bc; } else { H = 4 + gc - rc; } H /= 6; if (H < 0) { H = H + 1; } } return [H * 360, S, max]; } /** * Converts the given HSB (HSV) triple to an array of RGB components. */ static HSBtoRGB(H, S, B) { H = (H % 360 + 360) % 360 / 360; let r = 0; let g = 0; let b = 0; if (S === 0) { r = g = b = B; } else { const h = (H - Math.floor(H)) * 6; const f = h - Math.floor(h); const p = B * (1 - S); const q = B * (1 - S * f); const t = B * (1 - S * (1 - f)); switch (h >> 0) { case 0: r = B; g = t; b = p; break; case 1: r = q; g = B; b = p; break; case 2: r = p; g = B; b = t; break; case 3: r = p; g = q; b = B; break; case 4: r = t; g = p; b = B; break; case 5: r = B; g = p; b = q; break; } } return [r, g, b]; } static mix(c0, c1, t) { return new _Color(lerp(c0.r, c1.r, t), lerp(c0.g, c1.g, t), lerp(c0.b, c1.b, t), lerp(c0.a, c1.a, t)); } }; /** * CSS Color Module Level 4: * https://drafts.csswg.org/css-color/#named-colors */ _Color.nameToHex = /* @__PURE__ */ new Map([ ["aliceblue", "#F0F8FF"], ["antiquewhite", "#FAEBD7"], ["aqua", "#00FFFF"], ["aquamarine", "#7FFFD4"], ["azure", "#F0FFFF"], ["beige", "#F5F5DC"], ["bisque", "#FFE4C4"], ["black", "#000000"], ["blanchedalmond", "#FFEBCD"], ["blue", "#0000FF"], ["blueviolet", "#8A2BE2"], ["brown", "#A52A2A"], ["burlywood", "#DEB887"], ["cadetblue", "#5F9EA0"], ["chartreuse", "#7FFF00"], ["chocolate", "#D2691E"], ["coral", "#FF7F50"], ["cornflowerblue", "#6495ED"], ["cornsilk", "#FFF8DC"], ["crimson", "#DC143C"], ["cyan", "#00FFFF"], ["darkblue", "#00008B"], ["darkcyan", "#008B8B"], ["darkgoldenrod", "#B8860B"], ["darkgray", "#A9A9A9"], ["darkgreen", "#006400"], ["darkgrey", "#A9A9A9"], ["darkkhaki", "#BDB76B"], ["darkmagenta", "#8B008B"], ["darkolivegreen", "#556B2F"], ["darkorange", "#FF8C00"], ["darkorchid", "#9932CC"], ["darkred", "#8B0000"], ["darksalmon", "#E9967A"], ["darkseagreen", "#8FBC8F"], ["darkslateblue", "#483D8B"], ["darkslategray", "#2F4F4F"], ["darkslategrey", "#2F4F4F"], ["darkturquoise", "#00CED1"], ["darkviolet", "#9400D3"], ["deeppink", "#FF1493"], ["deepskyblue", "#00BFFF"], ["dimgray", "#696969"], ["dimgrey", "#696969"], ["dodgerblue", "#1E90FF"], ["firebrick", "#B22222"], ["floralwhite", "#FFFAF0"], ["forestgreen", "#228B22"], ["fuchsia", "#FF00FF"], ["gainsboro", "#DCDCDC"], ["ghostwhite", "#F8F8FF"], ["gold", "#FFD700"], ["goldenrod", "#DAA520"], ["gray", "#808080"], ["green", "#008000"], ["greenyellow", "#ADFF2F"], ["grey", "#808080"], ["honeydew", "#F0FFF0"], ["hotpink", "#FF69B4"], ["indianred", "#CD5C5C"], ["indigo", "#4B0082"], ["ivory", "#FFFFF0"], ["khaki", "#F0E68C"], ["lavender", "#E6E6FA"], ["lavenderblush", "#FFF0F5"], ["lawngreen", "#7CFC00"], ["lemonchiffon", "#FFFACD"], ["lightblue", "#ADD8E6"], ["lightcoral", "#F08080"], ["lightcyan", "#E0FFFF"], ["lightgoldenrodyellow", "#FAFAD2"], ["lightgray", "#D3D3D3"], ["lightgreen", "#90EE90"], ["lightgrey", "#D3D3D3"], ["lightpink", "#FFB6C1"], ["lightsalmon", "#FFA07A"], ["lightseagreen", "#20B2AA"], ["lightskyblue", "#87CEFA"], ["lightslategray", "#778899"], ["lightslategrey", "#778899"], ["lightsteelblue", "#B0C4DE"], ["lightyellow", "#FFFFE0"], ["lime", "#00FF00"], ["limegreen", "#32CD32"], ["linen", "#FAF0E6"], ["magenta", "#FF00FF"], ["maroon", "#800000"], ["mediumaquamarine", "#66CDAA"], ["mediumblue", "#0000CD"], ["mediumorchid", "#BA55D3"], ["mediumpurple", "#9370DB"], ["mediumseagreen", "#3CB371"], ["mediumslateblue", "#7B68EE"], ["mediumspringgreen", "#00FA9A"], ["mediumturquoise", "#48D1CC"], ["mediumvioletred", "#C71585"], ["midnightblue", "#191970"], ["mintcream", "#F5FFFA"], ["mistyrose", "#FFE4E1"], ["moccasin", "#FFE4B5"], ["navajowhite", "#FFDEAD"], ["navy", "#000080"], ["oldlace", "#FDF5E6"], ["olive", "#808000"], ["olivedrab", "#6B8E23"], ["orange", "#FFA500"], ["orangered", "#FF4500"], ["orchid", "#DA70D6"], ["palegoldenrod", "#EEE8AA"], ["palegreen", "#98FB98"], ["paleturquoise", "#AFEEEE"], ["palevioletred", "#DB7093"], ["papayawhip", "#FFEFD5"], ["peachpuff", "#FFDAB9"], ["peru", "#CD853F"], ["pink", "#FFC0CB"], ["plum", "#DDA0DD"], ["powderblue", "#B0E0E6"], ["purple", "#800080"], ["rebeccapurple", "#663399"], ["red", "#FF0000"], ["rosybrown", "#BC8F8F"], ["royalblue", "#4169E1"], ["saddlebrown", "#8B4513"], ["salmon", "#FA8072"], ["sandybrown", "#F4A460"], ["seagreen", "#2E8B57"], ["seashell", "#FFF5EE"], ["sienna", "#A0522D"], ["silver", "#C0C0C0"], ["skyblue", "#87CEEB"], ["slateblue", "#6A5ACD"], ["slategray", "#708090"], ["slategrey", "#708090"], ["snow", "#FFFAFA"], ["springgreen", "#00FF7F"], ["steelblue", "#4682B4"], ["tan", "#D2B48C"], ["teal", "#008080"], ["thistle", "#D8BFD8"], ["tomato", "#FF6347"], ["transparent", "#00000000"], ["turquoise", "#40E0D0"], ["violet", "#EE82EE"], ["wheat", "#F5DEB3"], ["white", "#FFFFFF"], ["whitesmoke", "#F5F5F5"], ["yellow", "#FFFF00"], ["yellowgreen", "#9ACD32"] ]); Color = _Color; } }); // packages/ag-charts-community/src/util/interpolate.ts function interpolateNumber(a, b) { return (d) => Number(a) * (1 - d) + Number(b) * d; } function interpolateColor(a, b) { if (typeof a === "string") { try { a = Color.fromString(a); } catch { a = Color.fromArray([0, 0, 0]); } } if (typeof b === "string") { try { b = Color.fromString(b); } catch { b = Color.fromArray([0, 0, 0]); } } return (d) => Color.mix(a, b, d).toRgbaString(); } var init_interpolate = __esm({ "packages/ag-charts-community/src/util/interpolate.ts"() { "use strict"; init_color(); } }); // packages/ag-charts-community/src/util/decorator.ts function initialiseConfig(target, propertyKeyOrSymbol) { if (Object.getOwnPropertyDescriptor(target, CONFIG_KEY) == null) { Object.defineProperty(target, CONFIG_KEY, { value: {} }); } const config = target[CONFIG_KEY]; const propertyKey = propertyKeyOrSymbol.toString(); if (typeof config[propertyKey] !== "undefined") { return config[propertyKey]; } const valuesMap = /* @__PURE__ */ new WeakMap(); config[propertyKey] = { setters: [], getters: [], observers: [], valuesMap }; const descriptor = Object.getOwnPropertyDescriptor(target, propertyKeyOrSymbol); const prevSet = descriptor?.set; const prevGet = descriptor?.get; const getter = function() { let value = prevGet ? prevGet.call(this) : valuesMap.get(this); for (const transformFn of config[propertyKey].getters) { value = transformFn(this, propertyKeyOrSymbol, value); if (value === BREAK_TRANSFORM_CHAIN) { return; } } return value; }; const setter = function(value) { const { setters, observers } = config[propertyKey]; let oldValue; if (setters.some((f) => f.length > 2)) { oldValue = prevGet ? prevGet.call(this) : valuesMap.get(this); } for (const transformFn of setters) { value = transformFn(this, propertyKeyOrSymbol, value, oldValue); if (value === BREAK_TRANSFORM_CHAIN) { return; } } if (prevSet) { prevSet.call(this, value); } else { valuesMap.set(this, value); } for (const observerFn of observers) { observerFn(this, value, oldValue); } }; Object.defineProperty(target, propertyKeyOrSymbol, { set: setter, get: getter, enumerable: true, configurable: false }); return config[propertyKey]; } function addTransformToInstanceProperty(setTransform, getTransform, configMetadata) { return (target, propertyKeyOrSymbol) => { const config = initialiseConfig(target, propertyKeyOrSymbol); config.setters.push(setTransform); if (getTransform) { config.getters.unshift(getTransform); } if (configMetadata) { Object.assign(config, configMetadata); } }; } function addObserverToInstanceProperty(setObserver) { return (target, propertyKeyOrSymbol) => { initialiseConfig(target, propertyKeyOrSymbol).observers.push(setObserver); }; } function isDecoratedObject(target) { return typeof target !== "undefined" && CONFIG_KEY in target; } function listDecoratedProperties(target) { const targets = /* @__PURE__ */ new Set(); while (isDecoratedObject(target)) { targets.add(target?.[CONFIG_KEY]); target = Object.getPrototypeOf(target); } return Array.from(targets).flatMap((configMap) => Object.keys(configMap)); } function extractDecoratedProperties(target) { return listDecoratedProperties(target).reduce((result, key) => { result[key] = target[key] ?? null; return result; }, {}); } function extractDecoratedPropertyMetadata(target, propertyKeyOrSymbol) { const propertyKey = propertyKeyOrSymbol.toString(); while (isDecoratedObject(target)) { const config = target[CONFIG_KEY]; if (Object.hasOwn(config, propertyKey)) { return config[propertyKey]; } target = Object.getPrototypeOf(target); } } var BREAK_TRANSFORM_CHAIN, CONFIG_KEY; var init_decorator = __esm({ "packages/ag-charts-community/src/util/decorator.ts"() { "use strict"; BREAK_TRANSFORM_CHAIN = Symbol("BREAK"); CONFIG_KEY = "__decorator_config"; } }); // packages/ag-charts-community/src/util/object.ts function objectsEqual(a, b) { if (Array.isArray(a)) { if (!Array.isArray(b)) return false; if (a.length !== b.length) return false; return a.every((av, i) => objectsEqual(av, b[i])); } else if (isPlainObject(a)) { if (!isPlainObject(b)) return false; return objectsEqualWith(a, b, objectsEqual); } return a === b; } function objectsEqualWith(a, b, cmp2) { for (const key of Object.keys(b)) { if (!(key in a)) return false; } for (const key of Object.keys(a)) { if (!(key in b)) return false; if (!cmp2(a[key], b[key])) return false; } return true; } function mergeDefaults(...sources) { const target = {}; for (const source of sources) { if (!isObject(source)) continue; const keys = isDecoratedObject(source) ? listDecoratedProperties(source) : Object.keys(source); for (const key of keys) { if (isPlainObject(target[key]) && isPlainObject(source[key])) { target[key] = mergeDefaults(target[key], source[key]); } else { target[key] ?? (target[key] = source[key]); } } } return target; } function mergeArrayDefaults(dataArray, ...itemDefaults) { if (itemDefaults && isArray(dataArray)) { return dataArray.map((item) => mergeDefaults(item, ...itemDefaults)); } return dataArray; } function mapValues(object2, mapper) { return Object.entries(object2).reduce( (result, [key, value]) => { result[key] = mapper(value, key, object2); return result; }, {} ); } function without(object2, keys) { const clone2 = { ...object2 }; for (const key of keys) { delete clone2[key]; } return clone2; } function getPath(object2, path) { const pathArray = isArray(path) ? path : path.split("."); return pathArray.reduce((value, pathKey) => value[pathKey], object2); } function setPath(object2, path, newValue) { const pathArray = isArray(path) ? path.slice() : path.split("."); const lastKey = pathArray.pop(); if (pathArray.some((p) => SKIP_JS_BUILTINS.has(p))) return; const lastObject = pathArray.reduce((value, pathKey) => value[pathKey], object2); lastObject[lastKey] = newValue; return lastObject[lastKey]; } function partialAssign(keysToCopy, target, source) { if (source === void 0) { return target; } for (const key of keysToCopy) { const value = source[key]; if (value !== void 0) { target[key] = value; } } return target; } function deepFreeze(obj) { Object.freeze(obj); Object.getOwnPropertyNames(obj).forEach((prop) => { const value = obj[prop]; if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) { deepFreeze(value); } }); return obj; } var SKIP_JS_BUILTINS; var init_object = __esm({ "packages/ag-charts-community/src/util/object.ts"() { "use strict"; init_main(); init_decorator(); SKIP_JS_BUILTINS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]); } }); // packages/ag-charts-community/src/motion/easing.ts var easing_exports = {}; __export(easing_exports, { easeIn: () => easeIn, easeInOut: () => easeInOut, easeInOutQuad: () => easeInOutQuad, easeInQuad: () => easeInQuad, easeOut: () => easeOut, easeOutQuad: () => easeOutQuad, inverseEaseOut: () => inverseEaseOut, linear: () => linear }); var linear, easeIn, easeOut, easeInOut, easeInQuad, easeOutQuad, easeInOutQuad, inverseEaseOut; var init_easing = __esm({ "packages/ag-charts-community/src/motion/easing.ts"() { "use strict"; linear = (n) => n; easeIn = (n) => 1 - Math.cos(n * Math.PI / 2); easeOut = (n) => Math.sin(n * Math.PI / 2); easeInOut = (n) => -(Math.cos(n * Math.PI) - 1) / 2; easeInQuad = (n) => n * n; easeOutQuad = (n) => 1 - (1 - n) ** 2; easeInOutQuad = (n) => n < 0.5 ? 2 * n * n : 1 - (-2 * n + 2) ** 2 / 2; inverseEaseOut = (x) => 2 * Math.asin(x) / Math.PI; } }); // packages/ag-charts-community/src/motion/animation.ts function isNodeArray(array2) { return array2.every((n) => n instanceof Node); } function deconstructSelectionsOrNodes(selectionsOrNodes) { return isNodeArray(selectionsOrNodes) ? { nodes: selectionsOrNodes, selections: [] } : { nodes: [], selections: selectionsOrNodes }; } function animationValuesEqual(a, b) { if (a === b) { return true; } else if (Array.isArray(a) && Array.isArray(b)) { return a.length === b.length && a.every((v, i) => animationValuesEqual(v, b[i])); } else if (isInterpolating(a) && isInterpolating(b)) { return a.equals(b); } else if (isPlainObject(a) && isPlainObject(b)) { return objectsEqualWith(a, b, animationValuesEqual); } return false; } var QUICK_TRANSITION, PHASE_ORDER, PHASE_METADATA, RepeatType, Animation; var init_animation = __esm({ "packages/ag-charts-community/src/motion/animation.ts"() { "use strict"; init_main(); init_node(); init_interpolate(); init_interpolating(); init_number(); init_object(); init_easing(); QUICK_TRANSITION = 0.2; PHASE_ORDER = ["initial", "remove", "update", "add", "trailing", "end", "none"]; PHASE_METADATA = { initial: { animationDuration: 1, animationDelay: 0 }, add: { animationDuration: 0.25, animationDelay: 0.75 }, remove: { animationDuration: 0.25, animationDelay: 0 }, update: { animationDuration: 0.5, animationDelay: 0.25 }, trailing: { animationDuration: QUICK_TRANSITION, animationDelay: 1, skipIfNoEarlierAnimations: true }, end: { animationDelay: 1 + QUICK_TRANSITION, animationDuration: 0, skipIfNoEarlierAnimations: true }, none: { animationDuration: 0, animationDelay: 0 } }; RepeatType = /* @__PURE__ */ ((RepeatType2) => { RepeatType2["Loop"] = "loop"; RepeatType2["Reverse"] = "reverse"; return RepeatType2; })(RepeatType || {}); Animation = class { constructor(opts) { this.isComplete = false; this.elapsed = 0; this.iteration = 0; this.isPlaying = false; this.isReverse = false; this.id = opts.id; this.groupId = opts.groupId; this.autoplay = opts.autoplay ?? true; this.ease = opts.ease ?? linear; this.phase = opts.phase; const durationProportion = opts.duration ?? PHASE_METADATA[this.phase].animationDuration; this.duration = durationProportion * opts.defaultDuration; this.delay = (opts.delay ?? 0) * opts.defaultDuration; this.onComplete = opts.onComplete; this.onPlay = opts.onPlay; this.onStop = opts.onStop; this.onUpdate = opts.onUpdate; this.interpolate = this.createInterpolator(opts.from, opts.to); this.from = opts.from; if (opts.skip === true) { this.onUpdate?.(opts.to, false, this); this.onStop?.(this); this.onComplete?.(this); this.isComplete = true; } if (opts.collapsable !== false) { this.duration = this.checkCollapse(opts, this.duration); } } checkCollapse(opts, calculatedDuration) { return animationValuesEqual(opts.from, opts.to) ? 0 : calculatedDuration; } play(initialUpdate = false) { if (this.isPlaying || this.isComplete) return; this.isPlaying = true; this.onPlay?.(this); if (!this.autoplay) return; this.autoplay = false; if (!initialUpdate) return; this.onUpdate?.(this.from, true, this); } stop() { this.isPlaying = false; if (!this.isComplete) { this.isComplete = true; this.onStop?.(this); } } update(time2) { if (this.isComplete) return time2; if (!this.isPlaying && this.autoplay) { this.play(true); } const previousElapsed = this.elapsed; this.elapsed += time2; if (this.delay > this.elapsed) return 0; const value = this.interpolate(this.isReverse ? 1 - this.delta : this.delta); this.onUpdate?.(value, false, this); const totalDuration = this.delay + this.duration; if (this.elapsed >= totalDuration) { this.stop(); this.isComplete = true; this.onComplete?.(this); return time2 - (totalDuration - previousElapsed); } return 0; } get delta() { return this.ease(clamp(0, (this.elapsed - this.delay) / this.duration, 1)); } createInterpolator(from3, to) { if (typeof to !== "object" || isInterpolating(to)) { return this.interpolateValue(from3, to); } const interpolatorEntries = []; for (const key of Object.keys(to)) { const interpolator = this.interpolateValue(from3[key], to[key]); if (interpolator != null) { interpolatorEntries.push([key, interpolator]); } } return (d) => { const result = {}; for (const [key, interpolator] of interpolatorEntries) { result[key] = interpolator(d); } return result; }; } interpolateValue(a, b) { if (a == null || b == null) { return; } else if (isInterpolating(a)) { return (d) => a[interpolate](b, d); } try { switch (typeof a) { case "number": return interpolateNumber(a, b); case "string": return interpolateColor(a, b); case "boolean": if (a === b) { return () => a; } break; } } catch { } throw new Error(`Unable to interpolate values: ${a}, ${b}`); } }; } }); // packages/ag-charts-community/src/motion/fromToMotion.ts var fromToMotion_exports = {}; __export(fromToMotion_exports, { NODE_UPDATE_STATE_TO_PHASE_MAPPING: () => NODE_UPDATE_STATE_TO_PHASE_MAPPING, fromToMotion: () => fromToMotion, staticFromToMotion: () => staticFromToMotion }); function fromToMotion(groupId, subId, animationManager, selectionsOrNodes, fns, getDatumId, diff8) { const { fromFn, toFn, applyFn = (node, props) => node.setProperties(props) } = fns; const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes); const processNodes = (liveNodes, subNodes) => { let prevFromProps; let liveNodeIndex = 0; let nodeIndex = 0; for (const node of subNodes) { const isLive = liveNodes[liveNodeIndex] === node; const ctx = { last: nodeIndex >= subNodes.length - 1, lastLive: liveNodeIndex >= liveNodes.length - 1, prev: subNodes[nodeIndex - 1], prevFromProps, prevLive: liveNodes[liveNodeIndex - 1], next: subNodes[nodeIndex + 1], nextLive: liveNodes[liveNodeIndex + (isLive ? 1 : 0)] }; const animationId = `${groupId}_${subId}_${node.id}`; animationManager.stopByAnimationId(animationId); let status = "unknown"; if (!isLive) { status = "removed"; } else if (getDatumId && diff8) { status = calculateStatus(node, node.datum, getDatumId, diff8); } node.transitionOut = status === "removed"; const { phase, start: start2, finish, delay, duration, ...from3 } = fromFn(node, node.datum, status, ctx); const { phase: toPhase, start: toStart, finish: toFinish, delay: toDelay, duration: toDuration, ...to } = toFn(node, node.datum, status, ctx); const collapsable = finish == null; animationManager.animate({ id: animationId, groupId, phase: phase ?? toPhase ?? "update", duration: duration ?? toDuration, delay: delay ?? toDelay, from: from3, to, ease: easeOut, collapsable, onPlay: () => { const startProps = { ...start2, ...toStart, ...from3 }; applyFn(node, startProps, "start"); }, onUpdate(props) { applyFn(node, props, "update"); }, onStop: () => { const endProps = { ...start2, ...toStart, ...from3, ...to, ...finish, ...toFinish }; applyFn(node, endProps, "end"); } }); if (isLive) { liveNodeIndex++; } nodeIndex++; prevFromProps = from3; } }; let selectionIndex = 0; for (const selection of selections) { const selectionNodes = selection.nodes(); const liveNodes = selectionNodes.filter((n) => !selection.isGarbage(n)); processNodes(liveNodes, selectionNodes); animationManager.animate({ id: `${groupId}_${subId}_selection_${selectionIndex}`, groupId, phase: "end", from: 0, to: 1, ease: easeOut, onStop() { selection.cleanup(); } }); selectionIndex++; } processNodes(nodes, nodes); } function staticFromToMotion(groupId, subId, animationManager, selectionsOrNodes, from3, to, extraOpts) { const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes); const { start: start2, finish, phase } = extraOpts; animationManager.animate({ id: `${groupId}_${subId}`, groupId, phase: phase ?? "update", from: from3, to, ease: easeOut, onPlay: () => { if (!start2) return; for (const node of nodes) { node.setProperties(start2); } for (const selection of selections) { for (const node of selection.nodes()) { node.setProperties(start2); } } }, onUpdate(props) { for (const node of nodes) { node.setProperties(props); } for (const selection of selections) { for (const node of selection.nodes()) { node.setProperties(props); } } }, onStop: () => { for (const node of nodes) { node.setProperties({ ...to, ...finish }); } for (const selection of selections) { for (const node of selection.nodes()) { node.setProperties({ ...to, ...finish }); } selection.cleanup(); } } }); } function calculateStatus(node, datum, getDatumId, diff8) { const id = getDatumId(node, datum); if (diff8.added.has(id)) { return "added"; } if (diff8.removed.has(id)) { return "removed"; } return "updated"; } var NODE_UPDATE_STATE_TO_PHASE_MAPPING; var init_fromToMotion = __esm({ "packages/ag-charts-community/src/motion/fromToMotion.ts"() { "use strict"; init_animation(); init_easing(); NODE_UPDATE_STATE_TO_PHASE_MAPPING = { added: "add", updated: "update", removed: "remove", unknown: "initial", "no-op": "none" }; } }); // packages/ag-charts-community/src/scale/abstractScale.ts var AbstractScale; var init_abstractScale = __esm({ "packages/ag-charts-community/src/scale/abstractScale.ts"() { "use strict"; AbstractScale = class { ticks(_ticks, _domain, _visibleRange) { return void 0; } niceDomain(_ticks, domain = this.domain) { return domain; } tickFormatter(_params) { return void 0; } datumFormatter(_params) { return void 0; } get bandwidth() { return void 0; } get step() { return void 0; } get inset() { return void 0; } }; } }); // packages/ag-charts-community/src/scale/continuousScale.ts var _ContinuousScale, ContinuousScale; var init_continuousScale = __esm({ "packages/ag-charts-community/src/scale/continuousScale.ts"() { "use strict"; init_number(); init_abstractScale(); _ContinuousScale = class _ContinuousScale extends AbstractScale { constructor(domain = [], range4 = []) { super(); this.domain = domain; this.range = range4; this.defaultClamp = false; } static is(value) { return value instanceof _ContinuousScale; } normalizeDomains(...domains) { let min; let minValue = Infinity; let max; let maxValue = -Infinity; for (const domain of domains) { for (const d of domain) { const value = d.valueOf(); if (value < minValue) { minValue = value; min = d; } if (value > maxValue) { maxValue = value; max = d; } } } if (min != null && max != null) { const domain = [min, max]; return { domain, animatable: true }; } else { return { domain: [], animatable: false }; } } transform(x) { return x; } transformInvert(x) { return x; } calcBandwidth(smallestInterval = 1) { const { domain } = this; const rangeDistance = this.getPixelRange(); if (domain.length === 0) return rangeDistance; const intervals = Math.abs(domain[1].valueOf() - domain[0].valueOf()) / smallestInterval + 1; const maxBands = Math.floor(rangeDistance); const bands = Math.min(intervals, maxBands); return rangeDistance / Math.max(1, bands); } convert(value, clamp9 = this.defaultClamp) { const { domain } = this; if (!domain || domain.length < 2) { return NaN; } const d0 = Number(this.transform(domain[0])); const d1 = Number(this.transform(domain[1])); const x = Number(this.transform(value)); const { range: range4 } = this; const [r0, r1] = range4; if (clamp9) { const [start2, stop] = findMinMax([d0, d1]); if (x < start2) { return r0; } else if (x > stop) { return r1; } } if (d0 === d1) { return (r0 + r1) / 2; } else if (x === d0) { return r0; } else if (x === d1) { return r1; } return r0 + (x - d0) / (d1 - d0) * (r1 - r0); } invert(x, _nearest) { const domain = this.domain.map((d2) => this.transform(d2)); const [d0, d1] = domain; const { range: range4 } = this; const [r0, r1] = range4; let d; if (r0 === r1) { d = this.toDomain((Number(d0) + Number(d1)) / 2); } else { d = this.toDomain(Number(d0) + (x - r0) / (r1 - r0) * (Number(d1) - Number(d0))); } return this.transformInvert(d); } getPixelRange() { const [a, b] = this.range; return Math.abs(b - a); } }; _ContinuousScale.defaultTickCount = 5; ContinuousScale = _ContinuousScale; } }); // packages/ag-charts-community/src/util/time/interval.ts var TimeInterval, CountableTimeInterval; var init_interval = __esm({ "packages/ag-charts-community/src/util/time/interval.ts"() { "use strict"; init_main(); TimeInterval = class { constructor(_encode, _decode, _rangeCallback) { this._encode = _encode; this._decode = _decode; this._rangeCallback = _rangeCallback; } /** * Returns a new date representing the latest interval boundary date before or equal to date. * For example, `day.floor(date)` typically returns 12:00 AM local time on the given date. * @param date */ floor(date2) { const d = new Date(date2); const e = this._encode(d); return this._decode(e); } /** * Returns a new date representing the earliest interval boundary date after or equal to date. * @param date */ ceil(date2) { const d = new Date(Number(date2) - 1); const e = this._encode(d); return this._decode(e + 1); } /** * Returns an array of dates representing every interval boundary after or equal to start (inclusive) and before stop (exclusive). * @param start Range start. * @param stop Range end. * @param extend If specified, the requested range will be extended to the closest "nice" values. */ range(start2, stop, { extend = false, visibleRange = [0, 1] } = {}) { let reversed = false; if (start2.getTime() > stop.getTime()) { [start2, stop] = [stop, start2]; reversed = true; } const rangeCallback = this._rangeCallback?.(start2, stop); const e0 = this._encode(extend ? this.floor(start2) : this.ceil(start2)); const e1 = this._encode(extend ? this.ceil(stop) : this.floor(stop)); if (e1 < e0) { return []; } const de = e1 - e0; let startIndex; let endIndex; if (reversed) { startIndex = Math.ceil(e0 + (1 - visibleRange[1]) * de); endIndex = Math.floor(e0 + (1 - visibleRange[0]) * de); } else { startIndex = Math.floor(e0 + visibleRange[0] * de); endIndex = Math.ceil(e0 + visibleRange[1] * de); } const range4 = []; for (let e = startIndex; e <= endIndex; e += 1) { const d = this._decode(e); range4.push(d); } rangeCallback?.(); return range4; } }; CountableTimeInterval = class extends TimeInterval { getOffset(snapTo, step) { return Math.floor(this._encode(new Date(snapTo))) % step; } /** * Returns a filtered view of this interval representing every step'th date. * It can be a number of minutes, hours, days etc. * Must be a positive integer. * @param step */ every(step, options) { let offset4 = 0; let rangeCallback; const unsafeStep = step; step = Math.max(1, Math.round(step)); if (unsafeStep !== step) { logger_exports.warnOnce(`interval step of [${unsafeStep}] rounded to [${step}].`); } const { snapTo = "start" } = options ?? {}; if (typeof snapTo === "string") { const initialOffset = offset4; rangeCallback = (start2, stop) => { const s = snapTo === "start" ? start2 : stop; offset4 = this.getOffset(s, step); return () => offset4 = initialOffset; }; } else if (typeof snapTo === "number") { offset4 = this.getOffset(new Date(snapTo), step); } else if (snapTo instanceof Date) { offset4 = this.getOffset(snapTo, step); } const encode13 = (date2) => Math.floor((this._encode(date2) - offset4) / step); const decode13 = (encoded) => this._decode(encoded * step + offset4); return new TimeInterval(encode13, decode13, rangeCallback); } }; } }); // packages/ag-charts-community/src/util/time/millisecond.ts function encode(date2) { return date2.getTime(); } function decode(encoded) { return new Date(encoded); } var millisecond; var init_millisecond = __esm({ "packages/ag-charts-community/src/util/time/millisecond.ts"() { "use strict"; init_interval(); millisecond = new CountableTimeInterval(encode, decode); } }); // packages/ag-charts-community/src/util/time/duration.ts var durationSecond, durationMinute, durationHour, durationDay, durationWeek, durationMonth, durationYear; var init_duration = __esm({ "packages/ag-charts-community/src/util/time/duration.ts"() { "use strict"; durationSecond = 1e3; durationMinute = durationSecond * 60; durationHour = durationMinute * 60; durationDay = durationHour * 24; durationWeek = durationDay * 7; durationMonth = durationDay * 30; durationYear = durationDay * 365; } }); // packages/ag-charts-community/src/util/time/second.ts function encode2(date2) { return Math.floor((date2.getTime() - offset) / durationSecond); } function decode2(encoded) { return new Date(offset + encoded * durationSecond); } var offset, second; var init_second = __esm({ "packages/ag-charts-community/src/util/time/second.ts"() { "use strict"; init_duration(); init_interval(); offset = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute; second = new CountableTimeInterval(encode2, decode2); } }); // packages/ag-charts-community/src/util/time/minute.ts function encode3(date2) { return Math.floor((date2.getTime() - offset2) / durationMinute); } function decode3(encoded) { return new Date(offset2 + encoded * durationMinute); } var offset2, minute; var init_minute = __esm({ "packages/ag-charts-community/src/util/time/minute.ts"() { "use strict"; init_duration(); init_interval(); offset2 = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute; minute = new CountableTimeInterval(encode3, decode3); } }); // packages/ag-charts-community/src/util/time/hour.ts function encode4(date2) { return Math.floor((date2.getTime() - offset3) / durationHour); } function decode4(encoded) { return new Date(offset3 + encoded * durationHour); } var offset3, hour; var init_hour = __esm({ "packages/ag-charts-community/src/util/time/hour.ts"() { "use strict"; init_duration(); init_interval(); offset3 = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute; hour = new CountableTimeInterval(encode4, decode4); } }); // packages/ag-charts-community/src/util/time/day.ts function encode5(date2) { const tzOffsetMs = date2.getTimezoneOffset() * durationMinute; return Math.floor((date2.getTime() - tzOffsetMs) / durationDay); } function decode5(encoded) { const d = new Date(1970, 0, 1); d.setDate(d.getDate() + encoded); return d; } var day; var init_day = __esm({ "packages/ag-charts-community/src/util/time/day.ts"() { "use strict"; init_duration(); init_interval(); day = new CountableTimeInterval(encode5, decode5); } }); // packages/ag-charts-community/src/util/time/week.ts function weekday(weekStart) { const thursday2 = 4; const dayShift = (7 + weekStart - thursday2) % 7; function encode13(date2) { const tzOffsetMs = date2.getTimezoneOffset() * durationMinute; return Math.floor((date2.getTime() - tzOffsetMs) / durationWeek - dayShift / 7); } function decode13(encoded) { const d = new Date(1970, 0, 1); d.setDate(d.getDate() + encoded * 7 + dayShift); return d; } return new CountableTimeInterval(encode13, decode13); } var sunday, monday, tuesday, wednesday, thursday, friday, saturday; var init_week = __esm({ "packages/ag-charts-community/src/util/time/week.ts"() { "use strict"; init_duration(); init_interval(); sunday = weekday(0); monday = weekday(1); tuesday = weekday(2); wednesday = weekday(3); thursday = weekday(4); friday = weekday(5); saturday = weekday(6); } }); // packages/ag-charts-community/src/util/time/month.ts function encode6(date2) { return date2.getFullYear() * 12 + date2.getMonth(); } function decode6(encoded) { const year2 = Math.floor(encoded / 12); const month2 = encoded - year2 * 12; return new Date(year2, month2, 1); } var month; var init_month = __esm({ "packages/ag-charts-community/src/util/time/month.ts"() { "use strict"; init_interval(); month = new CountableTimeInterval(encode6, decode6); } }); // packages/ag-charts-community/src/util/time/year.ts function encode7(date2) { return date2.getFullYear(); } function decode7(encoded) { const d = /* @__PURE__ */ new Date(); d.setFullYear(encoded); d.setMonth(0, 1); d.setHours(0, 0, 0, 0); return d; } var year; var init_year = __esm({ "packages/ag-charts-community/src/util/time/year.ts"() { "use strict"; init_interval(); year = new CountableTimeInterval(encode7, decode7); } }); // packages/ag-charts-community/src/util/time/utcMinute.ts function encode8(date2) { return Math.floor(date2.getTime() / durationMinute); } function decode8(encoded) { return new Date(encoded * durationMinute); } var utcMinute; var init_utcMinute = __esm({ "packages/ag-charts-community/src/util/time/utcMinute.ts"() { "use strict"; init_duration(); init_interval(); utcMinute = new CountableTimeInterval(encode8, decode8); } }); // packages/ag-charts-community/src/util/time/utcHour.ts function encode9(date2) { return Math.floor(date2.getTime() / durationHour); } function decode9(encoded) { return new Date(encoded * durationHour); } var utcHour; var init_utcHour = __esm({ "packages/ag-charts-community/src/util/time/utcHour.ts"() { "use strict"; init_duration(); init_interval(); utcHour = new CountableTimeInterval(encode9, decode9); } }); // packages/ag-charts-community/src/util/time/utcDay.ts function encode10(date2) { return Math.floor(date2.getTime() / durationDay); } function decode10(encoded) { const d = /* @__PURE__ */ new Date(0); d.setUTCDate(d.getUTCDate() + encoded); d.setUTCHours(0, 0, 0, 0); return d; } var utcDay; var init_utcDay = __esm({ "packages/ag-charts-community/src/util/time/utcDay.ts"() { "use strict"; init_duration(); init_interval(); utcDay = new CountableTimeInterval(encode10, decode10); } }); // packages/ag-charts-community/src/util/time/utcMonth.ts function encode11(date2) { return date2.getUTCFullYear() * 12 + date2.getUTCMonth(); } function decode11(encoded) { const year2 = Math.floor(encoded / 12); const month2 = encoded - year2 * 12; return new Date(Date.UTC(year2, month2, 1)); } var utcMonth; var init_utcMonth = __esm({ "packages/ag-charts-community/src/util/time/utcMonth.ts"() { "use strict"; init_interval(); utcMonth = new CountableTimeInterval(encode11, decode11); } }); // packages/ag-charts-community/src/util/time/utcYear.ts function encode12(date2) { return date2.getUTCFullYear(); } function decode12(encoded) { const d = /* @__PURE__ */ new Date(); d.setUTCFullYear(encoded); d.setUTCMonth(0, 1); d.setUTCHours(0, 0, 0, 0); return d; } var utcYear; var init_utcYear = __esm({ "packages/ag-charts-community/src/util/time/utcYear.ts"() { "use strict"; init_interval(); utcYear = new CountableTimeInterval(encode12, decode12); } }); // packages/ag-charts-community/src/util/time/index.ts var time_exports = {}; __export(time_exports, { TimeInterval: () => TimeInterval, day: () => day, friday: () => friday, hour: () => hour, millisecond: () => millisecond, minute: () => minute, monday: () => monday, month: () => month, saturday: () => saturday, second: () => second, sunday: () => sunday, thursday: () => thursday, tuesday: () => tuesday, utcDay: () => utcDay, utcHour: () => utcHour, utcMinute: () => utcMinute, utcMonth: () => utcMonth, utcYear: () => utcYear, wednesday: () => wednesday, year: () => year }); var init_time = __esm({ "packages/ag-charts-community/src/util/time/index.ts"() { "use strict"; init_millisecond(); init_second(); init_minute(); init_hour(); init_day(); init_week(); init_month(); init_year(); init_utcMinute(); init_utcHour(); init_utcDay(); init_utcMonth(); init_utcYear(); init_interval(); } }); // packages/ag-charts-community/src/util/timeFormat.ts function dayOfYear(date2, startOfYear = new Date(date2.getFullYear(), 0, 1)) { const startOffset = date2.getTimezoneOffset() - startOfYear.getTimezoneOffset(); const timeDiff = date2.getTime() - startOfYear.getTime() + startOffset * 6e4; const timeOneDay = 36e5 * 24; return Math.floor(timeDiff / timeOneDay); } function weekOfYear(date2, startDay) { const startOfYear = new Date(date2.getFullYear(), 0, 1); const startOfYearDay = startOfYear.getDay(); const firstWeekStartOffset = (startDay - startOfYearDay + 7) % 7; const startOffset = new Date(date2.getFullYear(), 0, firstWeekStartOffset + 1); if (startOffset <= date2) { return Math.floor(dayOfYear(date2, startOffset) / 7) + 1; } return 0; } function isoWeekOfYear(date2, year2 = date2.getFullYear()) { const firstOfYear = new Date(year2, 0, 1); const firstOfYearDay = firstOfYear.getDay(); const firstThursdayOffset = (THURSDAY - firstOfYearDay + 7) % 7; const startOffset = new Date(year2, 0, firstThursdayOffset - (THURSDAY - MONDAY) + 1); if (startOffset <= date2) { return Math.floor(dayOfYear(date2, startOffset) / 7) + 1; } return isoWeekOfYear(date2, year2 - 1); } function timezone(date2) { const offset4 = date2.getTimezoneOffset(); const unsignedOffset = Math.abs(offset4); const sign = offset4 > 0 ? "-" : "+"; return `${sign}${pad(Math.floor(unsignedOffset / 60), 2, "0")}${pad(Math.floor(unsignedOffset % 60), 2, "0")}`; } function pad(value, size, padChar) { const output = String(Math.floor(value)); if (output.length >= size) { return output; } return `${padChar.repeat(size - output.length)}${output}`; } function buildFormatter(formatString) { const formatParts = []; while (formatString.length > 0) { let nextEscapeIdx = formatString.indexOf("%"); if (nextEscapeIdx !== 0) { const literalPart = nextEscapeIdx > 0 ? formatString.substring(0, nextEscapeIdx) : formatString; formatParts.push(literalPart); } if (nextEscapeIdx < 0) break; const maybePadSpecifier = formatString[nextEscapeIdx + 1]; const maybePad = PADS[maybePadSpecifier]; if (maybePad != null) { nextEscapeIdx++; } const maybeFormatterSpecifier = formatString[nextEscapeIdx + 1]; const maybeFormatter = FORMATTERS[maybeFormatterSpecifier]; if (typeof maybeFormatter === "function") { formatParts.push([maybeFormatter, maybePad]); } else if (typeof maybeFormatter === "string") { const formatter = buildFormatter(maybeFormatter); formatParts.push([formatter, maybePad]); } else { formatParts.push(`${maybePad ?? ""}${maybeFormatterSpecifier}`); } formatString = formatString.substring(nextEscapeIdx + 2); } return (dateTime) => { const dateTimeAsDate = typeof dateTime === "number" ? new Date(dateTime) : dateTime; return formatParts.map((c) => typeof c === "string" ? c : c[0](dateTimeAsDate, c[1])).join(""); }; } var CONSTANTS, SUNDAY, MONDAY, THURSDAY, FORMATTERS, PADS; var init_timeFormat = __esm({ "packages/ag-charts-community/src/util/timeFormat.ts"() { "use strict"; CONSTANTS = { periods: ["AM", "PM"], days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }; SUNDAY = 0; MONDAY = 1; THURSDAY = 4; FORMATTERS = { a: (d) => CONSTANTS.shortDays[d.getDay()], A: (d) => CONSTANTS.days[d.getDay()], b: (d) => CONSTANTS.shortMonths[d.getMonth()], B: (d) => CONSTANTS.months[d.getMonth()], c: "%x, %X", d: (d, p) => pad(d.getDate(), 2, p ?? "0"), e: "%_d", f: (d, p) => pad(d.getMilliseconds() * 1e3, 6, p ?? "0"), H: (d, p) => pad(d.getHours(), 2, p ?? "0"), I: (d, p) => { const hours = d.getHours() % 12; return hours === 0 ? "12" : pad(hours, 2, p ?? "0"); }, j: (d, p) => pad(dayOfYear(d) + 1, 3, p ?? "0"), m: (d, p) => pad(d.getMonth() + 1, 2, p ?? "0"), M: (d, p) => pad(d.getMinutes(), 2, p ?? "0"), L: (d, p) => pad(d.getMilliseconds(), 3, p ?? "0"), p: (d) => d.getHours() < 12 ? "AM" : "PM", Q: (d) => String(d.getTime()), s: (d) => String(Math.floor(d.getTime() / 1e3)), S: (d, p) => pad(d.getSeconds(), 2, p ?? "0"), u: (d) => { let day2 = d.getDay(); if (day2 < 1) day2 += 7; return String(day2 % 7); }, U: (d, p) => pad(weekOfYear(d, SUNDAY), 2, p ?? "0"), V: (d, p) => pad(isoWeekOfYear(d), 2, p ?? "0"), w: (d, p) => pad(d.getDay(), 2, p ?? "0"), W: (d, p) => pad(weekOfYear(d, MONDAY), 2, p ?? "0"), x: "%-m/%-d/%Y", X: "%-I:%M:%S %p", y: (d, p) => pad(d.getFullYear() % 100, 2, p ?? "0"), Y: (d, p) => pad(d.getFullYear(), 4, p ?? "0"), Z: (d) => timezone(d), "%": () => "%" }; PADS = { _: " ", "0": "0", "-": "" }; } }); // packages/ag-charts-community/src/util/timeFormatDefaults.ts function dateToNumber(value) { return value instanceof Date ? value.getTime() : value; } function defaultTimeTickFormat(ticks, domain, formatOffset) { const formatString = calculateDefaultTimeTickFormat(ticks, domain, formatOffset); const formatter = buildFormatter(formatString); return (date2) => formatter(date2); } function calculateDefaultTimeTickFormat(ticks, domain, formatOffset = 0) { let minInterval = Infinity; for (let i = 1; i < ticks.length; i++) { minInterval = Math.min(minInterval, Math.abs(ticks[i].valueOf() - ticks[i - 1].valueOf())); } const [d0, d1] = domain.length === 0 ? [0, 0] : findMinMax([domain[0].valueOf(), domain[domain.length - 1].valueOf()]); const startYear = new Date(d0).getFullYear(); const stopYear = new Date(d1).getFullYear(); const yearChange = stopYear - startYear > 0; const timeFormat = isFinite(minInterval) ? getIntervalLowestGranularityFormat(minInterval, ticks) : getLowestGranularityFormat(ticks[0]); return formatStringBuilder(Math.max(timeFormat - formatOffset, 0), yearChange, ticks); } function getIntervalLowestGranularityFormat(value, ticks) { if (value < durationSecond) { return 0 /* MILLISECOND */; } else if (value < durationMinute) { return 1 /* SECOND */; } else if (value < durationHour) { return 2 /* MINUTE */; } else if (value < durationDay) { return 3 /* HOUR */; } else if (value < durationWeek) { return 4 /* WEEK_DAY */; } else if (value < durationDay * 28 || value < durationDay * 31 && hasDuplicateMonth(ticks)) { return 5 /* SHORT_MONTH */; } else if (value < durationYear) { return 6 /* MONTH */; } return 7 /* YEAR */; } function getLowestGranularityFormat(value) { if (second.floor(value) < value) { return 0 /* MILLISECOND */; } else if (minute.floor(value) < value) { return 1 /* SECOND */; } else if (hour.floor(value) < value) { return 2 /* MINUTE */; } else if (day.floor(value) < value) { return 3 /* HOUR */; } else if (month.floor(value) < value) { if (sunday.floor(value) < value) { return 4 /* WEEK_DAY */; } return 5 /* SHORT_MONTH */; } else if (year.floor(value) < value) { return 6 /* MONTH */; } return 7 /* YEAR */; } function hasDuplicateMonth(ticks) { let prevMonth = new Date(ticks[0]).getMonth(); for (let i = 1; i < ticks.length; i++) { const tickMonth = new Date(ticks[i]).getMonth(); if (prevMonth === tickMonth) { return true; } prevMonth = tickMonth; } return false; } function formatStringBuilder(defaultTimeFormat, yearChange, ticks) { const firstTick = dateToNumber(ticks[0]); const lastTick = dateToNumber(ticks.at(-1)); const extent3 = Math.abs(lastTick - firstTick); const activeYear = yearChange || defaultTimeFormat === 7 /* YEAR */; const activeDate = extent3 === 0; const parts = [ ["hour", 6 * durationHour, 14 * durationDay, 3 /* HOUR */, "%I %p"], ["hour", durationMinute, 6 * durationHour, 3 /* HOUR */, "%I:%M"], ["second", 1e3, 6 * durationHour, 1 /* SECOND */, ":%S"], ["ms", 0, 6 * durationHour, 0 /* MILLISECOND */, ".%L"], ["am/pm", durationMinute, 6 * durationHour, 3 /* HOUR */, "%p"], " ", ["day", durationDay, durationWeek, 4 /* WEEK_DAY */, "%a"], ["month", activeDate ? 0 : durationWeek, 52 * durationWeek, 5 /* SHORT_MONTH */, "%b %d"], ["month", 5 * durationWeek, 10 * durationYear, 6 /* MONTH */, "%B"], " ", ["year", activeYear ? 0 : durationYear, Infinity, 7 /* YEAR */, "%Y"] ]; const formatParts = parts.filter((v) => { if (typeof v === "string") { return true; } const [_, min, max, format] = v; return format >= defaultTimeFormat && min <= extent3 && extent3 < max; }).reduce( (r, next) => { if (typeof next === "string") { r.result.push(next); } else if (!r.used.has(next[0])) { r.result.push(next); r.used.add(next[0]); } return r; }, { result: [], used: /* @__PURE__ */ new Set() } ).result; const firstFormat = formatParts.findIndex((v) => typeof v !== "string"); const lastFormat = formatParts.findLastIndex((v) => typeof v !== "string"); return formatParts.slice(firstFormat, lastFormat + 1).map((v) => typeof v === "string" ? v : v[4]).join("").replaceAll(/\s+/g, " ").trim(); } var init_timeFormatDefaults = __esm({ "packages/ag-charts-community/src/util/timeFormatDefaults.ts"() { "use strict"; init_number(); init_time(); init_duration(); init_timeFormat(); } }); // packages/ag-charts-community/src/scale/invalidating.ts var Invalidating; var init_invalidating = __esm({ "packages/ag-charts-community/src/scale/invalidating.ts"() { "use strict"; Invalidating = (target, propertyKey) => { const mappedProperty = Symbol(String(propertyKey)); target[mappedProperty] = void 0; Object.defineProperty(target, propertyKey, { get() { return this[mappedProperty]; }, set(newValue) { const oldValue = this[mappedProperty]; if (oldValue !== newValue) { this[mappedProperty] = newValue; this.invalid = true; } }, enumerable: true, configurable: false }); }; } }); // packages/ag-charts-community/src/scale/scaleUtil.ts function filterVisibleTicks(ticks, reversed, visibleRange) { if (visibleRange == null || visibleRange[0] === 0 && visibleRange[1] === 1) return ticks; const vt0 = clamp(0, Math.floor(visibleRange[0] * ticks.length), ticks.length); const vt1 = clamp(0, Math.ceil(visibleRange[1] * ticks.length), ticks.length); const t0 = reversed ? ticks.length - vt1 : vt0; const t1 = reversed ? ticks.length - vt0 : vt1; return ticks.slice(t0, t1); } var init_scaleUtil = __esm({ "packages/ag-charts-community/src/scale/scaleUtil.ts"() { "use strict"; init_number(); } }); // packages/ag-charts-community/src/scale/bandScale.ts var _BandScale, BandScale; var init_bandScale = __esm({ "packages/ag-charts-community/src/scale/bandScale.ts"() { "use strict"; init_main(); init_number(); init_abstractScale(); init_invalidating(); init_scaleUtil(); _BandScale = class _BandScale extends AbstractScale { constructor() { super(...arguments); this.invalid = true; this.range = [0, 1]; this.round = false; this.interval = void 0; this._bandwidth = 1; this._step = 1; this._inset = 1; this._rawBandwidth = 1; /** * The ratio of the range that is reserved for space between bands. */ this._paddingInner = 0; /** * The ratio of the range that is reserved for space before the first * and after the last band. */ this._paddingOuter = 0; } static is(value) { return value instanceof _BandScale; } get bandwidth() { this.refresh(); return this._bandwidth; } get step() { this.refresh(); return this._step; } get inset() { this.refresh(); return this._inset; } get rawBandwidth() { this.refresh(); return this._rawBandwidth; } set padding(value) { value = clamp(0, value, 1); this._paddingInner = value; this._paddingOuter = value; } get padding() { return this._paddingInner; } set paddingInner(value) { this.invalid = true; this._paddingInner = clamp(0, value, 1); } get paddingInner() { return this._paddingInner; } set paddingOuter(value) { this.invalid = true; this._paddingOuter = clamp(0, value, 1); } get paddingOuter() { return this._paddingOuter; } refresh() { if (!this.invalid) return; this.invalid = false; this.update(); if (this.invalid) { logger_exports.warnOnce("Expected update to not invalidate scale"); } } ticks(_params, domain = this.domain, visibleRange) { return filterVisibleTicks(domain, false, visibleRange); } convert(d, _clamp) { this.refresh(); const i = this.getIndex(d); if (i == null || i < 0 || i >= this.domain.length) { return NaN; } return this.ordinalRange(i); } invertNearestIndex(position) { this.refresh(); const { domain } = this; if (domain.length === 0) return -1; let low = 0; let high = domain.length - 1; let closestDistance = Infinity; let closestIndex = 0; while (low <= high) { const mid = (high + low) / 2 | 0; const p = this.ordinalRange(mid); const distance2 = Math.abs(p - position); if (distance2 === 0) return mid; if (distance2 < closestDistance) { closestDistance = distance2; closestIndex = mid; } if (p < position) { low = mid + 1; } else { high = mid - 1; } } return closestIndex; } update() { const count = this.domain.length; if (count === 0) return; const [r0, r1] = this.range; let { _paddingInner: paddingInner } = this; const { _paddingOuter: paddingOuter, round: round6 } = this; const rangeDistance = r1 - r0; let rawStep; if (count === 1) { paddingInner = 0; rawStep = rangeDistance * (1 - paddingOuter * 2); } else { rawStep = rangeDistance / Math.max(1, count - paddingInner + paddingOuter * 2); } const step = round6 ? Math.floor(rawStep) : rawStep; let inset = r0 + (rangeDistance - step * (count - paddingInner)) / 2; let bandwidth = step * (1 - paddingInner); if (round6) { inset = Math.round(inset); bandwidth = Math.round(bandwidth); } this._step = step; this._inset = inset; this._bandwidth = bandwidth; this._rawBandwidth = rawStep * (1 - paddingInner); } ordinalRange(i) { const { _inset: inset, _step: step, range: range4 } = this; const min = Math.min(range4[0], range4[1]); const max = Math.max(range4[0], range4[1]); return clamp(min, inset + step * i, max); } }; __decorateClass([ Invalidating ], _BandScale.prototype, "range", 2); __decorateClass([ Invalidating ], _BandScale.prototype, "round", 2); __decorateClass([ Invalidating ], _BandScale.prototype, "interval", 2); BandScale = _BandScale; } }); // packages/ag-charts-community/src/scale/categoryScale.ts function deduplicateCategories(d) { let domain; const uniqueValues = /* @__PURE__ */ new Set(); for (const value of d) { const key = dateToNumber(value); const lastSize = uniqueValues.size; uniqueValues.add(key); const isUniqueValue = uniqueValues.size !== lastSize; if (isUniqueValue) { domain?.push(value); } else { domain ?? (domain = d.slice(0, uniqueValues.size)); } } return domain ?? d; } function domainOrderedToNormalizedDomain(domain, normalizedDomain) { let normalizedIndex = -1; for (const value of domain) { const normalizedNextIndex = normalizedDomain.indexOf(value); if (normalizedNextIndex === -1) { normalizedIndex = Infinity; } else if (normalizedNextIndex <= normalizedIndex) { return false; } else { normalizedIndex = normalizedNextIndex; } } return true; } var CategoryScale; var init_categoryScale = __esm({ "packages/ag-charts-community/src/scale/categoryScale.ts"() { "use strict"; init_timeFormatDefaults(); init_bandScale(); CategoryScale = class extends BandScale { constructor() { super(...arguments); this.type = "band"; /** * Maps datum to its index in the {@link domain} array. * Used to check for duplicate data (not allowed). */ this.index = void 0; /** * Contains unique data only. */ this._domain = []; } set domain(values) { if (this._domain === values) return; this.invalid = true; this._domain = values; this.index = void 0; } get domain() { return this._domain; } normalizeDomains(...domains) { let normalizedDomain = void 0; const seenDomains = /* @__PURE__ */ new Set(); let animatable = true; for (const domain of domains) { if (seenDomains.has(domain)) continue; seenDomains.add(domain); if (normalizedDomain == null) { normalizedDomain = deduplicateCategories(domain); } else { animatable && (animatable = domainOrderedToNormalizedDomain(domain, normalizedDomain)); normalizedDomain = deduplicateCategories([...normalizedDomain, ...domain]); } } normalizedDomain ?? (normalizedDomain = []); return { domain: normalizedDomain, animatable }; } toDomain(_value) { return void 0; } invert(position, nearest = false) { this.refresh(); const offset4 = nearest ? this.bandwidth / 2 : 0; const index = this.invertNearestIndex(Math.max(0, position - offset4)); const matches = nearest || position === this.ordinalRange(index); return matches ? this.domain[index] : void 0; } getIndex(value) { let { index } = this; if (index == null) { const { domain } = this; index = /* @__PURE__ */ new Map(); for (let i = 0; i < domain.length; i++) { index.set(dateToNumber(domain[i]), i); } this.index = index; } return index.get(dateToNumber(value)); } }; } }); // packages/ag-charts-community/src/util/properties.ts function isProperties(value) { return value instanceof BaseProperties || value instanceof PropertiesArray; } var BaseProperties, PropertiesArray; var init_properties = __esm({ "packages/ag-charts-community/src/util/properties.ts"() { "use strict"; init_main(); init_decorator(); BaseProperties = class { set(properties) { const { className = this.constructor.name } = this.constructor; if (typeof properties !== "object") { logger_exports.warn(`unable to set ${className} - expecting a properties object`); return this; } const keys = new Set(Object.keys(properties)); for (const propertyKey of listDecoratedProperties(this)) { if (keys.has(propertyKey)) { const value = properties[propertyKey]; const self = this; if (isProperties(self[propertyKey])) { if (self[propertyKey] instanceof PropertiesArray) { const array2 = self[propertyKey].reset(value); if (array2 != null) { self[propertyKey] = array2; } else { logger_exports.warn(`unable to set [${propertyKey}] - expecting a properties array`); } } else { self[propertyKey].set(value); } } else { self[propertyKey] = value; } keys.delete(propertyKey); } } for (const unknownKey of keys) { logger_exports.warn(`unable to set [${unknownKey}] in ${className} - property is unknown`); } return this; } isValid(warningPrefix) { return listDecoratedProperties(this).every((propertyKey) => { const { optional } = extractDecoratedPropertyMetadata(this, propertyKey); const valid = optional === true || typeof this[propertyKey] !== "undefined"; if (!valid) { logger_exports.warnOnce(`${warningPrefix ?? ""}[${propertyKey}] is required.`); } return valid; }); } toJson() { return listDecoratedProperties(this).reduce((object2, propertyKey) => { const propertyValue = this[propertyKey]; object2[propertyKey] = isProperties(propertyValue) ? propertyValue.toJson() : propertyValue; return object2; }, {}); } }; PropertiesArray = class _PropertiesArray extends Array { constructor(itemFactory, ...properties) { super(properties.length); const isConstructor = (value2) => Boolean(value2?.prototype?.constructor?.name); const value = isConstructor(itemFactory) ? (params) => new itemFactory().set(params) : itemFactory; Object.defineProperty(this, "itemFactory", { value, enumerable: false, configurable: false }); this.set(properties); } set(properties) { if (isArray(properties)) { this.length = properties.length; for (let i = 0; i < properties.length; i++) { this[i] = this.itemFactory(properties[i]); } } return this; } reset(properties) { if (Array.isArray(properties)) { return new _PropertiesArray(this.itemFactory, ...properties); } } toJson() { return this.map((value) => value?.toJson?.() ?? value); } }; } }); // packages/ag-charts-community/src/util/validation.ts function Validate(predicate, options = {}) { const { optional = false, property: overrideProperty } = options; return addTransformToInstanceProperty( (target, property, value) => { const context = { ...options, target, property }; if (optional && typeof value === "undefined" || predicate(value, context)) { if (isProperties(target[property]) && !isProperties(value)) { target[property].set(value); return target[property]; } return value; } const cleanKey = overrideProperty ?? String(property).replace(/^_*/, ""); const targetName = target.constructor.className ?? target.constructor.name.replace(/Properties$/, ""); const valueString = stringifyValue(value, 50); logger_exports.warn( `Property [${cleanKey}] of [${targetName}] cannot be set to [${valueString}]${predicate.message ? `; expecting ${getPredicateMessage(predicate, context)}` : ""}, ignoring.` ); return BREAK_TRANSFORM_CHAIN; }, void 0, { optional } ); } function UNION(options, message = "a") { return predicateWithMessage( (v, ctx) => { const option = options.find((o) => { const value = typeof o === "string" ? o : o.value; return v === value; }); if (option == null) return false; if (typeof option !== "string" && (option.deprecated === true || option.deprecatedTo != null)) { const messages = [`Property [%s] with value '${option.value}' is deprecated.`]; if (option.deprecatedTo) { messages.push(`Use ${option.deprecatedTo} instead.`); } logger_exports.warnOnce(messages.join(" "), ctx.property); } return true; }, `${message} keyword such as ${joinUnionOptions(options)}` ); } function predicateWithMessage(predicate, message) { predicate.message = message; return predicate; } function joinUnionOptions(options) { const values = options.filter((option) => typeof option === "string" || option.undocumented !== true).map((option) => `'${typeof option === "string" ? option : option.value}'`); if (values.length === 1) { return values[0]; } const lastValue = values.pop(); return `${values.join(", ")} or ${lastValue}`; } function getPredicateMessage(predicate, ctx) { return isFunction(predicate.message) ? predicate.message(ctx) : predicate.message; } function getPredicateMessageMapper(ctx) { return (predicate) => getPredicateMessage(predicate, ctx); } function attachArrayRestrictions(predicate) { return Object.assign(predicate, { restrict({ length: length2, minLength } = {}) { let message = "an array"; if (isNumber(minLength) && minLength > 0) { message = "a non-empty array"; } else if (isNumber(length2)) { message = `an array of length ${length2}`; } return predicateWithMessage( (value) => isArray(value) && (isNumber(length2) ? value.length === length2 : true) && (isNumber(minLength) ? value.length >= minLength : true), message ); } }); } function attachNumberRestrictions(predicate) { return Object.assign(predicate, { restrict({ min, max } = {}) { const message = ["a number"]; const hasMin = isNumber(min); const hasMax = isNumber(max); if (hasMin && hasMax) { message.push(`between ${min} and ${max} inclusive`); } else if (hasMin) { message.push(`greater than or equal to ${min}`); } else if (hasMax) { message.push(`less than or equal to ${max}`); } return predicateWithMessage( (value) => isFiniteNumber(value) && (hasMin ? value >= min : true) && (hasMax ? value <= max : true), message.join(" ") ); } }); } function attachObjectRestrictions(predicate) { return Object.assign(predicate, { restrict(objectType) { return predicateWithMessage( (value) => value instanceof objectType, (ctx) => getPredicateMessage(predicate, ctx) ?? `an instance of ${objectType.name}` ); } }); } var AND, OR, OBJECT, PLAIN_OBJECT, BOOLEAN, FUNCTION, STRING, NUMBER, REAL_NUMBER, NAN, POSITIVE_NUMBER, RATIO, NUMBER_OR_NAN, ARRAY, ARRAY_OF, isComparable2, LESS_THAN, GREATER_THAN, DATE, DATE_OR_DATETIME_MS, colorMessage, COLOR_STRING, COLOR_GRADIENT, COLOR_STRING_ARRAY, BOOLEAN_ARRAY, NUMBER_ARRAY, STRING_ARRAY, DATE_ARRAY, OBJECT_ARRAY, LINE_CAP, LINE_JOIN, LINE_STYLE, LINE_DASH, POSITION, FONT_STYLE, FONT_WEIGHT, TEXT_WRAP, TEXT_ALIGN, VERTICAL_ALIGN, OVERFLOW_STRATEGY, DIRECTION, PLACEMENT, INTERACTION_RANGE, LABEL_PLACEMENT, MIN_SPACING, MAX_SPACING; var init_validation2 = __esm({ "packages/ag-charts-community/src/util/validation.ts"() { "use strict"; init_main(); init_color(); init_decorator(); init_properties(); AND = (...predicates) => { const messages = []; return predicateWithMessage( (value, ctx) => { messages.length = 0; return predicates.every((predicate) => { const isValid = predicate(value, ctx); if (!isValid) { messages.push(getPredicateMessage(predicate, ctx)); } return isValid; }); }, () => messages.filter(Boolean).join(" AND ") ); }; OR = (...predicates) => predicateWithMessage( (value, ctx) => predicates.some((predicate) => predicate(value, ctx)), (ctx) => predicates.map(getPredicateMessageMapper(ctx)).filter(Boolean).join(" OR ") ); OBJECT = attachObjectRestrictions( predicateWithMessage( (value, ctx) => isProperties(value) || isObject(value) && isProperties(ctx.target[ctx.property]), "a properties object" ) ); PLAIN_OBJECT = attachObjectRestrictions(predicateWithMessage((value) => isObject(value), "an object")); BOOLEAN = predicateWithMessage(isBoolean, "a boolean"); FUNCTION = predicateWithMessage(isFunction, "a function"); STRING = predicateWithMessage(isString, "a string"); NUMBER = attachNumberRestrictions(predicateWithMessage(isFiniteNumber, "a number")); REAL_NUMBER = predicateWithMessage((value) => isNumber(value) && !isNaN(value), "a real number"); NAN = predicateWithMessage((value) => isNumber(value) && isNaN(value), "NaN"); POSITIVE_NUMBER = NUMBER.restrict({ min: 0 }); RATIO = NUMBER.restrict({ min: 0, max: 1 }); NUMBER_OR_NAN = OR(NUMBER, NAN); ARRAY = attachArrayRestrictions(predicateWithMessage(isArray, "an array")); ARRAY_OF = (predicate, message) => predicateWithMessage( (value, ctx) => isArray(value) && value.every((item) => predicate(item, ctx)), (ctx) => { const arrayMessage = getPredicateMessage(ARRAY, ctx) ?? ""; if (typeof message === "function") { return `${arrayMessage} of ${message(ctx)}`; } return message ? `${arrayMessage} of ${message}` : arrayMessage; } ); isComparable2 = (value) => isFiniteNumber(value) || isValidDate(value); LESS_THAN = (otherField) => predicateWithMessage( (v, ctx) => !isComparable2(v) || !isComparable2(ctx.target[otherField]) || v < ctx.target[otherField], `to be less than ${otherField}` ); GREATER_THAN = (otherField) => predicateWithMessage( (v, ctx) => !isComparable2(v) || !isComparable2(ctx.target[otherField]) || v > ctx.target[otherField], `to be greater than ${otherField}` ); DATE = predicateWithMessage(isValidDate, "Date object"); DATE_OR_DATETIME_MS = OR(DATE, POSITIVE_NUMBER); colorMessage = `A color string can be in one of the following formats to be valid: #rgb, #rrggbb, rgb(r, g, b), rgba(r, g, b, a) or a CSS color name such as 'white', 'orange', 'cyan', etc`; COLOR_STRING = predicateWithMessage( (v) => isString(v) && Color.validColorString(v), `color String. ${colorMessage}` ); COLOR_GRADIENT = attachObjectRestrictions( predicateWithMessage((value) => isObject(value) && value.type === "gradient", "a color gradient object") ); COLOR_STRING_ARRAY = predicateWithMessage(ARRAY_OF(COLOR_STRING), `color strings. ${colorMessage}`); BOOLEAN_ARRAY = ARRAY_OF(BOOLEAN, "boolean values"); NUMBER_ARRAY = ARRAY_OF(NUMBER, "numbers"); STRING_ARRAY = ARRAY_OF(STRING, "strings"); DATE_ARRAY = predicateWithMessage(ARRAY_OF(DATE), "Date objects"); OBJECT_ARRAY = predicateWithMessage(ARRAY_OF(OBJECT), "objects"); LINE_CAP = UNION(["butt", "round", "square"], "a line cap"); LINE_JOIN = UNION(["round", "bevel", "miter"], "a line join"); LINE_STYLE = UNION(["solid", "dashed", "dotted"], "a line style"); LINE_DASH = predicateWithMessage( ARRAY_OF(POSITIVE_NUMBER), "numbers specifying the length in pixels of alternating dashes and gaps, for example, [6, 3] means dashes with a length of 6 pixels with gaps between of 3 pixels." ); POSITION = UNION(["top", "right", "bottom", "left"], "a position"); FONT_STYLE = UNION(["normal", "italic", "oblique"], "a font style"); FONT_WEIGHT = OR( UNION(["normal", "bold", "bolder", "lighter"], "a font weight"), NUMBER.restrict({ min: 1, max: 1e3 }) ); TEXT_WRAP = UNION(["never", "always", "hyphenate", "on-space"], "a text wrap strategy"); TEXT_ALIGN = UNION(["left", "center", "right"], "a text align"); VERTICAL_ALIGN = UNION(["top", "middle", "bottom"], "a vertical align"); OVERFLOW_STRATEGY = UNION(["ellipsis", "hide"], "an overflow strategy"); DIRECTION = UNION(["horizontal", "vertical"], "a direction"); PLACEMENT = UNION(["inside", "outside"], "a placement"); INTERACTION_RANGE = OR(UNION(["exact", "nearest"], "interaction range"), NUMBER); LABEL_PLACEMENT = UNION(["top", "bottom", "left", "right"]); MIN_SPACING = OR(AND(NUMBER.restrict({ min: 1 }), LESS_THAN("maxSpacing")), NAN); MAX_SPACING = OR(AND(NUMBER.restrict({ min: 1 }), GREATER_THAN("minSpacing")), NAN); } }); // packages/ag-charts-community/src/motion/resetMotion.ts var resetMotion_exports = {}; __export(resetMotion_exports, { resetMotion: () => resetMotion }); function resetMotion(selectionsOrNodes, propsFn) { const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes); for (const selection of selections) { for (const node of selection.nodes()) { const from3 = propsFn(node, node.datum); node.setProperties(from3); } selection.cleanup(); } for (const node of nodes) { const from3 = propsFn(node, node.datum); node.setProperties(from3); } } var init_resetMotion = __esm({ "packages/ag-charts-community/src/motion/resetMotion.ts"() { "use strict"; init_animation(); } }); // packages/ag-charts-community/src/util/debug.ts var LONG_TIME_PERIOD_THRESHOLD, timeOfLastLog, logTimeGap, Debug; var init_debug = __esm({ "packages/ag-charts-community/src/util/debug.ts"() { "use strict"; init_main(); init_core(); LONG_TIME_PERIOD_THRESHOLD = 2e3; timeOfLastLog = Date.now(); logTimeGap = () => { const timeSinceLastLog = Date.now() - timeOfLastLog; if (timeSinceLastLog > LONG_TIME_PERIOD_THRESHOLD) { const prettyDuration = (Math.floor(timeSinceLastLog / 100) / 10).toFixed(1); logger_exports.log(`**** ${prettyDuration}s since last log message ****`); } timeOfLastLog = Date.now(); }; Debug = { create(...debugSelectors) { const resultFn = (...logContent) => { if (Debug.check(...debugSelectors)) { if (typeof logContent[0] === "function") { logContent = toArray(logContent[0]()); } logTimeGap(); logger_exports.log(...logContent); } }; return Object.assign(resultFn, { check: () => Debug.check(...debugSelectors), group: (name, cb) => { if (Debug.check(...debugSelectors)) { return logger_exports.logGroup(name, cb); } return cb(); } }); }, check(...debugSelectors) { if (debugSelectors.length === 0) { debugSelectors.push(true); } const chartDebug = toArray(getWindow("agChartsDebug")); return chartDebug.some((selector) => debugSelectors.includes(selector)); } }; } }); // packages/ag-charts-community/src/scene/canvas/canvasUtil.ts function clearContext({ context, pixelRatio, width: width2, height: height2 }) { context.save(); context.resetTransform(); context.clearRect(0, 0, Math.ceil(width2 * pixelRatio), Math.ceil(height2 * pixelRatio)); context.restore(); } function debugContext(ctx) { if (Debug.check("canvas")) { const save = ctx.save.bind(ctx); const restore = ctx.restore.bind(ctx); let depth = 0; Object.assign(ctx, { save() { save(); depth++; }, restore() { if (depth === 0) { throw new Error("AG Charts - Unable to restore() past depth 0"); } restore(); depth--; }, verifyDepthZero() { if (depth !== 0) { throw new Error(`AG Charts - Save/restore depth is non-zero: ${depth}`); } } }); } } var init_canvasUtil = __esm({ "packages/ag-charts-community/src/scene/canvas/canvasUtil.ts"() { "use strict"; init_debug(); } }); // packages/ag-charts-community/src/scene/canvas/hdpiOffscreenCanvas.ts function canvasDimensions(width2, height2, pixelRatio) { return [Math.round(width2 * pixelRatio), Math.round(height2 * pixelRatio)]; } var HdpiOffscreenCanvas; var init_hdpiOffscreenCanvas = __esm({ "packages/ag-charts-community/src/scene/canvas/hdpiOffscreenCanvas.ts"() { "use strict"; init_canvasUtil(); HdpiOffscreenCanvas = class { constructor(options) { const { width: width2, height: height2, pixelRatio, willReadFrequently = false } = options; this.width = width2; this.height = height2; this.pixelRatio = pixelRatio; const [canvasWidth, canvasHeight] = canvasDimensions(width2, height2, pixelRatio); this.canvas = new OffscreenCanvas(canvasWidth, canvasHeight); this.context = this.canvas.getContext("2d", { willReadFrequently }); this.context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); debugContext(this.context); } drawImage(context, dx2 = 0, dy2 = 0) { return context.drawImage(this.canvas, dx2, dy2); } transferToImageBitmap() { return this.canvas.transferToImageBitmap(); } resize(width2, height2, pixelRatio) { if (!(width2 > 0 && height2 > 0)) return; const { canvas, context } = this; if (width2 !== this.width || height2 !== this.height || pixelRatio !== this.pixelRatio) { const [canvasWidth, canvasHeight] = canvasDimensions(width2, height2, pixelRatio); canvas.width = canvasWidth; canvas.height = canvasHeight; } context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); this.width = width2; this.height = height2; this.pixelRatio = pixelRatio; } clear() { clearContext(this); } destroy() { this.canvas.width = 0; this.canvas.height = 0; this.context.clearRect(0, 0, 0, 0); this.canvas = null; this.context = null; Object.freeze(this); } }; } }); // packages/ag-charts-community/src/scale/colorScale.ts var convertColorStringToOklcha, delta, isAchromatic, interpolateOklch, ColorScale; var init_colorScale = __esm({ "packages/ag-charts-community/src/scale/colorScale.ts"() { "use strict"; init_main(); init_color(); init_number(); init_abstractScale(); init_invalidating(); convertColorStringToOklcha = (v) => { const color = Color.fromString(v); const [l, c, h] = Color.RGBtoOKLCH(color.r, color.g, color.b); return { l, c, h, a: color.a }; }; delta = 1e-6; isAchromatic = (x) => x.c < delta || x.l < delta || x.l > 1 - delta; interpolateOklch = (x, y, d) => { d = clamp(0, d, 1); let h; if (isAchromatic(x)) { h = y.h; } else if (isAchromatic(y)) { h = x.h; } else { const xH = x.h; let yH = y.h; const deltaH = y.h - x.h; if (deltaH > 180) { yH -= 360; } else if (deltaH < -180) { yH += 360; } h = xH * (1 - d) + yH * d; } const c = x.c * (1 - d) + y.c * d; const l = x.l * (1 - d) + y.l * d; const a = x.a * (1 - d) + y.a * d; return Color.fromOKLCH(l, c, h, a); }; ColorScale = class extends AbstractScale { constructor() { super(...arguments); this.type = "color"; this.invalid = true; this.domain = [0, 1]; this.range = ["red", "blue"]; this.parsedRange = this.range.map(convertColorStringToOklcha); } update() { const { domain, range: range4 } = this; if (domain.length < 2) { logger_exports.warnOnce("`colorDomain` should have at least 2 values."); if (domain.length === 0) { domain.push(0, 1); } else if (domain.length === 1) { domain.push(domain[0] + 1); } } for (let i = 1; i < domain.length; i++) { const a = domain[i - 1]; const b = domain[i]; if (a >= b) { logger_exports.warnOnce("`colorDomain` values should be supplied in ascending order."); domain.sort((a2, b2) => a2 - b2); break; } } if (range4.length < domain.length) { for (let i = range4.length; i < domain.length; i++) { range4.push(range4.length > 0 ? range4[0] : "black"); } } this.parsedRange = this.range.map(convertColorStringToOklcha); } normalizeDomains(...domains) { return { domain: domains.flat(), animatable: true }; } toDomain() { return; } convert(x) { this.refresh(); const { domain, range: range4, parsedRange } = this; const d0 = domain[0]; const d1 = domain.at(-1); const r0 = range4[0]; const r1 = range4[range4.length - 1]; if (x <= d0) { return r0; } if (x >= d1) { return r1; } let index; let q; if (domain.length === 2) { const t = (x - d0) / (d1 - d0); const step = 1 / (range4.length - 1); index = range4.length <= 2 ? 0 : Math.min(Math.floor(t * (range4.length - 1)), range4.length - 2); q = (t - index * step) / step; } else { for (index = 0; index < domain.length - 2; index++) { if (x < domain[index + 1]) { break; } } const a = domain[index]; const b = domain[index + 1]; q = (x - a) / (b - a); } const c0 = parsedRange[index]; const c1 = parsedRange[index + 1]; return interpolateOklch(c0, c1, q).toRgbaString(); } invert() { return; } refresh() { if (!this.invalid) return; this.invalid = false; this.update(); if (this.invalid) { logger_exports.warnOnce("Expected update to not invalidate scale"); } } }; __decorateClass([ Invalidating ], ColorScale.prototype, "domain", 2); __decorateClass([ Invalidating ], ColorScale.prototype, "range", 2); } }); // packages/ag-charts-community/src/scene/gradient/gradient.ts var Gradient; var init_gradient = __esm({ "packages/ag-charts-community/src/scene/gradient/gradient.ts"() { "use strict"; init_colorScale(); Gradient = class { constructor(colorSpace, stops = [], bbox) { this.colorSpace = colorSpace; this.stops = stops; this.bbox = bbox; this._cache = void 0; } createGradient(ctx, shapeBbox) { const bbox = this.bbox ?? shapeBbox; if (this._cache != null && this._cache.ctx === ctx && this._cache.bbox.equals(bbox)) { return this._cache.gradient; } const { stops, colorSpace } = this; if (stops.length === 0) return; if (stops.length === 1) return stops[0].color; let gradient2 = this.createCanvasGradient(ctx, bbox); if (gradient2 == null) return; const isOkLch = colorSpace === "oklch"; const step = 0.05; let c0 = stops[0]; gradient2.addColorStop(c0.offset, c0.color); for (let i = 1; i < stops.length; i += 1) { const c1 = stops[i]; if (isOkLch) { const scale2 = new ColorScale(); scale2.domain = [c0.offset, c1.offset]; scale2.range = [c0.color, c1.color]; for (let offset4 = c0.offset + step; offset4 < c1.offset; offset4 += step) { gradient2.addColorStop(offset4, scale2.convert(offset4)); } } gradient2.addColorStop(c1.offset, c1.color); c0 = c1; } if ("createPattern" in gradient2) { gradient2 = gradient2.createPattern(); } this._cache = { ctx, bbox, gradient: gradient2 }; return gradient2; } }; } }); // packages/ag-charts-community/src/util/angle.ts function normalizeAngle360(radians) { radians %= twoPi; radians += twoPi; radians %= twoPi; return radians; } function normalizeAngle360Inclusive(radians) { radians %= twoPi; radians += twoPi; if (radians !== twoPi) { radians %= twoPi; } return radians; } function normalizeAngle180(radians) { radians %= twoPi; if (radians < -Math.PI) { radians += twoPi; } else if (radians >= Math.PI) { radians -= twoPi; } return radians; } function isBetweenAngles(targetAngle, startAngle, endAngle) { const t = normalizeAngle360(targetAngle); const a0 = normalizeAngle360(startAngle); const a1 = normalizeAngle360(endAngle); if (a0 < a1) { return a0 <= t && t <= a1; } else if (a0 > a1) { return a0 <= t || t <= a1; } else { return true; } } function toRadians(degrees) { return degrees / 180 * Math.PI; } function toDegrees(radians) { return radians / Math.PI * 180; } function angleBetween(angle0, angle1) { angle0 = normalizeAngle360(angle0); angle1 = normalizeAngle360(angle1); return angle1 - angle0 + (angle0 > angle1 ? twoPi : 0); } function getAngleRatioRadians(angle2) { const normalizedAngle = normalizeAngle360(angle2); if (normalizedAngle <= halfPi) { return normalizedAngle / halfPi; } else if (normalizedAngle <= Math.PI) { return (Math.PI - normalizedAngle) / halfPi; } else if (normalizedAngle <= 1.5 * Math.PI) { return (normalizedAngle - Math.PI) / halfPi; } else { return (twoPi - normalizedAngle) / halfPi; } } var twoPi, halfPi; var init_angle = __esm({ "packages/ag-charts-community/src/util/angle.ts"() { "use strict"; twoPi = Math.PI * 2; halfPi = Math.PI / 2; } }); // packages/ag-charts-community/src/scene/gradient/linearGradient.ts var LinearGradient; var init_linearGradient = __esm({ "packages/ag-charts-community/src/scene/gradient/linearGradient.ts"() { "use strict"; init_angle(); init_gradient(); LinearGradient = class extends Gradient { constructor(colorSpace, stops, angle2 = 0, bbox) { super(colorSpace, stops, bbox); this.angle = angle2; } createCanvasGradient(ctx, bbox) { const angleOffset = 90; const { angle: angle2 } = this; const radians = normalizeAngle360(toRadians(angle2 + angleOffset)); const cos = Math.cos(radians); const sin = Math.sin(radians); const w = bbox.width; const h = bbox.height; const cx = bbox.x + w * 0.5; const cy = bbox.y + h * 0.5; const diagonal = Math.sqrt(h * h + w * w) / 2; const diagonalAngle = Math.atan2(h, w); let quarteredAngle; if (radians < Math.PI / 2) { quarteredAngle = radians; } else if (radians < Math.PI) { quarteredAngle = Math.PI - radians; } else if (radians < 1.5 * Math.PI) { quarteredAngle = radians - Math.PI; } else { quarteredAngle = 2 * Math.PI - radians; } const l = diagonal * Math.abs(Math.cos(quarteredAngle - diagonalAngle)); return ctx.createLinearGradient(cx + cos * l, cy + sin * l, cx - cos * l, cy - sin * l); } }; } }); // packages/ag-charts-community/src/scene/gradient/stops.ts function stopsAreAscending(fills) { let currentStop; for (const { stop } of fills) { if (stop == null) { continue; } else if (currentStop != null && stop < currentStop) { return false; } currentStop = stop; } return true; } function discreteColorStops(colorStops) { return colorStops.flatMap((colorStop, i) => { const { offset: offset4 } = colorStop; const nextColor = colorStops.at(i + 1)?.color; return nextColor != null ? [colorStop, { offset: offset4, color: nextColor }] : [colorStop]; }); } function getDefaultColorStops(defaultColorStops2, fillMode) { const stopOffset = fillMode === "discrete" ? 1 : 0; const colorStops = defaultColorStops2.map( (color, index, { length: length2 }) => ({ offset: (index + stopOffset) / (length2 - 1 + stopOffset), color }) ); return fillMode === "discrete" ? discreteColorStops(colorStops) : colorStops; } function getColorStops(fills, defaultColorStops2, domain, fillMode = "continuous") { if (fills.length === 0) { return getDefaultColorStops(defaultColorStops2, fillMode); } else if (!stopsAreAscending(fills)) { logger_exports.warnOnce(`[fills] must have the stops defined in ascending order`); return []; } const d0 = Math.min(...domain); const d1 = Math.max(...domain); const isDiscrete = fillMode === "discrete"; const offsets = new Float64Array(fills.length); let previousDefinedStopIndex = 0; let nextDefinedStopIndex = -1; for (let i = 0; i < fills.length; i += 1) { const colorStop = fills[i]; if (i >= nextDefinedStopIndex) { nextDefinedStopIndex = fills.length - 1; for (let j = i + 1; j < fills.length; j += 1) { if (fills[j].stop != null) { nextDefinedStopIndex = j; break; } } } let { stop } = colorStop; if (stop == null) { const stop0 = fills[previousDefinedStopIndex].stop; const stop1 = fills[nextDefinedStopIndex].stop; const value0 = stop0 ?? d0; const value1 = stop1 ?? d1; const stopOffset = isDiscrete && stop0 == null ? 1 : 0; stop = value0 + (value1 - value0) * (i - previousDefinedStopIndex + stopOffset) / (nextDefinedStopIndex - previousDefinedStopIndex + stopOffset); } else { previousDefinedStopIndex = i; } offsets[i] = Math.max(0, Math.min(1, (stop - d0) / (d1 - d0))); } let lastDefinedColor = fills.find((c) => c.color != null)?.color; let colorScale; const colorStops = fills.map(({ color }, i) => { const offset4 = offsets[i]; if (color != null) { lastDefinedColor = color; } else if (lastDefinedColor != null) { color = lastDefinedColor; } else { if (colorScale == null) { colorScale = new ColorScale(); colorScale.domain = [0, 1]; colorScale.range = defaultColorStops2; } color = colorScale.convert(offset4); } return { offset: offset4, color }; }); return fillMode === "discrete" ? discreteColorStops(colorStops) : colorStops; } var StopProperties; var init_stops = __esm({ "packages/ag-charts-community/src/scene/gradient/stops.ts"() { "use strict"; init_main(); init_colorScale(); init_properties(); init_validation2(); StopProperties = class extends BaseProperties { constructor() { super(...arguments); this.color = "black"; } }; __decorateClass([ Validate(NUMBER, { optional: true }) ], StopProperties.prototype, "stop", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], StopProperties.prototype, "color", 2); } }); // packages/ag-charts-community/src/scene/util/fill.ts function isGradientFill(fill) { return fill !== null && isObject(fill) && fill.type == "gradient"; } var init_fill = __esm({ "packages/ag-charts-community/src/scene/util/fill.ts"() { "use strict"; init_main(); } }); // packages/ag-charts-community/src/scene/util/pixel.ts function align(pixelRatio, start2, length2) { const alignedStart = Math.round(start2 * pixelRatio) / pixelRatio; if (length2 == null) { return alignedStart; } else if (length2 === 0) { return 0; } else if (length2 < 1) { return Math.ceil(length2 * pixelRatio) / pixelRatio; } return Math.round((length2 + start2) * pixelRatio) / pixelRatio - alignedStart; } function alignBefore(pixelRatio, start2) { return Math.floor(start2 * pixelRatio) / pixelRatio; } var init_pixel = __esm({ "packages/ag-charts-community/src/scene/util/pixel.ts"() { "use strict"; } }); // packages/ag-charts-community/src/scene/shape/shape.ts var LINEAR_GRADIENT_REGEXP, _Shape, Shape; var init_shape = __esm({ "packages/ag-charts-community/src/scene/shape/shape.ts"() { "use strict"; init_number(); init_gradient(); init_linearGradient(); init_stops(); init_node(); init_fill(); init_pixel(); LINEAR_GRADIENT_REGEXP = /^linear-gradient\((-?[\d.]+)deg,(.*?)\)$/i; _Shape = class _Shape extends Node { constructor() { super(...arguments); this.fillOpacity = 1; this.strokeOpacity = 1; this.fill = _Shape.defaultStyles.fill; this.stroke = _Shape.defaultStyles.stroke; this.strokeWidth = _Shape.defaultStyles.strokeWidth; this.lineDash = _Shape.defaultStyles.lineDash; this.lineDashOffset = _Shape.defaultStyles.lineDashOffset; this.lineCap = _Shape.defaultStyles.lineCap; this.lineJoin = _Shape.defaultStyles.lineJoin; this.miterLimit = void 0; this.opacity = _Shape.defaultStyles.opacity; this.fillShadow = _Shape.defaultStyles.fillShadow; this.gradientFillOptions = { domain: [0, 1], defaultColorRange: _Shape.defaultStyles.defaultColorRange }; } /** * Restores the default styles introduced by this subclass. */ restoreOwnStyles() { const { defaultStyles } = this.constructor; Object.assign(this, defaultStyles); } getGradient(pattern) { let linearGradientMatch; if (pattern instanceof Gradient) { return pattern; } else if (typeof pattern === "string" && pattern?.startsWith("linear-gradient") && (linearGradientMatch = LINEAR_GRADIENT_REGEXP.exec(pattern))) { const angle2 = parseFloat(linearGradientMatch[1]); const colors = []; const colorsPart = linearGradientMatch[2]; const colorRegex = /(#[0-9a-f]+)|(rgba?\(.+?\))|([a-z]+)/gi; let c; while (c = colorRegex.exec(colorsPart)) { colors.push(c[0]); } return new LinearGradient( "rgb", colors.map((color, index) => ({ color, offset: index / (colors.length - 1) })), angle2 ); } else if (isGradientFill(pattern)) { return this.createLinearGradient(pattern); } return void 0; } createLinearGradient(fill) { const { colorStops = [], direction } = fill; const isHorizontal = direction === "horizontal"; const { domain, defaultColorRange = [] } = this.gradientFillOptions; const stops = getColorStops(colorStops, defaultColorRange, domain); return new LinearGradient("oklch", stops, isHorizontal ? 0 : 90); } onFillChange() { this.fillGradient = this.getGradient(this.fill); } onStrokeChange() { this.strokeGradient = this.getGradient(this.stroke); } /** * Returns a device-pixel aligned coordinate (or length if length is supplied). * * NOTE: Not suitable for strokes, since the stroke needs to be offset to the middle * of a device pixel. */ align(start2, length2) { return align(this.layerManager?.canvas?.pixelRatio ?? 1, start2, length2); } fillStroke(ctx, path) { this.renderFill(ctx, path); this.renderStroke(ctx, path); } renderFill(ctx, path) { if (this.fill) { const { globalAlpha } = ctx; this.applyFill(ctx); this.applyFillAlpha(ctx); this.applyShadow(ctx); this.executeFill(ctx, path); ctx.globalAlpha = globalAlpha; } ctx.shadowColor = "rgba(0, 0, 0, 0)"; } executeFill(ctx, path) { if (path) { ctx.fill(path); } else { ctx.fill(); } } applyFill(ctx) { const bbox = this.gradientFillOptions.bbox ?? this.getBBox(); ctx.fillStyle = this.fillGradient?.createGradient(ctx, bbox) ?? (typeof this.fill === "string" ? this.fill : void 0) ?? "black"; } applyStroke(ctx) { ctx.strokeStyle = this.strokeGradient?.createGradient(ctx, this.getBBox()) ?? (typeof this.stroke === "string" ? this.stroke : void 0) ?? "black"; } applyFillAlpha(ctx) { ctx.globalAlpha *= this.opacity * this.fillOpacity; } applyShadow(ctx) { const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1; const fillShadow = this.fillShadow; if (fillShadow?.enabled) { ctx.shadowColor = fillShadow.color; ctx.shadowOffsetX = fillShadow.xOffset * pixelRatio; ctx.shadowOffsetY = fillShadow.yOffset * pixelRatio; ctx.shadowBlur = fillShadow.blur * pixelRatio; } } renderStroke(ctx, path) { if (this.stroke && this.strokeWidth) { const { globalAlpha } = ctx; this.applyStroke(ctx); ctx.globalAlpha *= this.opacity * this.strokeOpacity; ctx.lineWidth = this.strokeWidth; if (this.lineDash) { ctx.setLineDash(this.lineDash); } if (this.lineDashOffset) { ctx.lineDashOffset = this.lineDashOffset; } if (this.lineCap) { ctx.lineCap = this.lineCap; } if (this.lineJoin) { ctx.lineJoin = this.lineJoin; } if (this.miterLimit != null) { ctx.miterLimit = this.miterLimit; } this.executeStroke(ctx, path); ctx.globalAlpha = globalAlpha; } } executeStroke(ctx, path) { if (path) { ctx.stroke(path); } else { ctx.stroke(); } } containsPoint(x, y) { return this.isPointInPath(x, y); } applySvgFillAttributes(element2) { const { fill, fillOpacity } = this; element2.setAttribute("fill", typeof fill === "string" ? fill : "none"); element2.setAttribute("fill-opacity", String(fillOpacity)); } applySvgStrokeAttributes(element2) { const { stroke: stroke3, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this; if (stroke3 != null) { element2.setAttribute("stroke", typeof stroke3 === "string" ? stroke3 : "none"); element2.setAttribute("stroke-opacity", String(strokeOpacity)); element2.setAttribute("stroke-width", String(strokeWidth)); } if (lineDash?.some((d) => d !== 0) === true) { const svgLineDash = lineDash.length % 2 === 1 ? [...lineDash, ...lineDash] : lineDash; element2.setAttribute("stroke-dasharray", svgLineDash.join(" ")); element2.setAttribute("stroke-dashoffset", String(lineDashOffset)); } } }; /** * Defaults for style properties. Note that properties that affect the position * and shape of the node are not considered style properties, for example: * `x`, `y`, `width`, `height`, `radius`, `rotation`, etc. * Can be used to reset to the original styling after some custom styling * has been applied (using the `restoreOwnStyles` method). * These static defaults are meant to be inherited by subclasses. */ _Shape.defaultStyles = { fill: "black", stroke: void 0, strokeWidth: 0, lineDash: void 0, lineDashOffset: 0, lineCap: void 0, lineJoin: void 0, opacity: 1, fillShadow: void 0, defaultColorRange: ["#5090dc", "#ef5452"] }; __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "fillOpacity", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "strokeOpacity", 2); __decorateClass([ SceneChangeDetection({ changeCb: (s) => s.onFillChange() }) ], _Shape.prototype, "fill", 2); __decorateClass([ SceneChangeDetection({ changeCb: (s) => s.onStrokeChange() }) ], _Shape.prototype, "stroke", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "strokeWidth", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "lineDash", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "lineDashOffset", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "lineCap", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "lineJoin", 2); __decorateClass([ SceneChangeDetection() ], _Shape.prototype, "miterLimit", 2); __decorateClass([ SceneChangeDetection({ convertor: (v) => clamp(0, v, 1) }) ], _Shape.prototype, "opacity", 2); __decorateClass([ SceneChangeDetection({ checkDirtyOnAssignment: true }) ], _Shape.prototype, "fillShadow", 2); __decorateClass([ SceneChangeDetection({ changeCb: (s) => s.onFillChange() }) ], _Shape.prototype, "gradientFillOptions", 2); Shape = _Shape; } }); // packages/ag-charts-community/src/scene/matrix.ts var IDENTITY_MATRIX_ELEMENTS, Matrix; var init_matrix = __esm({ "packages/ag-charts-community/src/scene/matrix.ts"() { "use strict"; init_number(); init_bbox(); IDENTITY_MATRIX_ELEMENTS = [1, 0, 0, 1, 0, 0]; Matrix = class _Matrix { get e() { return [...this.elements]; } constructor(elements = IDENTITY_MATRIX_ELEMENTS) { this.elements = [...elements]; } setElements(elements) { const e = this.elements; e[0] = elements[0]; e[1] = elements[1]; e[2] = elements[2]; e[3] = elements[3]; e[4] = elements[4]; e[5] = elements[5]; return this; } get identity() { const e = this.elements; return isNumberEqual(e[0], 1) && isNumberEqual(e[1], 0) && isNumberEqual(e[2], 0) && isNumberEqual(e[3], 1) && isNumberEqual(e[4], 0) && isNumberEqual(e[5], 0); } /** * Performs the AxB matrix multiplication and saves the result * to `C`, if given, or to `A` otherwise. */ AxB(A, B, C2) { const a = A[0] * B[0] + A[2] * B[1], b = A[1] * B[0] + A[3] * B[1], c = A[0] * B[2] + A[2] * B[3], d = A[1] * B[2] + A[3] * B[3], e = A[0] * B[4] + A[2] * B[5] + A[4], f = A[1] * B[4] + A[3] * B[5] + A[5]; C2 = C2 ?? A; C2[0] = a; C2[1] = b; C2[2] = c; C2[3] = d; C2[4] = e; C2[5] = f; } /** * The `other` matrix gets post-multiplied to the current matrix. * Returns the current matrix. * @param other */ multiplySelf(other) { this.AxB(this.elements, other.elements); return this; } /** * The `other` matrix gets post-multiplied to the current matrix. * Returns a new matrix. * @param other */ multiply(other) { const elements = new Array(6); if (other instanceof _Matrix) { this.AxB(this.elements, other.elements, elements); } else { this.AxB(this.elements, [other.a, other.b, other.c, other.d, other.e, other.f], elements); } return new _Matrix(elements); } preMultiplySelf(other) { this.AxB(other.elements, this.elements, this.elements); return this; } /** * Returns the inverse of this matrix as a new matrix. */ inverse() { const el = this.elements; let a = el[0], b = el[1], c = el[2], d = el[3]; const e = el[4], f = el[5]; const rD = 1 / (a * d - b * c); a *= rD; b *= rD; c *= rD; d *= rD; return new _Matrix([d, -b, -c, a, c * f - d * e, b * e - a * f]); } invertSelf() { const el = this.elements; let a = el[0], b = el[1], c = el[2], d = el[3]; const e = el[4], f = el[5]; const rD = 1 / (a * d - b * c); a *= rD; b *= rD; c *= rD; d *= rD; el[0] = d; el[1] = -b; el[2] = -c; el[3] = a; el[4] = c * f - d * e; el[5] = b * e - a * f; return this; } transformPoint(x, y) { const e = this.elements; return { x: x * e[0] + y * e[2] + e[4], y: x * e[1] + y * e[3] + e[5] }; } transformBBox(bbox, target) { const el = this.elements; const xx = el[0]; const xy = el[1]; const yx = el[2]; const yy = el[3]; const h_w = bbox.width * 0.5; const h_h = bbox.height * 0.5; const cx = bbox.x + h_w; const cy = bbox.y + h_h; const w = Math.abs(h_w * xx) + Math.abs(h_h * yx); const h = Math.abs(h_w * xy) + Math.abs(h_h * yy); target ?? (target = new BBox(0, 0, 0, 0)); target.x = cx * xx + cy * yx + el[4] - w; target.y = cx * xy + cy * yy + el[5] - h; target.width = w + w; target.height = h + h; return target; } toContext(ctx) { if (this.identity) { return; } const e = this.elements; ctx.transform(e[0], e[1], e[2], e[3], e[4], e[5]); } static updateTransformMatrix(matrix, scalingX, scalingY, rotation, translationX, translationY, opts) { const sx = scalingX; const sy = scalingY; let scx; let scy; if (sx === 1 && sy === 1) { scx = 0; scy = 0; } else { scx = opts?.scalingCenterX ?? 0; scy = opts?.scalingCenterY ?? 0; } const r = rotation; const cos = Math.cos(r); const sin = Math.sin(r); let rcx; let rcy; if (r === 0) { rcx = 0; rcy = 0; } else { rcx = opts?.rotationCenterX ?? 0; rcy = opts?.rotationCenterY ?? 0; } const tx = translationX; const ty = translationY; const tx4 = scx * (1 - sx) - rcx; const ty4 = scy * (1 - sy) - rcy; matrix.setElements([ cos * sx, sin * sx, -sin * sy, cos * sy, cos * tx4 - sin * ty4 + rcx + tx, sin * tx4 + cos * ty4 + rcy + ty ]); return matrix; } }; } }); // packages/ag-charts-community/src/scene/transformable.ts function isMatrixTransform(node) { return isMatrixTransformType(node.constructor); } function isMatrixTransformType(cstr) { return cstr[MATRIX_TRANSFORM_TYPE] === true; } function MatrixTransform(Parent) { var _a, _b; const ParentNode = Parent; if (isMatrixTransformType(Parent)) { return Parent; } const TRANSFORM_MATRIX = Symbol("matrix_combined_transform"); class MatrixTransformInternal extends ParentNode { constructor() { super(...arguments); this[_b] = new Matrix(); this._dirtyTransform = true; } markDirtyTransform() { this._dirtyTransform = true; super.markDirty(); } updateMatrix(_matrix) { } computeTransformMatrix() { if (!this._dirtyTransform) return; this[TRANSFORM_MATRIX].setElements(IDENTITY_MATRIX_ELEMENTS); this.updateMatrix(this[TRANSFORM_MATRIX]); this._dirtyTransform = false; } toParent(bbox) { this.computeTransformMatrix(); if (this[TRANSFORM_MATRIX].identity) return bbox.clone(); return this[TRANSFORM_MATRIX].transformBBox(bbox); } toParentPoint(x, y) { this.computeTransformMatrix(); if (this[TRANSFORM_MATRIX].identity) return { x, y }; return this[TRANSFORM_MATRIX].transformPoint(x, y); } fromParent(bbox) { this.computeTransformMatrix(); if (this[TRANSFORM_MATRIX].identity) return bbox.clone(); return this[TRANSFORM_MATRIX].inverse().transformBBox(bbox); } fromParentPoint(x, y) { this.computeTransformMatrix(); if (this[TRANSFORM_MATRIX].identity) return { x, y }; return this[TRANSFORM_MATRIX].inverse().transformPoint(x, y); } computeBBox() { const bbox = super.computeBBox(); if (!bbox) return bbox; return this.toParent(bbox); } computeBBoxWithoutTransforms() { return super.computeBBox(); } pickNode(x, y, localCoords = false) { if (!localCoords) { ({ x, y } = this.fromParentPoint(x, y)); } return super.pickNode(x, y); } render(renderCtx) { this.computeTransformMatrix(); const { ctx } = renderCtx; const matrix = this[TRANSFORM_MATRIX]; let performRestore = false; if (!matrix.identity) { ctx.save(); performRestore = true; matrix.toContext(ctx); } super.render(renderCtx); if (performRestore) { ctx.restore(); } } toSVG() { this.computeTransformMatrix(); const svg = super.toSVG(); const matrix = this[TRANSFORM_MATRIX]; if (matrix.identity || svg == null) return svg; const g = createSvgElement("g"); g.append(...svg.elements); const [a, b, c, d, e, f] = matrix.e; g.setAttribute("transform", `matrix(${a} ${b} ${c} ${d} ${e} ${f})`); return { elements: [g], defs: svg.defs }; } } _a = MATRIX_TRANSFORM_TYPE, _b = TRANSFORM_MATRIX; MatrixTransformInternal[_a] = true; return MatrixTransformInternal; } function Rotatable(Parent) { var _a; const ParentNode = Parent; const ROTATABLE_MATRIX = Symbol("matrix_rotation"); class RotatableInternal extends MatrixTransform(ParentNode) { constructor() { super(...arguments); this[_a] = new Matrix(); this.rotationCenterX = null; this.rotationCenterY = null; this.rotation = 0; } updateMatrix(matrix) { super.updateMatrix(matrix); const { rotation, rotationCenterX, rotationCenterY } = this; if (rotation === 0) return; Matrix.updateTransformMatrix(this[ROTATABLE_MATRIX], 1, 1, rotation, 0, 0, { rotationCenterX, rotationCenterY }); matrix.multiplySelf(this[ROTATABLE_MATRIX]); } } _a = ROTATABLE_MATRIX; __decorateClass([ SceneChangeDetection({ type: "transform" }) ], RotatableInternal.prototype, "rotationCenterX", 2); __decorateClass([ SceneChangeDetection({ type: "transform" }) ], RotatableInternal.prototype, "rotationCenterY", 2); __decorateClass([ SceneChangeDetection({ type: "transform" }) ], RotatableInternal.prototype, "rotation", 2); return RotatableInternal; } function Scalable(Parent) { var _a; const ParentNode = Parent; const SCALABLE_MATRIX = Symbol("matrix_scale"); class ScalableInternal extends MatrixTransform(ParentNode) { constructor() { super(...arguments); this[_a] = new Matrix(); this.scalingX = 1; this.scalingY = 1; this.scalingCenterX = null; this.scalingCenterY = null; } updateMatrix(matrix) { super.updateMatrix(matrix); const { scalingX, scalingY, scalingCenterX, scalingCenterY } = this; if (scalingX === 1 && scalingY === 1) return; Matrix.updateTransformMatrix(this[SCALABLE_MATRIX], scalingX, scalingY, 0, 0, 0, { scalingCenterX, scalingCenterY }); matrix.multiplySelf(this[SCALABLE_MATRIX]); } } _a = SCALABLE_MATRIX; __decorateClass([ SceneChangeDetection({ type: "transform" }) ], ScalableInternal.prototype, "scalingX", 2); __decorateClass([ SceneChangeDetection({ type: "transform" }) ], ScalableInternal.prototype, "scalingY", 2); __decorateClass([ SceneChangeDetection({ type: "transform" }) ], ScalableInternal.prototype, "scalingCenterX", 2); __decorateClass([ SceneChangeDetection({ type: "transform" }) ], ScalableInternal.prototype, "scalingCenterY", 2); return ScalableInternal; } function Translatable(Parent) { var _a; const ParentNode = Parent; const TRANSLATABLE_MATRIX = Symbol("matrix_translation"); class TranslatableInternal extends MatrixTransform(ParentNode) { constructor() { super(...arguments); this[_a] = new Matrix(); this.translationX = 0; this.translationY = 0; } updateMatrix(matrix) { super.updateMatrix(matrix); const { translationX, translationY } = this; if (translationX === 0 && translationY === 0) return; Matrix.updateTransformMatrix(this[TRANSLATABLE_MATRIX], 1, 1, 0, translationX, translationY); matrix.multiplySelf(this[TRANSLATABLE_MATRIX]); } } _a = TRANSLATABLE_MATRIX; __decorateClass([ SceneChangeDetection({ type: "transform" }) ], TranslatableInternal.prototype, "translationX", 2); __decorateClass([ SceneChangeDetection({ type: "transform" }) ], TranslatableInternal.prototype, "translationY", 2); return TranslatableInternal; } var MATRIX_TRANSFORM_TYPE, Transformable; var init_transformable = __esm({ "packages/ag-charts-community/src/scene/transformable.ts"() { "use strict"; init_core(); init_matrix(); init_node(); MATRIX_TRANSFORM_TYPE = Symbol("isMatrixTransform"); Transformable = class { /** * Converts a BBox from canvas coordinate space into the coordinate space of the given Node. */ static fromCanvas(node, bbox) { const parents = []; for (const parent of node.traverseUp()) { if (isMatrixTransform(parent)) { parents.unshift(parent); } } for (const parent of parents) { bbox = parent.fromParent(bbox); } if (isMatrixTransform(node)) { bbox = node.fromParent(bbox); } return bbox; } /** * Converts a Nodes BBox (or an arbitrary BBox if supplied) from local Node coordinate space * into the Canvas coordinate space. */ static toCanvas(node, bbox) { if (bbox == null) { bbox = node.getBBox(); } else if (isMatrixTransform(node)) { bbox = node.toParent(bbox); } for (const parent of node.traverseUp()) { if (isMatrixTransform(parent)) { bbox = parent.toParent(bbox); } } return bbox; } /** * Converts a point from canvas coordinate space into the coordinate space of the given Node. */ static fromCanvasPoint(node, x, y) { const parents = []; for (const parent of node.traverseUp()) { if (isMatrixTransform(parent)) { parents.unshift(parent); } } for (const parent of parents) { ({ x, y } = parent.fromParentPoint(x, y)); } if (isMatrixTransform(node)) { ({ x, y } = node.fromParentPoint(x, y)); } return { x, y }; } /** * Converts a point from a Nodes local coordinate space into the Canvas coordinate space. */ static toCanvasPoint(node, x, y) { if (isMatrixTransform(node)) { ({ x, y } = node.toParentPoint(x, y)); } for (const parent of node.traverseUp()) { if (isMatrixTransform(parent)) { ({ x, y } = parent.toParentPoint(x, y)); } } return { x, y }; } }; } }); // packages/ag-charts-community/src/scene/zIndex.ts function compareZIndex(a, b) { if (typeof a === "number" && typeof b === "number") { return cmp(a, b); } const aArray = typeof a === "number" ? [a] : a; const bArray = typeof b === "number" ? [b] : b; const length2 = Math.min(aArray.length, bArray.length); for (let i = 0; i < length2; i += 1) { const diff8 = cmp(aArray[i], bArray[i]); if (diff8 !== 0) return diff8; } return cmp(aArray.length, bArray.length); } var cmp; var init_zIndex = __esm({ "packages/ag-charts-community/src/scene/zIndex.ts"() { "use strict"; cmp = (a, b) => Math.sign(a - b); } }); // packages/ag-charts-community/src/scene/group.ts var sharedOffscreenCanvas, _Group, Group, ScalableGroup, RotatableGroup, TranslatableGroup, TransformableGroup; var init_group = __esm({ "packages/ag-charts-community/src/scene/group.ts"() { "use strict"; init_number(); init_bbox(); init_hdpiOffscreenCanvas(); init_node(); init_shape(); init_transformable(); init_pixel(); init_zIndex(); _Group = class _Group extends Node { // optimizeForInfrequentRedraws: true constructor(opts) { super(opts); this.opacity = 1; this.renderToOffscreenCanvas = false; this.optimizeForInfrequentRedraws = false; // Used when renderToOffscreenCanvas: true this.layer = void 0; // optimizeForInfrequentRedraws: false this.image = void 0; this._lastWidth = NaN; this._lastHeight = NaN; this._lastDevicePixelRatio = NaN; this.isContainerNode = true; this.renderToOffscreenCanvas = opts?.renderToOffscreenCanvas === true; } static is(value) { return value instanceof _Group; } static computeChildrenBBox(nodes, skipInvisible = true) { return BBox.merge(Node.extractBBoxes(nodes, skipInvisible)); } static compareChildren(a, b) { return compareZIndex(a.zIndex, b.zIndex) || a.serialNumber - b.serialNumber; } // We consider a group to be boundless, thus any point belongs to it. containsPoint(_x, _y) { return true; } computeBBox() { return _Group.computeChildrenBBox(this.children()); } computeSafeClippingBBox(pixelRatio) { const bbox = this.computeBBox(); if (!bbox.isFinite()) return; let strokeWidth = 0; const strokeMiterAmount = 4; for (const child of this.descendants()) { if (child instanceof Shape) { strokeWidth = Math.max(strokeWidth, child.strokeWidth); } } const padding = Math.max( // Account for anti-aliasing artefacts 1, // Account for strokes (incl. miters) - this may not be the best place to include this strokeWidth / 2 * strokeMiterAmount ); const { x: originX, y: originY } = Transformable.toCanvasPoint(this, 0, 0); const x = alignBefore(pixelRatio, originX + bbox.x - padding) - originX; const y = alignBefore(pixelRatio, originY + bbox.y - padding) - originY; const width2 = Math.ceil(bbox.x + bbox.width - x + padding); const height2 = Math.ceil(bbox.y + bbox.height - y + padding); return new BBox(x, y, width2, height2); } prepareSharedCanvas(width2, height2, pixelRatio) { if (sharedOffscreenCanvas == null || sharedOffscreenCanvas.pixelRatio !== pixelRatio) { sharedOffscreenCanvas = new HdpiOffscreenCanvas({ width: width2, height: height2, pixelRatio }); } else { sharedOffscreenCanvas.resize(width2, height2, pixelRatio); } return sharedOffscreenCanvas; } isDirty(renderCtx) { const { width: width2, height: height2, devicePixelRatio } = renderCtx; const { dirty, dirtyZIndex, layer } = this; const layerResized = layer != null && (this._lastWidth !== width2 || this._lastHeight !== height2); const pixelRatioChanged = this._lastDevicePixelRatio !== devicePixelRatio; this._lastWidth = width2; this._lastHeight = height2; this._lastDevicePixelRatio = devicePixelRatio; if (dirty || dirtyZIndex || layerResized || pixelRatioChanged) return true; for (const child of this.children()) { if (child.dirty) return true; } return false; } preRender(renderCtx) { const counts = super.preRender(renderCtx, 0); counts.groups += 1; counts.nonGroups -= 1; if (this.renderToOffscreenCanvas && !this.optimizeForInfrequentRedraws && counts.nonGroups > 0 && this.getVisibility()) { this.layer ?? (this.layer = this._layerManager?.addLayer({ name: this.name })); } else if (this.layer != null) { this._layerManager?.removeLayer(this.layer); this.layer = void 0; } return counts; } render(renderCtx) { const { layer, renderToOffscreenCanvas } = this; const childRenderCtx = { ...renderCtx }; if (!renderToOffscreenCanvas) { this.renderInContext(childRenderCtx); super.render(childRenderCtx); return; } const { ctx, stats, devicePixelRatio: pixelRatio } = renderCtx; let { image } = this; if (this.isDirty(renderCtx)) { image?.bitmap.close(); image = void 0; const bbox = layer ? void 0 : this.computeSafeClippingBBox(pixelRatio); const renderOffscreen = (offscreenCanvas, ...transform) => { const offscreenCtx = offscreenCanvas.context; childRenderCtx.ctx = offscreenCtx; offscreenCanvas.clear(); offscreenCtx.save(); offscreenCtx.setTransform(...transform); offscreenCtx.globalAlpha = 1; this.renderInContext(childRenderCtx); offscreenCtx.restore(); offscreenCtx.verifyDepthZero?.(); }; if (layer) { renderOffscreen(layer, ctx.getTransform()); } else if (bbox) { const { x, y, width: width2, height: height2 } = bbox; const canvas = this.prepareSharedCanvas(width2, height2, pixelRatio); renderOffscreen(canvas, pixelRatio, 0, 0, pixelRatio, -x * pixelRatio, -y * pixelRatio); image = { bitmap: canvas.transferToImageBitmap(), x, y, width: width2, height: height2 }; } else if (this.dirtyZIndex) { this.sortChildren(_Group.compareChildren); } this.image = image; if (stats) stats.layersRendered++; } else { this.skipRender(childRenderCtx); if (stats) stats.layersSkipped++; } const { globalAlpha } = ctx; ctx.globalAlpha = globalAlpha * this.opacity; if (layer) { ctx.save(); ctx.resetTransform(); layer.drawImage(ctx); ctx.restore(); } else if (image) { const { bitmap, x, y, width: width2, height: height2 } = image; ctx.drawImage(bitmap, 0, 0, width2 * pixelRatio, height2 * pixelRatio, x, y, width2, height2); } ctx.globalAlpha = globalAlpha; super.render(childRenderCtx); } skipRender(childRenderCtx) { const { stats } = childRenderCtx; for (const child of this.children()) { child.markClean(); if (stats) { stats.nodesSkipped += this.childNodeCounts.groups + this.childNodeCounts.nonGroups; stats.opsSkipped += this.childNodeCounts.complexity; } } } applyClip(ctx, clipRect) { const { x, y, width: width2, height: height2 } = clipRect; ctx.beginPath(); ctx.rect(x, y, width2, height2); ctx.clip(); } renderInContext(childRenderCtx) { const { ctx, stats } = childRenderCtx; if (this.dirtyZIndex) { this.sortChildren(_Group.compareChildren); } ctx.save(); ctx.globalAlpha *= this.opacity; if (this.clipRect != null) { this.applyClip(ctx, this.clipRect); childRenderCtx.clipBBox = Transformable.toCanvas(this, this.clipRect); } for (const child of this.children()) { if (!child.visible) { child.markClean(); if (stats) { stats.nodesSkipped += child.childNodeCounts.nonGroups + child.childNodeCounts.groups; stats.opsSkipped += child.childNodeCounts.complexity; } continue; } ctx.save(); child.render(childRenderCtx); ctx.restore(); } ctx.restore(); } /** * Transforms bbox given in the canvas coordinate space to bbox in this group's coordinate space and * sets this group's clipRect to the transformed bbox. * @param bbox clipRect bbox in the canvas coordinate space. */ setClipRect(bbox) { this.clipRect = bbox ? Transformable.fromCanvas(this, bbox) : void 0; } /** * Set the clip rect within the canvas coordinate space. * @param bbox clipRect bbox in the canvas coordinate space. */ setClipRectCanvasSpace(bbox) { this.clipRect = bbox; } _setLayerManager(layersManager) { if (this.layer) { this._layerManager?.removeLayer(this.layer); this.layer = void 0; } super._setLayerManager(layersManager); } getVisibility() { for (const node of this.traverseUp(true)) { if (!node.visible) { return false; } } return true; } toSVG() { if (!this.visible) return; const defs = []; const elements = []; for (const child of this.children()) { const svg = child.toSVG(); if (svg != null) { elements.push(...svg.elements); if (svg.defs != null) { defs.push(...svg.defs); } } } return { elements, defs }; } }; _Group.className = "Group"; __decorateClass([ SceneChangeDetection({ convertor: (v) => clamp(0, v, 1) }) ], _Group.prototype, "opacity", 2); Group = _Group; ScalableGroup = class extends Scalable(Group) { }; RotatableGroup = class extends Rotatable(Group) { }; TranslatableGroup = class extends Translatable(Group) { }; TransformableGroup = class extends Rotatable(Translatable(Group)) { }; } }); // packages/ag-charts-community/src/util/canvas.util.ts function createCanvasContext(width2 = 0, height2 = 0) { return new OffscreenCanvas(width2, height2).getContext("2d"); } var init_canvas_util = __esm({ "packages/ag-charts-community/src/util/canvas.util.ts"() { "use strict"; } }); // packages/ag-charts-community/src/util/lruCache.ts var LRUCache; var init_lruCache = __esm({ "packages/ag-charts-community/src/util/lruCache.ts"() { "use strict"; LRUCache = class { constructor(maxCacheSize = 5) { this.maxCacheSize = maxCacheSize; this.store = /* @__PURE__ */ new Map(); } get(key) { if (!this.store.has(key)) return void 0; const hit = this.store.get(key); this.store.delete(key); this.store.set(key, hit); return hit; } has(key) { return this.store.has(key); } set(key, value) { this.store.set(key, value); if (this.store.size > this.maxCacheSize) { const iterator = this.store.keys(); let evictCount = this.store.size - this.maxCacheSize; while (evictCount > 0) { const evictKeyIterator = iterator.next(); if (!evictKeyIterator.done) { this.store.delete(evictKeyIterator.value); } evictCount--; } } return value; } clear() { this.store.clear(); } }; } }); // packages/ag-charts-community/src/util/textMeasurer.ts var CachedTextMeasurerPool, CachedTextMeasurer, TextUtils, SimpleTextMeasurer; var init_textMeasurer = __esm({ "packages/ag-charts-community/src/util/textMeasurer.ts"() { "use strict"; init_canvas_util(); init_lruCache(); CachedTextMeasurerPool = class { // Measures the dimensions of the provided text, handling multiline if needed. static measureText(text3, options) { const textMeasurer = this.getMeasurer(options); return textMeasurer.measureText(text3); } static measureLines(text3, options) { const textMeasurer = this.getMeasurer(options); return textMeasurer.measureLines(text3); } // Gets a TextMeasurer instance, configuring text alignment and baseline if provided. static getMeasurer(options) { const font3 = typeof options.font === "string" ? options.font : TextUtils.toFontString(options.font); const key = `${font3}-${options.textAlign ?? "start"}-${options.textBaseline ?? "alphabetic"}`; return this.instanceMap.get(key) ?? this.createFontMeasurer(font3, options, key); } // Creates or retrieves a TextMeasurer instance for a specific font. static createFontMeasurer(font3, options, key) { const ctx = createCanvasContext(); ctx.font = font3; ctx.textAlign = options.textAlign ?? "start"; ctx.textBaseline = options.textBaseline ?? "alphabetic"; const measurer3 = new CachedTextMeasurer(ctx, options); this.instanceMap.set(key, measurer3); return measurer3; } }; CachedTextMeasurerPool.instanceMap = new LRUCache(10); CachedTextMeasurer = class { constructor(ctx, options) { this.ctx = ctx; // cached text measurements this.measureMap = new LRUCache(100); if (options.textAlign) { ctx.textAlign = options.textAlign; } if (options.textBaseline) { ctx.textBaseline = options.textBaseline; } ctx.font = typeof options.font === "string" ? options.font : TextUtils.toFontString(options.font); this.textMeasurer = new SimpleTextMeasurer( (t) => this.cachedCtxMeasureText(t), options.textBaseline ?? "alphabetic" ); } textWidth(text3, estimate) { return this.textMeasurer.textWidth(text3, estimate); } measureText(text3) { return this.textMeasurer.measureText(text3); } measureLines(text3) { return this.textMeasurer.measureLines(text3); } cachedCtxMeasureText(text3) { if (!this.measureMap.has(text3)) { const rawResult = this.ctx.measureText(text3); this.measureMap.set(text3, { actualBoundingBoxAscent: rawResult.actualBoundingBoxAscent, emHeightAscent: rawResult.emHeightAscent, emHeightDescent: rawResult.emHeightDescent, actualBoundingBoxDescent: rawResult.actualBoundingBoxDescent, actualBoundingBoxLeft: rawResult.actualBoundingBoxLeft, actualBoundingBoxRight: rawResult.actualBoundingBoxRight, alphabeticBaseline: rawResult.alphabeticBaseline, fontBoundingBoxAscent: rawResult.fontBoundingBoxAscent, fontBoundingBoxDescent: rawResult.fontBoundingBoxDescent, hangingBaseline: rawResult.hangingBaseline, ideographicBaseline: rawResult.ideographicBaseline, width: rawResult.width }); } return this.measureMap.get(text3); } }; TextUtils = class { static toFontString({ fontSize = 10, fontStyle, fontWeight, fontFamily, lineHeight }) { let fontString = ""; if (fontStyle) { fontString += `${fontStyle} `; } if (fontWeight) { fontString += `${fontWeight} `; } fontString += `${fontSize}px`; if (lineHeight) { fontString += `/${lineHeight}px`; } fontString += ` ${fontFamily}`; return fontString.trim(); } static getLineHeight(fontSize) { return Math.ceil(fontSize * this.defaultLineHeight); } // Determines vertical offset modifier based on text baseline. static getVerticalModifier(textBaseline) { switch (textBaseline) { case "hanging": case "top": return 0; case "middle": return 0.5; case "alphabetic": case "bottom": case "ideographic": default: return 1; } } }; TextUtils.EllipsisChar = "\u2026"; // Representation for text clipping. TextUtils.defaultLineHeight = 1.15; // Normally between 1.1 and 1.2 TextUtils.lineSplitter = /\r?\n/g; SimpleTextMeasurer = class { constructor(measureTextFn, textBaseline = "alphabetic") { this.measureTextFn = measureTextFn; this.textBaseline = textBaseline; // local chars width cache per TextMeasurer this.charMap = /* @__PURE__ */ new Map(); } // Measures metrics for a single line of text. getMetrics(text3) { const m = this.measureTextFn(text3); m.fontBoundingBoxAscent ?? (m.fontBoundingBoxAscent = m.emHeightAscent); m.fontBoundingBoxDescent ?? (m.fontBoundingBoxDescent = m.emHeightDescent); return { width: m.width, height: m.actualBoundingBoxAscent + m.actualBoundingBoxDescent, lineHeight: m.fontBoundingBoxAscent + m.fontBoundingBoxDescent, offsetTop: m.actualBoundingBoxAscent, offsetLeft: m.actualBoundingBoxLeft }; } // Calculates aggregated metrics for multiline text. getMultilineMetrics(lines) { let width2 = 0; let height2 = 0; let offsetTop = 0; let offsetLeft = 0; let baselineDistance = 0; const verticalModifier = TextUtils.getVerticalModifier(this.textBaseline); const lineMetrics = []; let index = 0; const length2 = lines.length; for (const line of lines) { const m = this.measureTextFn(line); m.fontBoundingBoxAscent ?? (m.fontBoundingBoxAscent = m.emHeightAscent); m.fontBoundingBoxDescent ?? (m.fontBoundingBoxDescent = m.emHeightDescent); if (width2 < m.width) { width2 = m.width; } if (offsetLeft < m.actualBoundingBoxLeft) { offsetLeft = m.actualBoundingBoxLeft; } if (index === 0) { height2 += m.actualBoundingBoxAscent; offsetTop += m.actualBoundingBoxAscent; } else { baselineDistance += m.fontBoundingBoxAscent; } if (index === length2 - 1) { height2 += m.actualBoundingBoxDescent; } else { baselineDistance += m.fontBoundingBoxDescent; } lineMetrics.push({ text: line, width: m.width, height: m.actualBoundingBoxAscent + m.actualBoundingBoxDescent, lineHeight: m.fontBoundingBoxAscent + m.fontBoundingBoxDescent, offsetTop: m.actualBoundingBoxAscent, offsetLeft: m.actualBoundingBoxLeft }); index++; } height2 += baselineDistance; offsetTop += baselineDistance * verticalModifier; return { width: width2, height: height2, offsetTop, offsetLeft, lineMetrics }; } textWidth(text3, estimate) { if (estimate) { let estimatedWidth = 0; for (let i = 0; i < text3.length; i++) { estimatedWidth += this.textWidth(text3.charAt(i)); } return estimatedWidth; } if (text3.length > 1) { return this.measureTextFn(text3).width; } return this.charMap.get(text3) ?? this.charWidth(text3); } measureText(text3) { return this.getMetrics(text3); } // Measures the dimensions of the provided text, handling multiline if needed. measureLines(text3) { const lines = typeof text3 === "string" ? text3.split(TextUtils.lineSplitter) : text3; return this.getMultilineMetrics(lines); } charWidth(char) { const { width: width2 } = this.measureTextFn(char); this.charMap.set(char, width2); return width2; } }; } }); // packages/ag-charts-community/src/scene/shape/text.ts var _Text, Text, RotatableText, TransformableText; var init_text = __esm({ "packages/ag-charts-community/src/scene/shape/text.ts"() { "use strict"; init_core(); init_textMeasurer(); init_bbox(); init_node(); init_transformable(); init_shape(); _Text = class _Text extends Shape { constructor() { super(...arguments); this.x = 0; this.y = 0; this.lines = []; this.text = void 0; this.fontSize = 10; this.fontFamily = "sans-serif"; this.textAlign = _Text.defaultStyles.textAlign; this.textBaseline = _Text.defaultStyles.textBaseline; } onTextChange() { this.lines = this.text?.split("\n").map((s) => s.trim()) ?? []; } static computeBBox(lines, x, y, opts) { const { offsetTop, offsetLeft, width: width2, height: height2 } = CachedTextMeasurerPool.measureLines(lines, opts); return new BBox(x - offsetLeft, y - offsetTop, width2, height2); } computeBBox() { const { x, y, lines, textBaseline, textAlign } = this; return _Text.computeBBox(lines, x, y, { font: this, textBaseline, textAlign }); } isPointInPath(x, y) { const bbox = this.getBBox(); return bbox ? bbox.containsPoint(x, y) : false; } render(renderCtx) { const { ctx, stats } = renderCtx; if (!this.lines.length || !this.layerManager) { if (stats) stats.nodesSkipped += 1; return super.render(renderCtx); } const { fill, stroke: stroke3, strokeWidth } = this; const { pixelRatio } = this.layerManager.canvas; ctx.font = TextUtils.toFontString(this); ctx.textAlign = this.textAlign; ctx.textBaseline = this.textBaseline; if (fill) { this.applyFill(ctx); ctx.globalAlpha *= this.opacity * this.fillOpacity; const { fillShadow } = this; if (fillShadow?.enabled) { ctx.shadowColor = fillShadow.color; ctx.shadowOffsetX = fillShadow.xOffset * pixelRatio; ctx.shadowOffsetY = fillShadow.yOffset * pixelRatio; ctx.shadowBlur = fillShadow.blur * pixelRatio; } this.renderLines((line, x, y) => ctx.fillText(line, x, y)); } if (stroke3 && strokeWidth) { this.applyStroke(ctx); ctx.lineWidth = strokeWidth; ctx.globalAlpha *= this.opacity * this.strokeOpacity; const { lineDash, lineDashOffset, lineCap, lineJoin } = this; if (lineDash) { ctx.setLineDash(lineDash); } if (lineDashOffset) { ctx.lineDashOffset = lineDashOffset; } if (lineCap) { ctx.lineCap = lineCap; } if (lineJoin) { ctx.lineJoin = lineJoin; } this.renderLines((line, x, y) => ctx.strokeText(line, x, y)); } super.render(renderCtx); } renderLines(renderCallback) { const { lines, x, y } = this; const lineHeight = this.lineHeight ?? TextUtils.getLineHeight(this.fontSize); let offsetY = (lineHeight - lineHeight * lines.length) * TextUtils.getVerticalModifier(this.textBaseline); for (const line of lines) { renderCallback(line, x, y + offsetY); offsetY += lineHeight; } } setFont(props) { this.fontFamily = props.fontFamily; this.fontSize = props.fontSize; this.fontStyle = props.fontStyle; this.fontWeight = props.fontWeight; } setAlign(props) { this.textAlign = props.textAlign; this.textBaseline = props.textBaseline; } toSVG() { if (!this.visible || !this.text) return; const element2 = createSvgElement("text"); this.applySvgFillAttributes(element2); element2.setAttribute("font-family", this.fontFamily?.split(",")[0] ?? ""); element2.setAttribute("font-size", String(this.fontSize)); element2.setAttribute("font-style", this.fontStyle ?? ""); element2.setAttribute("font-weight", String(this.fontWeight ?? "")); element2.setAttribute( "text-anchor", { center: "middle", left: "start", right: "end", start: "start", end: "end" }[this.textAlign ?? "start"] ); element2.setAttribute( "alignment-baseline", { alphabetic: "alphabetic", top: "top", bottom: "bottom", hanging: "hanging", middle: "middle", ideographic: "ideographic" }[this.textBaseline ?? "alphabetic"] ); element2.setAttribute("x", String(this.x)); element2.setAttribute("y", String(this.y)); element2.textContent = this.text ?? ""; return { elements: [element2] }; } }; _Text.className = "Text"; _Text.defaultStyles = { ...Shape.defaultStyles, textAlign: "start", fontStyle: void 0, fontWeight: void 0, fontSize: 10, fontFamily: "sans-serif", textBaseline: "alphabetic" }; __decorateClass([ SceneChangeDetection() ], _Text.prototype, "x", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "y", 2); __decorateClass([ SceneChangeDetection({ changeCb: (o) => o.onTextChange() }) ], _Text.prototype, "text", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "fontStyle", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "fontWeight", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "fontSize", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "fontFamily", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "textAlign", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "textBaseline", 2); __decorateClass([ SceneChangeDetection() ], _Text.prototype, "lineHeight", 2); Text = _Text; RotatableText = class extends Rotatable(Text) { }; TransformableText = class extends Rotatable(Translatable(Text)) { }; } }); // packages/ag-charts-community/src/util/stateMachine.ts function StateMachineProperty() { return addObserverToInstanceProperty(() => { }); } function applyProperties(parentState, childState) { const childProperties = listDecoratedProperties(childState); if (childProperties.length === 0) return; const properties = extractDecoratedProperties(parentState); for (const property of childProperties) { if (property in properties) { childState[property] = properties[property]; } } } var debugColor, debugQuietColor, AbstractStateMachine, _StateMachine, StateMachine, ParallelStateMachine; var init_stateMachine = __esm({ "packages/ag-charts-community/src/util/stateMachine.ts"() { "use strict"; init_debug(); init_decorator(); debugColor = "color: green"; debugQuietColor = "color: grey"; AbstractStateMachine = class { transitionRoot(event, data) { if (this.parent) { this.parent.transitionRoot(event, data); } else { this.transition(event, data); } } }; _StateMachine = class _StateMachine extends AbstractStateMachine { constructor(defaultState, states, enterEach) { super(); this.defaultState = defaultState; this.states = states; this.enterEach = enterEach; this.debug = Debug.create(true, "animation"); this.state = defaultState; this.debug(`%c${this.constructor.name} | init -> ${defaultState}`, debugColor); } // TODO: handle events which do not require data without requiring `undefined` to be passed as as parameter, while // also still requiring data to be passed to those events which do require it. transition(event, data) { const shouldTransitionSelf = this.transitionChild(event, data); if (!shouldTransitionSelf || this.state === _StateMachine.child || this.state === _StateMachine.parent) { return; } const currentState = this.state; const currentStateConfig = this.states[this.state]; let destination = currentStateConfig[event]; const debugPrefix = `%c${this.constructor.name} | ${this.state} -> ${event} ->`; if (Array.isArray(destination)) { destination = destination.find((transition) => { if (!transition.guard) return true; const valid = transition.guard(data); if (!valid) { this.debug(`${debugPrefix} (guarded)`, transition.target, debugQuietColor); } return valid; }); } else if (typeof destination === "object" && !(destination instanceof _StateMachine) && destination.guard && !destination.guard(data)) { this.debug(`${debugPrefix} (guarded)`, destination.target, debugQuietColor); return; } if (!destination) { this.debug(`${debugPrefix} ${this.state}`, debugQuietColor); return; } const destinationState = this.getDestinationState(destination); const exitFn = destinationState === this.state ? void 0 : currentStateConfig.onExit; this.debug(`${debugPrefix} ${destinationState}`, debugColor); this.state = destinationState; if (typeof destination === "function") { destination(data); } else if (typeof destination === "object" && !(destination instanceof _StateMachine)) { destination.action?.(data); } exitFn?.(); this.enterEach?.(currentState, destinationState); if (destinationState !== currentState && destinationState !== _StateMachine.child && destinationState !== _StateMachine.parent) { this.states[destinationState].onEnter?.(currentState, data); } } transitionAsync(event, data) { setTimeout(() => { this.transition(event, data); }, 0); } is(value) { if (this.state === _StateMachine.child && this.childState) { return this.childState.is(value); } return this.state === value; } resetHierarchy() { this.debug( `%c${this.constructor.name} | ${this.state} -> [resetHierarchy] -> ${this.defaultState}`, "color: green" ); this.state = this.defaultState; } transitionChild(event, data) { if (this.state !== _StateMachine.child || !this.childState) return true; applyProperties(this, this.childState); this.childState.transition(event, data); if (!this.childState.is(_StateMachine.parent)) return true; this.debug(`%c${this.constructor.name} | ${this.state} -> ${event} -> ${this.defaultState}`, debugColor); this.state = this.defaultState; this.states[this.state].onEnter?.(); this.childState.resetHierarchy(); return false; } getDestinationState(destination) { let state = this.state; if (typeof destination === "string") { state = destination; } else if (destination instanceof _StateMachine) { this.childState = destination; this.childState.parent = this; state = _StateMachine.child; } else if (typeof destination === "object") { if (destination.target instanceof _StateMachine) { this.childState = destination.target; this.childState.parent = this; state = _StateMachine.child; } else if (destination.target != null) { state = destination.target; } } return state; } }; _StateMachine.child = "__child"; _StateMachine.parent = "__parent"; StateMachine = _StateMachine; ParallelStateMachine = class extends AbstractStateMachine { constructor(...stateMachines) { super(); this.stateMachines = stateMachines; for (const stateMachine of stateMachines) { stateMachine.parent = this; } } transition(event, data) { for (const stateMachine of this.stateMachines) { applyProperties(this, stateMachine); stateMachine.transition(event, data); } } transitionAsync(event, data) { for (const stateMachine of this.stateMachines) { applyProperties(this, stateMachine); stateMachine.transitionAsync(event, data); } } }; } }); // packages/ag-charts-community/src/util/proxy.ts function ProxyProperty(proxyPath, configMetadata) { const pathArray = isArray(proxyPath) ? proxyPath : proxyPath.split("."); if (pathArray.length === 1) { const [property] = pathArray; return addTransformToInstanceProperty( (target, _, value) => target[property] = value, (target) => target[property], configMetadata ); } return addTransformToInstanceProperty( (target, _, value) => setPath(target, pathArray, value), (target) => getPath(target, pathArray), configMetadata ); } function ProxyOnWrite(proxyProperty) { return addTransformToInstanceProperty((target, _, value) => target[proxyProperty] = value); } function ProxyPropertyOnWrite(childName, childProperty) { return addTransformToInstanceProperty((target, key, value) => target[childName][childProperty ?? key] = value); } function ActionOnSet(opts) { const { newValue: newValueFn, oldValue: oldValueFn, changeValue: changeValueFn } = opts; return addTransformToInstanceProperty((target, _, newValue, oldValue) => { if (newValue !== oldValue) { if (oldValue !== void 0) { oldValueFn?.call(target, oldValue); } if (newValue !== void 0) { newValueFn?.call(target, newValue); } changeValueFn?.call(target, newValue, oldValue); } return newValue; }); } function ObserveChanges(observerFn) { return addObserverToInstanceProperty(observerFn); } var init_proxy = __esm({ "packages/ag-charts-community/src/util/proxy.ts"() { "use strict"; init_main(); init_decorator(); init_object(); } }); // packages/ag-charts-community/src/util/textWrapper.ts var TextWrapper; var init_textWrapper = __esm({ "packages/ag-charts-community/src/util/textWrapper.ts"() { "use strict"; init_textMeasurer(); TextWrapper = class { static wrapText(text3, options) { return this.wrapLines(text3, options).join("\n"); } static wrapLines(text3, options) { const clippedResult = this.textWrap(text3, options); if (options.overflow === "hide" && clippedResult.some((l) => l.endsWith(TextUtils.EllipsisChar))) { return []; } return clippedResult; } static appendEllipsis(text3) { return text3.replace(/[.,]{1,5}$/, "") + TextUtils.EllipsisChar; } static truncateLine(text3, measurer3, maxWidth, ellipsisForce) { const ellipsisWidth = measurer3.textWidth(TextUtils.EllipsisChar); let estimatedWidth = 0; let i = 0; for (; i < text3.length; i++) { const charWidth = measurer3.textWidth(text3.charAt(i)); if (estimatedWidth + charWidth > maxWidth) break; estimatedWidth += charWidth; } if (text3.length === i && (!ellipsisForce || estimatedWidth + ellipsisWidth <= maxWidth)) { return ellipsisForce ? text3 + TextUtils.EllipsisChar : text3; } text3 = text3.slice(0, i).trimEnd(); while (text3.length && measurer3.textWidth(text3) + ellipsisWidth > maxWidth) { text3 = text3.slice(0, -1).trimEnd(); } return text3 + TextUtils.EllipsisChar; } static textWrap(text3, options) { const lines = text3.split(TextUtils.lineSplitter); const measurer3 = CachedTextMeasurerPool.getMeasurer(options); if (options.textWrap === "never") { return lines.map((line) => this.truncateLine(line.trimEnd(), measurer3, options.maxWidth)); } const result = []; const wrapHyphenate = options.textWrap === "hyphenate"; const wrapOnSpace = options.textWrap == null || options.textWrap === "on-space"; for (const untrimmedLine of lines) { let line = untrimmedLine.trimEnd(); if (line === "") { result.push(line); continue; } let i = 0; let estimatedWidth = 0; let lastSpaceIndex = 0; while (i < line.length) { const char = line.charAt(i); estimatedWidth += measurer3.textWidth(char); if (char === " ") { lastSpaceIndex = i; } if (estimatedWidth > options.maxWidth) { if (i === 0) break; const actualWidth = measurer3.textWidth(line.slice(0, i + 1)); if (actualWidth <= options.maxWidth) { estimatedWidth = actualWidth; i++; continue; } if (lastSpaceIndex) { const nextWord = this.getWordAt(line, lastSpaceIndex + 1); const textWidth = measurer3.textWidth(nextWord); if (textWidth <= options.maxWidth) { result.push(line.slice(0, lastSpaceIndex).trimEnd()); line = line.slice(lastSpaceIndex).trimStart(); i = 0; estimatedWidth = 0; lastSpaceIndex = 0; continue; } else if (wrapOnSpace && textWidth > options.maxWidth) { result.push( line.slice(0, lastSpaceIndex).trimEnd(), this.truncateLine( line.slice(lastSpaceIndex).trimStart(), measurer3, options.maxWidth, true ) ); } } else if (wrapOnSpace) { result.push(this.truncateLine(line, measurer3, options.maxWidth, true)); } if (wrapOnSpace) { line = ""; break; } const postfix = wrapHyphenate ? "-" : ""; let newLine = line.slice(0, i).trim(); while (newLine.length && measurer3.textWidth(newLine + postfix) > options.maxWidth) { newLine = newLine.slice(0, -1).trimEnd(); } result.push(newLine + postfix); if (!newLine.length) { line = ""; break; } line = line.slice(newLine.length).trimStart(); i = -1; estimatedWidth = 0; lastSpaceIndex = 0; } i++; } if (line) { result.push(line); } } this.avoidOrphans(result, measurer3, options); return this.clipLines(result, measurer3, options); } static getWordAt(text3, position) { const nextSpaceIndex = text3.indexOf(" ", position); return nextSpaceIndex === -1 ? text3.slice(position) : text3.slice(position, nextSpaceIndex); } static clipLines(lines, measurer3, options) { if (!options.maxHeight) { return lines; } const { height: height2, lineMetrics } = measurer3.measureLines(lines); if (height2 <= options.maxHeight) { return lines; } for (let i = 0, cumulativeHeight = 0; i < lineMetrics.length; i++) { const { lineHeight } = lineMetrics[i]; cumulativeHeight += lineHeight; if (cumulativeHeight > options.maxHeight) { if (options.overflow === "hide") { return []; } const clippedResults = lines.slice(0, i || 1); const lastLine = clippedResults.pop(); return clippedResults.concat(this.truncateLine(lastLine, measurer3, options.maxWidth, true)); } } return lines; } static avoidOrphans(lines, measurer3, options) { if (options.avoidOrphans === false || lines.length < 2) return; const { length: length2 } = lines; const lastLine = lines[length2 - 1]; const beforeLast = lines[length2 - 2]; if (beforeLast.length < lastLine.length) return; const lastSpaceIndex = beforeLast.lastIndexOf(" "); if (lastSpaceIndex === -1 || lastSpaceIndex === beforeLast.indexOf(" ") || lastLine.includes(" ")) return; const lastWord = beforeLast.slice(lastSpaceIndex + 1); if (measurer3.textWidth(lastLine + lastWord) <= options.maxWidth) { lines[length2 - 2] = beforeLast.slice(0, lastSpaceIndex); lines[length2 - 1] = lastWord + " " + lastLine; } } }; } }); // packages/ag-charts-community/src/chart/caption.ts var Caption; var init_caption = __esm({ "packages/ag-charts-community/src/chart/caption.ts"() { "use strict"; init_text(); init_transformable(); init_id(); init_properties(); init_proxy(); init_textMeasurer(); init_textWrapper(); init_validation2(); Caption = class extends BaseProperties { constructor() { super(...arguments); this.id = createId(this); this.node = new RotatableText({ zIndex: 1 }).setProperties({ textAlign: "center", pointerEvents: 1 /* None */ }); this.enabled = false; this.textAlign = "center"; this.fontSize = 10; this.fontFamily = "sans-serif"; this.wrapping = "always"; this.padding = 0; this.layoutStyle = "block"; this.truncated = false; } registerInteraction(moduleCtx, where) { return moduleCtx.layoutManager.addListener("layout:complete", () => this.updateA11yText(moduleCtx, where)); } computeTextWrap(containerWidth, containerHeight) { const { text: text3, padding, wrapping } = this; const maxWidth = Math.min(this.maxWidth ?? Infinity, containerWidth) - padding * 2; const maxHeight = this.maxHeight ?? containerHeight - padding * 2; if (!isFinite(maxWidth) && !isFinite(maxHeight)) { this.node.text = text3; return; } const wrappedText = TextWrapper.wrapText(text3 ?? "", { maxWidth, maxHeight, font: this, textWrap: wrapping }); this.node.text = wrappedText; this.truncated = wrappedText.includes(TextUtils.EllipsisChar); } updateA11yText(moduleCtx, where) { const { proxyInteractionService } = moduleCtx; if (this.enabled && this.text) { const bbox = Transformable.toCanvas(this.node); if (bbox) { const { id: domManagerId } = this; this.proxyText ?? (this.proxyText = proxyInteractionService.createProxyElement({ type: "text", domManagerId, where })); this.proxyText.textContent = this.text; this.proxyText.setBounds(bbox); this.proxyText.addListener("mousemove", (ev) => this.handleMouseMove(moduleCtx, ev)); this.proxyText.addListener("mouseleave", (ev) => this.handleMouseLeave(moduleCtx, ev)); } } else { this.proxyText?.destroy(); this.proxyText = void 0; } } handleMouseMove(moduleCtx, event) { if (event != null && this.enabled && this.node.visible && this.truncated) { const { x, y } = Transformable.toCanvas(this.node); const canvasX = event.sourceEvent.offsetX + x; const canvasY = event.sourceEvent.offsetY + y; const lastPointerEvent = { type: "pointermove", canvasX, canvasY }; moduleCtx.tooltipManager.updateTooltip( this.id, { canvasX, canvasY, lastPointerEvent, showArrow: false }, { type: "structured", title: this.text } ); } } handleMouseLeave(moduleCtx, _event) { moduleCtx.tooltipManager.removeTooltip(this.id); } }; Caption.SMALL_PADDING = 10; Caption.LARGE_PADDING = 20; __decorateClass([ Validate(BOOLEAN), ProxyPropertyOnWrite("node", "visible") ], Caption.prototype, "enabled", 2); __decorateClass([ Validate(STRING, { optional: true }), ProxyPropertyOnWrite("node") ], Caption.prototype, "text", 2); __decorateClass([ Validate(TEXT_ALIGN, { optional: true }), ProxyPropertyOnWrite("node") ], Caption.prototype, "textAlign", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }), ProxyPropertyOnWrite("node") ], Caption.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }), ProxyPropertyOnWrite("node") ], Caption.prototype, "fontWeight", 2); __decorateClass([ Validate(POSITIVE_NUMBER), ProxyPropertyOnWrite("node") ], Caption.prototype, "fontSize", 2); __decorateClass([ Validate(STRING), ProxyPropertyOnWrite("node") ], Caption.prototype, "fontFamily", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }), ProxyPropertyOnWrite("node", "fill") ], Caption.prototype, "color", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], Caption.prototype, "spacing", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], Caption.prototype, "maxWidth", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], Caption.prototype, "maxHeight", 2); __decorateClass([ Validate(TEXT_WRAP) ], Caption.prototype, "wrapping", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Caption.prototype, "padding", 2); __decorateClass([ Validate(STRING) ], Caption.prototype, "layoutStyle", 2); } }); // packages/ag-charts-community/src/chart/chartAxisDirection.ts var ChartAxisDirection; var init_chartAxisDirection = __esm({ "packages/ag-charts-community/src/chart/chartAxisDirection.ts"() { "use strict"; ChartAxisDirection = /* @__PURE__ */ ((ChartAxisDirection34) => { ChartAxisDirection34["X"] = "x"; ChartAxisDirection34["Y"] = "y"; return ChartAxisDirection34; })(ChartAxisDirection || {}); } }); // packages/ag-charts-community/src/module/moduleMap.ts var ModuleMap; var init_moduleMap = __esm({ "packages/ag-charts-community/src/module/moduleMap.ts"() { "use strict"; init_main(); ModuleMap = class { constructor() { this.moduleMap = /* @__PURE__ */ new Map(); } *modules() { for (const m of this.moduleMap.values()) { yield m.moduleInstance; } } addModule(module2, moduleFactory) { if (this.moduleMap.has(module2.optionsKey)) { throw new Error(`AG Charts - module already initialised: ${module2.optionsKey}`); } this.moduleMap.set(module2.optionsKey, { module: module2, moduleInstance: moduleFactory(module2) }); } removeModule(module2) { const moduleKey = isString(module2) ? module2 : module2.optionsKey; this.moduleMap.get(moduleKey)?.moduleInstance.destroy(); this.moduleMap.delete(moduleKey); } getModule(module2) { return this.moduleMap.get(isString(module2) ? module2 : module2.optionsKey)?.moduleInstance; } isEnabled(module2) { return this.moduleMap.has(isString(module2) ? module2 : module2.optionsKey); } mapModules(callback2) { return Array.from(this.moduleMap.values(), (m, i) => callback2(m.moduleInstance, i)); } destroy() { for (const moduleKey of this.moduleMap.keys()) { this.moduleMap.get(moduleKey)?.moduleInstance.destroy(); } this.moduleMap.clear(); } }; } }); // packages/ag-charts-community/src/util/date.ts function compareDates(a, b) { return a.valueOf() - b.valueOf(); } function deduplicateSortedArray(values) { let v0 = NaN; const out = []; for (const v of values) { const v1 = v.valueOf(); if (v0 !== v1) out.push(v); v0 = v1; } return out; } function sortAndUniqueDates(values) { const sortedValues = values.slice().sort(compareDates); return datesSortOrder(sortedValues) == null ? deduplicateSortedArray(sortedValues) : sortedValues; } function datesSortOrder(d) { if (d.length === 0) return 1; const sign = Number(d[d.length - 1]) > Number(d[0]) ? 1 : -1; let v0 = -Infinity * sign; for (const v of d) { const v1 = v.valueOf(); if (Math.sign(v1 - v0) !== sign) return; v0 = v1; } return sign; } var init_date = __esm({ "packages/ag-charts-community/src/util/date.ts"() { "use strict"; } }); // packages/ag-charts-community/src/util/numberFormat.ts function parseFormat(format) { let prefix; let suffix; const surrounded = surroundedRegEx.exec(format); if (surrounded) { [, prefix, format, suffix] = surrounded; } const match = formatRegEx.exec(format); if (!match) { throw new Error(`The number formatter is invalid: ${format}`); } const [, fill, align2, sign, symbol, zero, width2, comma, precision, trim, type] = match; return { fill, align: align2, sign, symbol, zero, width: parseInt(width2), comma, precision: parseInt(precision), trim: Boolean(trim), type, prefix, suffix }; } function numberFormat(format) { const options = typeof format === "string" ? parseFormat(format) : format; const { fill, align: align2, sign = "-", symbol, zero, width: width2, comma, type, prefix = "", suffix = "", precision } = options; let { trim } = options; const precisionIsNaN = precision == null || isNaN(precision); let formatBody; if (!type) { formatBody = decimalTypes["g"]; trim = true; } else if (type in decimalTypes && type in integerTypes) { formatBody = precisionIsNaN ? integerTypes[type] : decimalTypes[type]; } else if (type in decimalTypes) { formatBody = decimalTypes[type]; } else if (type in integerTypes) { formatBody = integerTypes[type]; } else { throw new Error(`The number formatter type is invalid: ${type}`); } let formatterPrecision; if (precision == null || precisionIsNaN) { formatterPrecision = type ? 6 : 12; } else { formatterPrecision = precision; } return (n) => { let result = formatBody(n, formatterPrecision); if (trim) { result = removeTrailingZeros(result); } if (comma) { result = insertSeparator(result, comma); } result = addSign(n, result, sign); if (symbol && symbol !== "#") { result = `${symbol}${result}`; } if (symbol === "#" && type === "x") { result = `0x${result}`; } if (type === "s") { result = `${result}${getSIPrefix(n)}`; } if (type === "%" || type === "p") { result = `${result}%`; } if (width2 != null && !isNaN(width2)) { result = addPadding(result, width2, fill ?? zero, align2); } result = `${prefix}${result}${suffix}`; return result; }; } function absFloor(n) { return Math.floor(Math.abs(n)); } function removeTrailingZeros(numString) { return numString.replace(/\.0+$/, "").replace(/(\.[1-9])0+$/, "$1"); } function insertSeparator(numString, separator) { let dotIndex = numString.indexOf("."); if (dotIndex < 0) { dotIndex = numString.length; } const integerChars = numString.substring(0, dotIndex).split(""); const fractionalPart = numString.substring(dotIndex); for (let i = integerChars.length - 3; i > 0; i -= 3) { integerChars.splice(i, 0, separator); } return `${integerChars.join("")}${fractionalPart}`; } function getSIPrefix(n) { return siPrefixes[getSIPrefixPower(n)]; } function getSIPrefixPower(n) { return clamp(minSIPrefix, n ? Math.floor(Math.log10(Math.abs(n)) / 3) * 3 : 0, maxSIPrefix); } function addSign(num, numString, signType = "") { if (signType === "(") { return num >= 0 ? numString : `(${numString})`; } const plusSign = signType === "+" ? "+" : ""; return `${num >= 0 ? plusSign : minusSign}${numString}`; } function addPadding(numString, width2, fill = " ", align2 = ">") { let result = numString; if (align2 === ">" || !align2) { result = result.padStart(width2, fill); } else if (align2 === "<") { result = result.padEnd(width2, fill); } else if (align2 === "^") { const padWidth = Math.max(0, width2 - result.length); const padLeft = Math.ceil(padWidth / 2); const padRight = Math.floor(padWidth / 2); result = result.padStart(padLeft + result.length, fill); result = result.padEnd(padRight + result.length, fill); } return result; } var formatRegEx, surroundedRegEx, integerTypes, decimalTypes, minSIPrefix, maxSIPrefix, siPrefixes, minusSign; var init_numberFormat = __esm({ "packages/ag-charts-community/src/util/numberFormat.ts"() { "use strict"; init_number(); formatRegEx = /^(?:(.)?([<>=^]))?([+\-( ])?([$€£¥₣₹#])?(0)?(\d+)?(,)?(?:\.(\d+))?(~)?([%a-z])?$/i; surroundedRegEx = /^((?:[^#]|#[^{])*)#{([^}]+)}(.*)$/; integerTypes = { b: (n) => absFloor(n).toString(2), c: (n) => String.fromCharCode(n), d: (n) => Math.round(Math.abs(n)).toFixed(0), o: (n) => absFloor(n).toString(8), x: (n) => absFloor(n).toString(16), X: (n) => integerTypes.x(n).toUpperCase(), n: (n) => integerTypes.d(n), "%": (n) => `${absFloor(n * 100).toFixed(0)}` }; decimalTypes = { e: (n, f) => Math.abs(n).toExponential(f), E: (n, f) => decimalTypes.e(n, f).toUpperCase(), f: (n, f) => Math.abs(n).toFixed(f), F: (n, f) => decimalTypes.f(n, f).toUpperCase(), g: (n, f) => { if (n === 0) { return "0"; } const a = Math.abs(n); const p = Math.floor(Math.log10(a)); if (p >= -4 && p < f) { return a.toFixed(f - 1 - p); } return a.toExponential(f - 1); }, G: (n, f) => decimalTypes.g(n, f).toUpperCase(), n: (n, f) => decimalTypes.g(n, f), p: (n, f) => decimalTypes.r(n * 100, f), r: (n, f) => { if (n === 0) { return "0"; } const a = Math.abs(n); const p = Math.floor(Math.log10(a)); const q = p - (f - 1); if (q <= 0) { return a.toFixed(-q); } const x = 10 ** q; return (Math.round(a / x) * x).toFixed(); }, s: (n, f) => { const p = getSIPrefixPower(n); return decimalTypes.r(n / 10 ** p, f); }, "%": (n, f) => decimalTypes.f(n * 100, f) }; minSIPrefix = -24; maxSIPrefix = 24; siPrefixes = { [minSIPrefix]: "y", [-21]: "z", [-18]: "a", [-15]: "f", [-12]: "p", [-9]: "n", [-6]: "\xB5", [-3]: "m", [0]: "", [3]: "k", [6]: "M", [9]: "G", [12]: "T", [15]: "P", [18]: "E", [21]: "Z", [maxSIPrefix]: "Y" }; minusSign = "\u2212"; } }); // packages/ag-charts-community/src/util/ticks.ts function isCloseToInteger(n, delta4) { return Math.abs(Math.round(n) - n) < delta4; } function createTicks(start2, stop, count, minCount, maxCount, visibleRange) { if (count < 2) { return [start2, stop]; } const step = tickStep(start2, stop, count, minCount, maxCount); if (!Number.isFinite(step)) { return []; } if (!isCloseToInteger(start2 / step, 1e-12)) { start2 = Math.ceil(start2 / step) * step; } if (!isCloseToInteger(stop / step, 1e-12)) { stop = Math.floor(stop / step) * step; } if (visibleRange != null && visibleRange[0] !== 0 && visibleRange[1] !== 1) { const rangeExtent = stop - start2; const adjustedStart = start2 + rangeExtent * visibleRange[0]; const adjustedEnd = stop - rangeExtent * (1 - visibleRange[1]); return range(adjustedStart - adjustedStart % step, adjustedEnd + adjustedEnd % step, step); } return range(start2, stop, step); } function getTickInterval(start2, stop, count, minCount, maxCount, targetInterval) { const target = targetInterval ?? Math.abs(stop - start2) / Math.max(count, 1); let i = 0; for (const tickInterval of TickIntervals) { if (target <= tickInterval.duration) break; i++; } if (i === 0) { const step2 = Math.max(tickStep(start2, stop, count, minCount, maxCount), 1); return millisecond.every(step2); } else if (i === TickIntervals.length) { const step2 = targetInterval == null ? tickStep(start2 / durationYear, stop / durationYear, count, minCount, maxCount) : 1; return year.every(step2); } const i0 = TickIntervals[i - 1]; const i1 = TickIntervals[i]; const { timeInterval, step } = target - i0.duration < i1.duration - target ? i0 : i1; return timeInterval.every(step); } function tickStep(start2, end2, count, minCount = 0, maxCount = Infinity) { if (start2 === end2) { return clamp(1, minCount, maxCount); } else if (count < 1) { return NaN; } const extent3 = Math.abs(end2 - start2); const step = 10 ** Math.floor(Math.log10(extent3 / count)); let m = NaN, minDiff = Infinity, isInBounds = false; for (const multiplier of TickMultipliers) { const c = Math.ceil(extent3 / (multiplier * step)); const validBounds = c >= minCount && c <= maxCount; if (isInBounds && !validBounds) continue; const diffCount = Math.abs(c - count); if (minDiff > diffCount || isInBounds !== validBounds) { isInBounds || (isInBounds = validBounds); minDiff = diffCount; m = multiplier; } } return m * step; } function decimalPlaces(decimal) { for (let i = decimal.length - 1; i >= 0; i -= 1) { if (decimal[i] !== "0") { return i + 1; } } return 0; } function tickFormat(ticks, format) { const options = parseFormat(format ?? ",f"); if (options.precision == null || isNaN(options.precision)) { if (!options.type || "eEFgGnprs".includes(options.type)) { options.precision = Math.max( ...ticks.map((x) => { if (!Number.isFinite(x)) return 0; const [integer, decimal] = x.toExponential((options.type ? 6 : 12) - 1).split(/[.e]/g); return (integer !== "1" && integer !== "-1" ? 1 : 0) + decimalPlaces(decimal) + 1; }) ); } else if ("f%".includes(options.type)) { options.precision = Math.max( ...ticks.map((x) => { if (!Number.isFinite(x) || x === 0) return 0; const l = Math.floor(Math.log10(Math.abs(x))); const digits = options.type ? 6 : 12; const decimal = x.toExponential(digits - 1).split(/[.e]/g)[1]; const decimalLength = decimalPlaces(decimal); return Math.max(0, decimalLength - l); }) ); } } const formatter = numberFormat(options); return (n) => formatter(Number(n)); } function range(start2, end2, step) { if (!Number.isFinite(step) || step <= 0) { return []; } const f = 10 ** countFractionDigits(step); const d0 = Math.min(start2, end2); const d1 = Math.max(start2, end2); const out = []; for (let i = 0; ; i += 1) { const p = Math.round((d0 + step * i) * f) / f; if (p > d1) break; out.push(p); } return out; } function isDenseInterval(count, availableRange) { if (count >= availableRange) { logger_exports.warnOnce( `the configured interval results in more than 1 item per pixel, ignoring. Supply a larger interval or omit this configuration` ); return true; } return false; } function niceTicksDomain(start2, end2) { const extent3 = Math.abs(end2 - start2); const step = 10 ** Math.floor(Math.log10(extent3)); let minError = Infinity, ticks = [start2, end2]; for (const multiplier of TickMultipliers) { const m = multiplier * step; const d0 = Math.floor(start2 / m) * m; const d1 = Math.ceil(end2 / m) * m; const error3 = 1 - extent3 / Math.abs(d1 - d0); if (minError > error3) { minError = error3; ticks = [d0, d1]; } } return ticks; } function estimateTickCount(rangeExtent, zoomExtent, minSpacing, maxSpacing, defaultTickCount, defaultMinSpacing) { defaultMinSpacing = Math.max(defaultMinSpacing, rangeExtent / (defaultTickCount + 1)); if (isNaN(minSpacing)) { minSpacing = defaultMinSpacing; } if (isNaN(maxSpacing)) { maxSpacing = rangeExtent; } if (minSpacing > maxSpacing) { if (minSpacing === defaultMinSpacing) { minSpacing = maxSpacing; } else { maxSpacing = minSpacing; } } const maxTickCount = Math.max(1, Math.floor(rangeExtent / (zoomExtent * minSpacing))); const minTickCount = Math.min(maxTickCount, Math.ceil(rangeExtent / (zoomExtent * maxSpacing))); const tickCount = clamp(minTickCount, Math.floor(defaultTickCount / zoomExtent), maxTickCount); return { minTickCount, maxTickCount, tickCount }; } var tInterval, TickIntervals, TickMultipliers; var init_ticks = __esm({ "packages/ag-charts-community/src/util/ticks.ts"() { "use strict"; init_main(); init_number(); init_numberFormat(); init_time(); init_duration(); tInterval = (timeInterval, baseDuration, step) => ({ duration: baseDuration * step, timeInterval, step }); TickIntervals = [ tInterval(second, durationSecond, 1), tInterval(second, durationSecond, 5), tInterval(second, durationSecond, 15), tInterval(second, durationSecond, 30), tInterval(minute, durationMinute, 1), tInterval(minute, durationMinute, 5), tInterval(minute, durationMinute, 15), tInterval(minute, durationMinute, 30), tInterval(hour, durationHour, 1), tInterval(hour, durationHour, 3), tInterval(hour, durationHour, 6), tInterval(hour, durationHour, 12), tInterval(day, durationDay, 1), tInterval(day, durationDay, 2), tInterval(sunday, durationWeek, 1), tInterval(sunday, durationWeek, 2), tInterval(sunday, durationWeek, 3), tInterval(month, durationMonth, 1), tInterval(month, durationMonth, 2), tInterval(month, durationMonth, 3), tInterval(month, durationMonth, 4), tInterval(month, durationMonth, 6), tInterval(year, durationYear, 1) ]; TickMultipliers = [1, 2, 5, 10]; } }); // packages/ag-charts-community/src/scale/timeScale.ts function getDefaultDateTicks({ start: start2, stop, tickCount, minTickCount, maxTickCount, visibleRange }) { const t = getTickInterval(start2, stop, tickCount, minTickCount, maxTickCount); return t ? t.range(new Date(start2), new Date(stop), { visibleRange }) : []; } function getDateTicksForInterval({ start: start2, stop, interval, availableRange, visibleRange }) { if (!interval) { return []; } if (interval instanceof TimeInterval) { const ticks2 = interval.range(new Date(start2), new Date(stop), { visibleRange }); if (isDenseInterval(ticks2.length, availableRange)) { return; } return ticks2; } const absInterval = Math.abs(interval); if (isDenseInterval(Math.abs(stop - start2) / absInterval, availableRange)) return; const timeInterval = TickIntervals.findLast((tickInterval) => absInterval % tickInterval.duration === 0); if (timeInterval) { const i = timeInterval.timeInterval.every(absInterval / (timeInterval.duration / timeInterval.step)); return i.range(new Date(start2), new Date(stop), { visibleRange }); } let date2 = new Date(Math.min(start2, stop)); const stopDate = new Date(Math.max(start2, stop)); const ticks = []; while (date2 <= stopDate) { ticks.push(date2); date2 = new Date(date2); date2.setMilliseconds(date2.getMilliseconds() + absInterval); } return ticks; } function updateNiceDomainIteration(d0, d1, ticks) { const { interval } = ticks; const start2 = Math.min(dateToNumber(d0), dateToNumber(d1)); const stop = Math.max(dateToNumber(d0), dateToNumber(d1)); const isReversed = d0 > d1; let i; if (interval instanceof TimeInterval) { i = interval; } else { const tickCount = typeof interval === "number" ? (stop - start2) / Math.max(interval, 1) : ticks.tickCount ?? ContinuousScale.defaultTickCount; i = getTickInterval(start2, stop, tickCount, ticks.minTickCount, ticks.maxTickCount); } if (i) { const intervalRange = i.range(new Date(start2), new Date(stop), { extend: true }); const domain = isReversed ? [...intervalRange].reverse() : intervalRange; const n0 = domain[0]; const n1 = domain.at(-1); return [n0, n1]; } else { return [d0, d1]; } } var TimeScale; var init_timeScale = __esm({ "packages/ag-charts-community/src/scale/timeScale.ts"() { "use strict"; init_ticks(); init_time(); init_timeFormat(); init_timeFormatDefaults(); init_continuousScale(); TimeScale = class extends ContinuousScale { constructor() { super([], [0, 1]); this.type = "time"; } toDomain(d) { return new Date(d); } convert(value, clamp9) { if (!(value instanceof Date)) value = new Date(value); return super.convert(value, clamp9); } invert(value) { return new Date(super.invert(value)); } niceDomain(ticks, domain = this.domain) { if (domain.length < 2) return []; const maxAttempts = 4; let [d0, d1] = domain; for (let i = 0; i < maxAttempts; i++) { const [n0, n1] = updateNiceDomainIteration(d0, d1, ticks); if (dateToNumber(d0) === dateToNumber(n0) && dateToNumber(d1) === dateToNumber(n1)) { break; } d0 = n0; d1 = n1; } return [d0, d1]; } /** * Returns uniformly-spaced dates that represent the scale's domain. */ ticks(params, domain = this.domain, visibleRange = [0, 1]) { const { nice, interval, tickCount = ContinuousScale.defaultTickCount, minTickCount, maxTickCount } = params; if (domain.length < 2) return []; const timestamps = domain.map(dateToNumber); const start2 = timestamps[0]; const stop = timestamps[timestamps.length - 1]; if (interval != null) { const availableRange = this.getPixelRange(); return getDateTicksForInterval({ start: start2, stop, interval, availableRange, visibleRange }) ?? getDefaultDateTicks({ start: start2, stop, tickCount, minTickCount, maxTickCount, visibleRange }); } else if (nice && tickCount === 2) { return domain; } else if (nice && tickCount === 1) { return domain.slice(0, 1); } return getDefaultDateTicks({ start: start2, stop, tickCount, minTickCount, maxTickCount, visibleRange }); } _tickFormatter({ domain, ticks, specifier }, formatOffset) { return specifier != null ? buildFormatter(specifier) : defaultTimeTickFormat(ticks, domain, formatOffset); } /** * Returns a time format function suitable for displaying tick values. * * @param ticks Optional array of tick values for custom formatting. * @param domain Optional array representing the [min, max] values of the time axis. * @param specifier Optional format specifier string for custom date formatting (e.g., `%Y`, `%m`, `%d`). * @param formatOffset Optional number for applying an offset to the format (e.g., timezone shifts). * @returns A function that formats a `Date` object into a string based on the provided specifier or default format. */ tickFormatter(params) { return this._tickFormatter(params); } datumFormatter(params) { return this._tickFormatter(params, 1); } }; } }); // packages/ag-charts-community/src/scale/ordinalTimeScale.ts function getDefaultTicks(domain, maxTickCount, isReversed, visibleRange) { const ticks = []; const tickEvery = Math.ceil(domain.length / maxTickCount); const tickOffset = Math.floor(tickEvery / 2); const startIndex = Math.floor(visibleRange[0] * domain.length); const endIndex = Math.ceil(visibleRange[1] * domain.length); for (let index = startIndex; index < endIndex; index += 1) { const tickIndex = isReversed ? domain.length - 1 - index : index; if (tickEvery <= 0 || (tickIndex + tickOffset) % tickEvery === 0) { ticks.push(domain[index]); } } if (isReversed) { ticks.reverse(); } return ticks; } var OrdinalTimeScale; var init_ordinalTimeScale = __esm({ "packages/ag-charts-community/src/scale/ordinalTimeScale.ts"() { "use strict"; init_main(); init_date(); init_timeFormat(); init_timeFormatDefaults(); init_bandScale(); init_timeScale(); OrdinalTimeScale = class _OrdinalTimeScale extends BandScale { constructor() { super(...arguments); this.type = "ordinal-time"; this._domain = []; this.isReversed = false; } static is(value) { return value instanceof _OrdinalTimeScale; } set domain(domain) { if (domain === this._domain) return; this.invalid = true; this._domain = domain; this.isReversed = domain.length > 0 && domain[0] > domain[domain.length - 1]; this.sortedTimestamps = void 0; this.precomputedSteps = void 0; } get domain() { return this._domain; } toDomain(value) { return new Date(value); } normalizeDomains(...domains) { const sortedDomains = domains.filter((domain2) => domain2.length > 0).map((domain2) => { let sortOrder = datesSortOrder(domain2); if (sortOrder == null) { domain2 = sortAndUniqueDates(domain2.slice()); sortOrder = 1; } return { domain: domain2, sortOrder }; }); if (sortedDomains.length === 0) return { domain: [], animatable: false }; if (sortedDomains.length === 1) return { domain: sortedDomains[0].domain, animatable: true }; let domain = sortedDomains.flatMap((s) => s.domain); domain = sortAndUniqueDates(domain); if (sortedDomains.every((s) => s.sortOrder === -1)) { domain.reverse(); } return { domain, animatable: true }; } ticks({ interval, maxTickCount }, domain = this.domain, visibleRange = [0, 1]) { if (!domain.length) { return []; } this.refresh(); const { isReversed } = this; if (interval == null) { return getDefaultTicks(domain, maxTickCount, isReversed, visibleRange); } const [t0, t1] = [domain[0].valueOf(), domain.at(-1).valueOf()]; const start2 = Math.min(t0, t1); const stop = Math.max(t0, t1); const [r0, r1] = this.range; const availableRange = Math.abs(r1 - r0); const ticks = getDateTicksForInterval({ start: start2, stop, interval, availableRange, visibleRange }) ?? []; let lastIndex = -1; return ticks.filter((tick) => { const index = this.findInterval(tick.valueOf()); const duplicated = index === lastIndex; lastIndex = index; return !duplicated; }); } getSortedTimestamps() { let { sortedTimestamps } = this; if (sortedTimestamps == null) { sortedTimestamps = this.domain.map(dateToNumber); if (this.isReversed) sortedTimestamps.reverse(); this.sortedTimestamps = sortedTimestamps; } return sortedTimestamps; } getPrecomputedSteps() { const { domain } = this; let { precomputedSteps } = this; const computedStepCount = domain.length < 1e4 ? domain.length : Math.ceil(domain.length / 16); if (precomputedSteps != null || computedStepCount <= 1) return precomputedSteps; const sortedTimestamps = this.getSortedTimestamps(); precomputedSteps = new Int32Array(computedStepCount); const d0 = sortedTimestamps[0]; const d1 = sortedTimestamps[sortedTimestamps.length - 1]; const dRange = d1 - d0; const low = 0; const high = sortedTimestamps.length - 1; for (let i = 0; i < precomputedSteps.length; i += 1) { precomputedSteps[i] = this.findIntervalInRange(d0 + i / computedStepCount * dRange, low, high); } this.precomputedSteps = precomputedSteps; } findIntervalInRange(target, low, high) { const sortedTimestamps = this.getSortedTimestamps(); while (low <= high) { const mid = (low + high) / 2 | 0; if (sortedTimestamps[mid] === target) { return mid; } else if (sortedTimestamps[mid] < target) { low = mid + 1; } else { high = mid - 1; } } return low; } findInterval(target) { const precomputedSteps = this.getPrecomputedSteps(); let low; let high; if (precomputedSteps == null) { low = 0; high = this.domain.length - 1; } else { const sortedTimestamps = this.getSortedTimestamps(); const d0 = sortedTimestamps[0]; const d1 = sortedTimestamps[sortedTimestamps.length - 1]; const i = Math.min( (target - d0) / (d1 - d0) * precomputedSteps.length | 0, precomputedSteps.length - 1 | 0 ); low = precomputedSteps[i]; high = i < precomputedSteps.length - 2 ? precomputedSteps[i + 1] : sortedTimestamps.length - 1; } return this.findIntervalInRange(target, low, high); } /** * Returns a time format function suitable for displaying tick values. * @param specifier If the specifier string is provided, this method is equivalent to * the {@link TimeLocaleObject.format} method. * If no specifier is provided, this method returns the default time format function. */ tickFormatter({ domain, ticks, specifier }) { return specifier != null ? buildFormatter(specifier) : defaultTimeTickFormat(ticks, domain); } datumFormatter(params) { return this.tickFormatter(params); } invert(position, nearest = false) { this.refresh(); const { domain } = this; if (nearest) { const index = this.invertNearestIndex(position - this.bandwidth / 2); return index != null ? domain[index] : void 0; } const closest = findMinValue(0, domain.length - 1, (i) => { const p = this.ordinalRange(i); return p >= position ? domain[i] : void 0; }); return closest ?? domain[0]; } getIndex(value) { const sortedTimestamps = this.getSortedTimestamps(); const n = Number(value); if (n < sortedTimestamps[0]) { return void 0; } let i = this.findInterval(n); if (this.isReversed) { i = this.domain.length - i - 1; } return i; } }; } }); // packages/ag-charts-community/src/scene/selection.ts var Selection; var init_selection = __esm({ "packages/ag-charts-community/src/scene/selection.ts"() { "use strict"; init_debug(); init_node(); Selection = class _Selection { constructor(parentNode, classOrFactory, autoCleanup = true) { this.parentNode = parentNode; this.autoCleanup = autoCleanup; this.garbageBin = /* @__PURE__ */ new Set(); this._nodesMap = /* @__PURE__ */ new Map(); this._nodes = []; this.data = []; this.debug = Debug.create(true, "scene", "scene:selections"); this.nodeFactory = Object.prototype.isPrototypeOf.call(Node, classOrFactory) ? () => new classOrFactory() : classOrFactory; } static select(parent, classOrFactory, garbageCollection = true) { return new _Selection(parent, classOrFactory, garbageCollection); } static selectAll(parent, predicate) { const results = []; const traverse = (node) => { if (predicate(node)) { results.push(node); } for (const child of node.children()) { traverse(child); } }; traverse(parent); return results; } static selectByClass(node, ...Classes) { return _Selection.selectAll(node, (n) => Classes.some((C2) => n instanceof C2)); } static selectByTag(node, tag) { return _Selection.selectAll(node, (n) => n.tag === tag); } createNode(datum, initializer, idx) { const node = this.nodeFactory(datum); node.datum = datum; initializer?.(node); if (idx == null) { this._nodes.push(node); } else { this._nodes.splice(idx, 0, node); } this.parentNode.appendChild(node); return node; } /** * Update the data in a selection. If an `getDatumId()` function is provided, maintain a list of ids related to * the nodes. Otherwise, take the more efficient route of simply creating and destroying nodes at the end * of the array. */ update(data, initializer, getDatumId) { if (this.garbageBin.size > 0) { this.debug(`Selection - update() called with pending garbage`, data); } if (getDatumId) { const dataMap = new Map( data.map((datum, idx) => [getDatumId(datum), [datum, idx]]) ); for (const [node, datumId] of this._nodesMap.entries()) { if (dataMap.has(datumId)) { const [newDatum] = dataMap.get(datumId); node.datum = newDatum; this.garbageBin.delete(node); dataMap.delete(datumId); } else { this.garbageBin.add(node); } } for (const [datumId, [datum, idx]] of dataMap.entries()) { this._nodesMap.set(this.createNode(datum, initializer, idx), datumId); } } else { const maxLength = Math.max(data.length, this.data.length); for (let i = 0; i < maxLength; i++) { if (i >= data.length) { this.garbageBin.add(this._nodes[i]); } else if (i >= this._nodes.length) { this.createNode(data[i], initializer); } else { this._nodes[i].datum = data[i]; this.garbageBin.delete(this._nodes[i]); } } } this.data = data.slice(); if (this.autoCleanup) { this.cleanup(); } return this; } cleanup() { if (this.garbageBin.size === 0) { return this; } this._nodes = this._nodes.filter((node) => { if (this.garbageBin.has(node)) { this._nodesMap.delete(node); this.garbageBin.delete(node); node.destroy(); return false; } return true; }); return this; } clear() { this.update([]); return this; } isGarbage(node) { return this.garbageBin.has(node); } each(iterate3) { for (const entry of this._nodes.entries()) { iterate3(entry[1], entry[1].datum, entry[0]); } return this; } *[Symbol.iterator]() { for (let index = 0; index < this._nodes.length; index++) { const node = this._nodes[index]; yield { node, datum: node.datum, index }; } } select(predicate) { return _Selection.selectAll(this.parentNode, predicate); } selectByClass(Class) { return _Selection.selectByClass(this.parentNode, Class); } selectByTag(tag) { return _Selection.selectByTag(this.parentNode, tag); } nodes() { return this._nodes; } at(index) { return this._nodes.at(index); } get length() { return this._nodes.length; } }; } }); // packages/ag-charts-community/src/util/distance.ts function pointsDistanceSquared(x1, y1, x2, y2) { const dx2 = x1 - x2; const dy2 = y1 - y2; return dx2 * dx2 + dy2 * dy2; } function lineDistanceSquared(x, y, x1, y1, x2, y2, best) { if (x1 === x2 && y1 === y2) { return Math.min(best, pointsDistanceSquared(x, y, x1, y1)); } const dx2 = x2 - x1; const dy2 = y2 - y1; const t = Math.max(0, Math.min(1, ((x - x1) * dx2 + (y - y1) * dy2) / (dx2 * dx2 + dy2 * dy2))); const ix = x1 + t * dx2; const iy = y1 + t * dy2; return Math.min(best, pointsDistanceSquared(x, y, ix, iy)); } function arcDistanceSquared(x, y, cx, cy, radius, startAngle, endAngle, counterClockwise, best) { if (counterClockwise) { [endAngle, startAngle] = [startAngle, endAngle]; } const angle2 = Math.atan2(y - cy, x - cx); if (!isBetweenAngles(angle2, startAngle, endAngle)) { const startX = cx + Math.cos(startAngle) * radius; const startY = cy + Math.sin(startAngle) * radius; const endX = cx + Math.cos(startAngle) * radius; const endY = cy + Math.sin(startAngle) * radius; return Math.min(best, pointsDistanceSquared(x, y, startX, startY), pointsDistanceSquared(x, y, endX, endY)); } const distToArc = radius - Math.sqrt(pointsDistanceSquared(x, y, cx, cy)); return Math.min(best, distToArc * distToArc); } var init_distance = __esm({ "packages/ag-charts-community/src/util/distance.ts"() { "use strict"; init_angle(); } }); // packages/ag-charts-community/src/scene/shape/line.ts var Line; var init_line = __esm({ "packages/ag-charts-community/src/scene/shape/line.ts"() { "use strict"; init_core(); init_distance(); init_bbox(); init_node(); init_shape(); Line = class extends Shape { constructor(opts = {}) { super(opts); this.x1 = 0; this.y1 = 0; this.x2 = 0; this.y2 = 0; this.restoreOwnStyles(); } set x(value) { this.x1 = value; this.x2 = value; } set y(value) { this.y1 = value; this.y2 = value; } get midPoint() { return { x: (this.x1 + this.x2) / 2, y: (this.y1 + this.y2) / 2 }; } computeBBox() { return new BBox( Math.min(this.x1, this.x2), Math.min(this.y1, this.y2), Math.abs(this.x2 - this.x1), Math.abs(this.y2 - this.y1) ); } isPointInPath(x, y) { if (this.x1 === this.x2 || this.y1 === this.y2) { return this.getBBox().clone().grow(this.strokeWidth / 2).containsPoint(x, y); } return false; } distanceSquared(px, py) { const { x1, y1, x2, y2 } = this; return lineDistanceSquared(px, py, x1, y1, x2, y2, Infinity); } render(renderCtx) { const { ctx, devicePixelRatio } = renderCtx; let { x1, y1, x2, y2 } = this; if (x1 === x2) { const { strokeWidth } = this; const x = Math.round(x1 * devicePixelRatio) / devicePixelRatio + Math.trunc(strokeWidth * devicePixelRatio) % 2 / (devicePixelRatio * 2); x1 = x; x2 = x; } else if (y1 === y2) { const { strokeWidth } = this; const y = Math.round(y1 * devicePixelRatio) / devicePixelRatio + Math.trunc(strokeWidth * devicePixelRatio) % 2 / (devicePixelRatio * 2); y1 = y; y2 = y; } ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); this.fillStroke(ctx); this.fillShadow?.markClean(); super.render(renderCtx); } toSVG() { if (!this.visible) return; const element2 = createSvgElement("line"); element2.setAttribute("x1", String(this.x1)); element2.setAttribute("y1", String(this.y1)); element2.setAttribute("x2", String(this.x2)); element2.setAttribute("y2", String(this.y2)); this.applySvgStrokeAttributes(element2); return { elements: [element2] }; } }; Line.className = "Line"; Line.defaultStyles = { ...Shape.defaultStyles, fill: void 0, strokeWidth: 1 }; __decorateClass([ SceneChangeDetection() ], Line.prototype, "x1", 2); __decorateClass([ SceneChangeDetection() ], Line.prototype, "y1", 2); __decorateClass([ SceneChangeDetection() ], Line.prototype, "x2", 2); __decorateClass([ SceneChangeDetection() ], Line.prototype, "y2", 2); } }); // packages/ag-charts-community/src/util/format.util.ts function formatValue(value, maximumFractionDigits = 2) { if (typeof value === "number") { return formatNumber(value, maximumFractionDigits); } return String(value ?? ""); } function formatPercent(value) { return percentFormatter.format(value); } function formatNumber(value, maximumFractionDigits) { if (maximumFractionDigits === 2) { return defaultNumberFormatter.format(value); } return new Intl.NumberFormat("en-US", { maximumFractionDigits, useGrouping: false }).format(value); } var defaultNumberFormatter, percentFormatter; var init_format_util = __esm({ "packages/ag-charts-community/src/util/format.util.ts"() { "use strict"; defaultNumberFormatter = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2, useGrouping: false }); percentFormatter = new Intl.NumberFormat("en-US", { style: "percent" }); } }); // packages/ag-charts-community/src/scene/shape/range.ts var Range; var init_range = __esm({ "packages/ag-charts-community/src/scene/shape/range.ts"() { "use strict"; init_bbox(); init_node(); init_shape(); Range = class extends Shape { constructor(opts = {}) { super(opts); this.x1 = 0; this.y1 = 0; this.x2 = 0; this.y2 = 0; this.startLine = false; this.endLine = false; this.isRange = false; this.restoreOwnStyles(); } computeBBox() { return new BBox(this.x1, this.y1, this.x2 - this.x1, this.y2 - this.y1); } isPointInPath(_x, _y) { return false; } render(renderCtx) { const { ctx } = renderCtx; let { x1, y1, x2, y2 } = this; x1 = this.align(x1); y1 = this.align(y1); x2 = this.align(x2); y2 = this.align(y2); const { fill, opacity, isRange } = this; const fillActive = !!(isRange && fill); if (fillActive) { const { fillOpacity } = this; this.applyFill(ctx); ctx.globalAlpha = opacity * fillOpacity; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y1); ctx.lineTo(x2, y2); ctx.lineTo(x1, y2); ctx.closePath(); ctx.fill(); } const { stroke: stroke3, strokeWidth, startLine, endLine } = this; const strokeActive = !!((startLine || endLine) && stroke3 && strokeWidth); if (strokeActive) { const { strokeOpacity, lineDash, lineDashOffset, lineCap, lineJoin } = this; this.applyStroke(ctx); ctx.globalAlpha = opacity * strokeOpacity; ctx.lineWidth = strokeWidth; if (lineDash) { ctx.setLineDash(lineDash); } if (lineDashOffset) { ctx.lineDashOffset = lineDashOffset; } if (lineCap) { ctx.lineCap = lineCap; } if (lineJoin) { ctx.lineJoin = lineJoin; } ctx.beginPath(); if (startLine) { ctx.moveTo(x1, y1); ctx.lineTo(x2, y1); } if (endLine) { ctx.moveTo(x2, y2); ctx.lineTo(x1, y2); } ctx.stroke(); } this.fillShadow?.markClean(); super.render(renderCtx); } }; Range.className = "Range"; Range.defaultStyles = { ...Shape.defaultStyles, strokeWidth: 1 }; __decorateClass([ SceneChangeDetection() ], Range.prototype, "x1", 2); __decorateClass([ SceneChangeDetection() ], Range.prototype, "y1", 2); __decorateClass([ SceneChangeDetection() ], Range.prototype, "x2", 2); __decorateClass([ SceneChangeDetection() ], Range.prototype, "y2", 2); __decorateClass([ SceneChangeDetection() ], Range.prototype, "startLine", 2); __decorateClass([ SceneChangeDetection() ], Range.prototype, "endLine", 2); __decorateClass([ SceneChangeDetection() ], Range.prototype, "isRange", 2); } }); // packages/ag-charts-community/src/chart/label.ts function calculateLabelRotation(opts) { const { parallelFlipRotation = 0, regularFlipRotation = 0 } = opts; const configuredRotation = opts.rotation ? normalizeAngle360(toRadians(opts.rotation)) : 0; const parallelFlipFlag = !configuredRotation && parallelFlipRotation >= 0 && parallelFlipRotation <= Math.PI ? -1 : 1; const regularFlipFlag = !configuredRotation && regularFlipRotation >= 0 && regularFlipRotation <= Math.PI ? -1 : 1; let defaultRotation = 0; if (opts.parallel) { defaultRotation = parallelFlipFlag * Math.PI / 2; } else if (regularFlipFlag === -1) { defaultRotation = Math.PI; } return { configuredRotation, defaultRotation, parallelFlipFlag, regularFlipFlag }; } function getLabelSpacing(minSpacing, rotated) { if (!isNaN(minSpacing)) { return minSpacing; } return rotated ? 0 : 10; } function getTextBaseline(parallel, labelRotation, sideFlag, parallelFlipFlag) { if (parallel && !labelRotation) { return sideFlag * parallelFlipFlag === -1 ? "hanging" : "bottom"; } return "middle"; } function getTextAlign(parallel, labelRotation, labelAutoRotation, sideFlag, regularFlipFlag) { const labelRotated = labelRotation > 0 && labelRotation <= Math.PI; const labelAutoRotated = labelAutoRotation > 0 && labelAutoRotation <= Math.PI; const alignFlag = labelRotated || labelAutoRotated ? -1 : 1; if (parallel) { if (labelRotation || labelAutoRotation) { if (sideFlag * alignFlag === -1) { return "end"; } } else { return "center"; } } else if (sideFlag * regularFlipFlag === -1) { return "end"; } return "start"; } function createLabelData(tickData, labelX, labelMatrix, textMeasurer) { const labelData = []; for (const { tickLabel: text3, translationY } of tickData) { if (!text3) continue; const { width: width2, height: height2 } = textMeasurer.measureLines(text3); const bbox = new BBox(labelX, translationY, width2, height2); const translatedBBox = new BBox(labelX, translationY, 0, 0); labelMatrix.transformBBox(translatedBBox, bbox); const { x, y } = bbox; labelData.push({ point: { x, y }, label: { text: text3, width: width2, height: height2 } }); } return labelData; } var Label; var init_label = __esm({ "packages/ag-charts-community/src/chart/label.ts"() { "use strict"; init_bbox(); init_angle(); init_properties(); init_textMeasurer(); init_validation2(); Label = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; this.fontSize = 12; this.fontFamily = "Verdana, sans-serif"; } getFont() { return TextUtils.toFontString(this); } }; __decorateClass([ Validate(BOOLEAN) ], Label.prototype, "enabled", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], Label.prototype, "color", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], Label.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], Label.prototype, "fontWeight", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Label.prototype, "fontSize", 2); __decorateClass([ Validate(STRING) ], Label.prototype, "fontFamily", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], Label.prototype, "formatter", 2); } }); // packages/ag-charts-community/src/util/value.ts function isStringObject(value) { return value != null && Object.hasOwn(value, "toString") && isString(value.toString()); } function isNumberObject(value) { return value != null && Object.hasOwn(value, "valueOf") && isFiniteNumber(value.valueOf()); } function isContinuous(value) { return isFiniteNumber(value) || isValidDate(value) || isNumberObject(value); } function checkDatum(value, isContinuousScale) { return value != null && (!isContinuousScale || isContinuous(value)); } function transformIntegratedCategoryValue(value) { if (isStringObject(value) && Object.hasOwn(value, "id")) { return value.id; } return value; } var init_value = __esm({ "packages/ag-charts-community/src/util/value.ts"() { "use strict"; init_main(); } }); // packages/ag-charts-community/src/chart/crossline/crossLine.ts var MATCHING_CROSSLINE_TYPE, validateCrossLineValues; var init_crossLine = __esm({ "packages/ag-charts-community/src/chart/crossline/crossLine.ts"() { "use strict"; init_main(); init_continuousScale(); init_ordinalTimeScale(); init_validation2(); init_value(); MATCHING_CROSSLINE_TYPE = (property) => { return property === "value" ? predicateWithMessage( (_, ctx) => ctx.target["type"] === "line", (ctx) => ctx.target["type"] === "range" ? `crossLine type 'range' to have a 'range' property instead of 'value'` : `crossLine property 'type' to be 'line'` ) : predicateWithMessage( (_, ctx) => ctx.target["type"] === "range", (ctx) => ctx.target.type === "line" ? `crossLine type 'line' to have a 'value' property instead of 'range'` : `crossLine property 'type' to be 'range'` ); }; validateCrossLineValues = (type, value, range4, scale2, visibilityCheck) => { const lineCrossLine = type === "line" && value !== void 0; const rangeCrossLine = type === "range" && range4 !== void 0; if (!lineCrossLine && !rangeCrossLine) { return true; } const [start2, end2] = range4 ?? [value, void 0]; const isContinuous3 = ContinuousScale.is(scale2) || OrdinalTimeScale.is(scale2); const validStart = checkDatum(start2, isContinuous3) && !isNaN(scale2.convert(start2)); const validEnd = checkDatum(end2, isContinuous3) && !isNaN(scale2.convert(end2)); if (lineCrossLine && validStart || rangeCrossLine && validStart && validEnd) { return visibilityCheck?.() ?? true; } const message = [`Expecting crossLine`]; if (rangeCrossLine) { if (!validStart) { message.push(`range start ${stringifyValue(start2)}`); } if (!validEnd) { message.push(`${validStart ? "" : "and "}range end ${stringifyValue(end2)}`); } } else { message.push(`value ${stringifyValue(start2)}`); } message.push(`to match the axis scale domain.`); logger_exports.warnOnce(message.join(" ")); return false; }; } }); // packages/ag-charts-community/src/chart/crossline/crossLineLabelPosition.ts function calculateLabelTranslation({ yDirection, padding = 0, position = "top", bbox }) { const crossLineTranslationDirections = yDirection ? horizontalCrosslineTranslationDirections : verticalCrossLineTranslationDirections; const { xTranslationDirection, yTranslationDirection } = crossLineTranslationDirections[position]; const xTranslation = xTranslationDirection * (padding + bbox.width / 2); const yTranslation = yTranslationDirection * (padding + bbox.height / 2); return { xTranslation, yTranslation }; } function calculateLabelChartPadding({ yDirection, bbox, padding = 0, position = "top" }) { const chartPadding = {}; if (position.startsWith("inside")) return chartPadding; if (position === "top" && !yDirection) { chartPadding.top = padding + bbox.height; } else if (position === "bottom" && !yDirection) { chartPadding.bottom = padding + bbox.height; } else if (position === "left" && yDirection) { chartPadding.left = padding + bbox.width; } else if (position === "right" && yDirection) { chartPadding.right = padding + bbox.width; } return chartPadding; } var horizontalCrosslineTranslationDirections, verticalCrossLineTranslationDirections, POSITION_TOP_COORDINATES, POSITION_LEFT_COORDINATES, POSITION_RIGHT_COORDINATES, POSITION_BOTTOM_COORDINATES, POSITION_INSIDE_COORDINATES, POSITION_TOP_LEFT_COORDINATES, POSITION_BOTTOM_LEFT_COORDINATES, POSITION_TOP_RIGHT_COORDINATES, POSITION_BOTTOM_RIGHT_COORDINATES, labelDirectionHandling; var init_crossLineLabelPosition = __esm({ "packages/ag-charts-community/src/chart/crossline/crossLineLabelPosition.ts"() { "use strict"; horizontalCrosslineTranslationDirections = { top: { xTranslationDirection: 0, yTranslationDirection: -1 }, bottom: { xTranslationDirection: 0, yTranslationDirection: 1 }, left: { xTranslationDirection: -1, yTranslationDirection: 0 }, right: { xTranslationDirection: 1, yTranslationDirection: 0 }, "top-left": { xTranslationDirection: 1, yTranslationDirection: -1 }, "top-right": { xTranslationDirection: -1, yTranslationDirection: -1 }, "bottom-left": { xTranslationDirection: 1, yTranslationDirection: 1 }, "bottom-right": { xTranslationDirection: -1, yTranslationDirection: 1 }, inside: { xTranslationDirection: 0, yTranslationDirection: 0 }, "inside-left": { xTranslationDirection: 1, yTranslationDirection: 0 }, "inside-right": { xTranslationDirection: -1, yTranslationDirection: 0 }, "inside-top": { xTranslationDirection: 0, yTranslationDirection: 1 }, "inside-bottom": { xTranslationDirection: 0, yTranslationDirection: -1 }, "inside-top-left": { xTranslationDirection: 1, yTranslationDirection: 1 }, "inside-bottom-left": { xTranslationDirection: 1, yTranslationDirection: -1 }, "inside-top-right": { xTranslationDirection: -1, yTranslationDirection: 1 }, "inside-bottom-right": { xTranslationDirection: -1, yTranslationDirection: -1 } }; verticalCrossLineTranslationDirections = { top: { xTranslationDirection: 1, yTranslationDirection: 0 }, bottom: { xTranslationDirection: -1, yTranslationDirection: 0 }, left: { xTranslationDirection: 0, yTranslationDirection: -1 }, right: { xTranslationDirection: 0, yTranslationDirection: 1 }, "top-left": { xTranslationDirection: -1, yTranslationDirection: -1 }, "top-right": { xTranslationDirection: -1, yTranslationDirection: 1 }, "bottom-left": { xTranslationDirection: 1, yTranslationDirection: -1 }, "bottom-right": { xTranslationDirection: 1, yTranslationDirection: 1 }, inside: { xTranslationDirection: 0, yTranslationDirection: 0 }, "inside-left": { xTranslationDirection: 0, yTranslationDirection: 1 }, "inside-right": { xTranslationDirection: 0, yTranslationDirection: -1 }, "inside-top": { xTranslationDirection: -1, yTranslationDirection: 0 }, "inside-bottom": { xTranslationDirection: 1, yTranslationDirection: 0 }, "inside-top-left": { xTranslationDirection: -1, yTranslationDirection: 1 }, "inside-bottom-left": { xTranslationDirection: 1, yTranslationDirection: 1 }, "inside-top-right": { xTranslationDirection: -1, yTranslationDirection: -1 }, "inside-bottom-right": { xTranslationDirection: 1, yTranslationDirection: -1 } }; POSITION_TOP_COORDINATES = ({ direction, xEnd, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xEnd / 2, y: yStart }; } else { return { x: xEnd, y: isNaN(yEnd) ? yStart : (yStart + yEnd) / 2 }; } }; POSITION_LEFT_COORDINATES = ({ direction, xStart, xEnd, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xStart, y: isNaN(yEnd) ? yStart : (yStart + yEnd) / 2 }; } else { return { x: xEnd / 2, y: yStart }; } }; POSITION_RIGHT_COORDINATES = ({ direction, xEnd, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xEnd, y: isNaN(yEnd) ? yStart : (yStart + yEnd) / 2 }; } else { return { x: xEnd / 2, y: isNaN(yEnd) ? yStart : yEnd }; } }; POSITION_BOTTOM_COORDINATES = ({ direction, xStart, xEnd, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xEnd / 2, y: isNaN(yEnd) ? yStart : yEnd }; } else { return { x: xStart, y: isNaN(yEnd) ? yStart : (yStart + yEnd) / 2 }; } }; POSITION_INSIDE_COORDINATES = ({ xEnd, yStart, yEnd }) => { return { x: xEnd / 2, y: isNaN(yEnd) ? yStart : (yStart + yEnd) / 2 }; }; POSITION_TOP_LEFT_COORDINATES = ({ direction, xStart, xEnd, yStart }) => { if (direction === "y" /* Y */) { return { x: xStart / 2, y: yStart }; } else { return { x: xEnd, y: yStart }; } }; POSITION_BOTTOM_LEFT_COORDINATES = ({ direction, xStart, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xStart, y: isNaN(yEnd) ? yStart : yEnd }; } else { return { x: xStart, y: yStart }; } }; POSITION_TOP_RIGHT_COORDINATES = ({ direction, xEnd, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xEnd, y: yStart }; } else { return { x: xEnd, y: isNaN(yEnd) ? yStart : yEnd }; } }; POSITION_BOTTOM_RIGHT_COORDINATES = ({ direction, xStart, xEnd, yStart, yEnd }) => { if (direction === "y" /* Y */) { return { x: xEnd, y: isNaN(yEnd) ? yStart : yEnd }; } else { return { x: xStart, y: isNaN(yEnd) ? yStart : yEnd }; } }; labelDirectionHandling = { top: { c: POSITION_TOP_COORDINATES }, bottom: { c: POSITION_BOTTOM_COORDINATES }, left: { c: POSITION_LEFT_COORDINATES }, right: { c: POSITION_RIGHT_COORDINATES }, "top-left": { c: POSITION_TOP_LEFT_COORDINATES }, "top-right": { c: POSITION_TOP_RIGHT_COORDINATES }, "bottom-left": { c: POSITION_BOTTOM_LEFT_COORDINATES }, "bottom-right": { c: POSITION_BOTTOM_RIGHT_COORDINATES }, inside: { c: POSITION_INSIDE_COORDINATES }, "inside-left": { c: POSITION_LEFT_COORDINATES }, "inside-right": { c: POSITION_RIGHT_COORDINATES }, "inside-top": { c: POSITION_TOP_COORDINATES }, "inside-bottom": { c: POSITION_BOTTOM_COORDINATES }, "inside-top-left": { c: POSITION_TOP_LEFT_COORDINATES }, "inside-bottom-left": { c: POSITION_BOTTOM_LEFT_COORDINATES }, "inside-top-right": { c: POSITION_TOP_RIGHT_COORDINATES }, "inside-bottom-right": { c: POSITION_BOTTOM_RIGHT_COORDINATES } }; } }); // packages/ag-charts-community/src/chart/crossline/cartesianCrossLine.ts var CROSSLINE_LABEL_POSITION, CartesianCrossLineLabel, CartesianCrossLine; var init_cartesianCrossLine = __esm({ "packages/ag-charts-community/src/chart/crossline/cartesianCrossLine.ts"() { "use strict"; init_bandScale(); init_continuousScale(); init_ordinalTimeScale(); init_group(); init_range(); init_text(); init_id(); init_number(); init_properties(); init_validation2(); init_label(); init_crossLine(); init_crossLineLabelPosition(); CROSSLINE_LABEL_POSITION = UNION( [ "top", "left", "right", "bottom", "top-left", "top-right", "bottom-left", "bottom-right", "inside", "inside-left", "inside-right", "inside-top", "inside-bottom", "inside-top-left", "inside-bottom-left", "inside-top-right", "inside-bottom-right" ], "crossLine label position" ); CartesianCrossLineLabel = class extends BaseProperties { constructor() { super(...arguments); this.fontSize = 14; this.fontFamily = "Verdana, sans-serif"; this.padding = 5; this.color = "rgba(87, 87, 87, 1)"; } }; __decorateClass([ Validate(BOOLEAN, { optional: true }) ], CartesianCrossLineLabel.prototype, "enabled", 2); __decorateClass([ Validate(STRING, { optional: true }) ], CartesianCrossLineLabel.prototype, "text", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], CartesianCrossLineLabel.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], CartesianCrossLineLabel.prototype, "fontWeight", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], CartesianCrossLineLabel.prototype, "fontSize", 2); __decorateClass([ Validate(STRING) ], CartesianCrossLineLabel.prototype, "fontFamily", 2); __decorateClass([ Validate(NUMBER) ], CartesianCrossLineLabel.prototype, "padding", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], CartesianCrossLineLabel.prototype, "color", 2); __decorateClass([ Validate(CROSSLINE_LABEL_POSITION, { optional: true }) ], CartesianCrossLineLabel.prototype, "position", 2); __decorateClass([ Validate(NUMBER, { optional: true }) ], CartesianCrossLineLabel.prototype, "rotation", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], CartesianCrossLineLabel.prototype, "parallel", 2); CartesianCrossLine = class extends BaseProperties { constructor() { super(); this.id = createId(this); this.label = new CartesianCrossLineLabel(); this.scale = void 0; this.clippedRange = [-Infinity, Infinity]; this.gridLength = 0; this.sideFlag = -1; this.parallelFlipRotation = 0; this.regularFlipRotation = 0; this.direction = "x" /* X */; this.rangeGroup = new Group({ name: this.id }); this.lineGroup = new Group({ name: this.id }); this.labelGroup = new Group({ name: this.id }); this.crossLineRange = new Range(); this.crossLineLabel = new TransformableText(); this.labelPoint = void 0; this.data = []; this.startLine = false; this.endLine = false; this.isRange = false; this._isRange = void 0; this.lineGroup.append(this.crossLineRange); this.labelGroup.append(this.crossLineLabel); this.crossLineRange.pointerEvents = 1 /* None */; } update(visible) { const { enabled, data, type, value, range: range4, scale: scale2 } = this; if (!type || !scale2 || !enabled || !visible || !validateCrossLineValues(type, value, range4, scale2) || data.length === 0) { this.rangeGroup.visible = false; this.lineGroup.visible = false; this.labelGroup.visible = false; return; } this.rangeGroup.visible = visible; this.lineGroup.visible = visible; this.labelGroup.visible = visible; this.updateNodes(); const { isRange } = this; if (isRange !== this._isRange) { if (isRange) { this.rangeGroup.appendChild(this.crossLineRange); } else { this.lineGroup.appendChild(this.crossLineRange); } } this._isRange = isRange; } calculateLayout(visible, reversedAxis) { if (!visible) return; const { scale: scale2, gridLength, sideFlag, direction, label: { position = "top" }, clippedRange, strokeWidth = 0 } = this; this.data = []; if (!scale2) return; const bandwidth = scale2.bandwidth ?? 0; const step = scale2.step ?? 0; const padding = (reversedAxis ? -1 : 1) * (scale2 instanceof BandScale ? (step - bandwidth) / 2 : 0); const [xStart, xEnd] = [0, sideFlag * gridLength]; let [yStart, yEnd] = this.getRange(); const ordinalTimeScalePadding = yEnd === void 0 && OrdinalTimeScale.is(scale2) ? bandwidth / 2 + padding : 0; let [clampedYStart, clampedYEnd] = [ Number(scale2.convert(yStart, true)) - padding + ordinalTimeScalePadding, scale2.convert(yEnd, true) + bandwidth + padding ]; clampedYStart = clampArray(clampedYStart, clippedRange); clampedYEnd = clampArray(clampedYEnd, clippedRange); [yStart, yEnd] = [Number(scale2.convert(yStart)) + ordinalTimeScalePadding, scale2.convert(yEnd) + bandwidth]; const validRange = (yStart === clampedYStart || yEnd === clampedYEnd || clampedYStart !== clampedYEnd) && Math.abs(clampedYEnd - clampedYStart) > 0; if (validRange && clampedYStart > clampedYEnd) { [clampedYStart, clampedYEnd] = [clampedYEnd, clampedYStart]; [yStart, yEnd] = [yEnd, yStart]; } if (yStart - padding >= clampedYStart) yStart -= padding; if (yEnd + padding <= clampedYEnd) yEnd += padding; this.isRange = validRange; this.startLine = strokeWidth > 0 && yStart >= clampedYStart && yStart <= clampedYStart + padding; this.endLine = strokeWidth > 0 && yEnd >= clampedYEnd - bandwidth - padding && yEnd <= clampedYEnd; if (!validRange && !this.startLine && !this.endLine) return; this.data = [clampedYStart, clampedYEnd]; if (!this.label.enabled) return; const { c = POSITION_TOP_COORDINATES } = labelDirectionHandling[position] ?? {}; const { x: labelX, y: labelY } = c({ direction, xStart, xEnd, yStart: clampedYStart, yEnd: clampedYEnd }); this.labelPoint = { x: labelX, y: labelY }; } updateNodes() { this.updateRangeNode(); if (this.label.enabled) { this.updateLabel(); this.positionLabel(); } } updateRangeNode() { const { crossLineRange, sideFlag, gridLength, data, startLine, endLine, isRange, fill, fillOpacity, stroke: stroke3, strokeWidth, lineDash } = this; crossLineRange.x1 = 0; crossLineRange.x2 = sideFlag * gridLength; crossLineRange.y1 = data[0]; crossLineRange.y2 = data[1]; crossLineRange.startLine = startLine; crossLineRange.endLine = endLine; crossLineRange.isRange = isRange; crossLineRange.fill = fill; crossLineRange.fillOpacity = fillOpacity ?? 1; crossLineRange.stroke = stroke3; crossLineRange.strokeWidth = strokeWidth ?? 1; crossLineRange.strokeOpacity = this.strokeOpacity ?? 1; crossLineRange.lineDash = lineDash; } updateLabel() { const { crossLineLabel, label } = this; if (!label.text) return; crossLineLabel.fontStyle = label.fontStyle; crossLineLabel.fontWeight = label.fontWeight; crossLineLabel.fontSize = label.fontSize; crossLineLabel.fontFamily = label.fontFamily; crossLineLabel.fill = label.color; crossLineLabel.text = label.text; } positionLabel() { const { crossLineLabel, labelPoint: { x = void 0, y = void 0 } = {}, label: { parallel, rotation, position = "top", padding = 0 }, direction, parallelFlipRotation, regularFlipRotation } = this; if (x === void 0 || y === void 0) return; const { defaultRotation, configuredRotation } = calculateLabelRotation({ rotation, parallel, regularFlipRotation, parallelFlipRotation }); crossLineLabel.rotation = defaultRotation + configuredRotation; crossLineLabel.textBaseline = "middle"; crossLineLabel.textAlign = "center"; const bbox = crossLineLabel.getBBox(); if (!bbox) return; const yDirection = direction === "y" /* Y */; const { xTranslation, yTranslation } = calculateLabelTranslation({ yDirection, padding, position, bbox }); crossLineLabel.translationX = x + xTranslation; crossLineLabel.translationY = y + yTranslation; } getRange() { const { value, range: range4, scale: scale2 } = this; const isContinuous3 = ContinuousScale.is(scale2) || OrdinalTimeScale.is(scale2); const start2 = range4?.[0] ?? value; let end2 = range4?.[1]; if (!isContinuous3 && end2 === void 0) { end2 = start2; } if (isContinuous3 && start2 === end2) { end2 = void 0; } return [start2, end2]; } computeLabelBBox() { const { label } = this; if (!label.enabled) return; const tempText2 = new TransformableText(); tempText2.fontFamily = label.fontFamily; tempText2.fontSize = label.fontSize; tempText2.fontStyle = label.fontStyle; tempText2.fontWeight = label.fontWeight; tempText2.text = label.text; const { labelPoint: { x = void 0, y = void 0 } = {}, label: { parallel, rotation, position = "top", padding = 0 }, direction, parallelFlipRotation, regularFlipRotation } = this; if (x === void 0 || y === void 0) return; const { configuredRotation } = calculateLabelRotation({ rotation, parallel, regularFlipRotation, parallelFlipRotation }); tempText2.rotation = configuredRotation; tempText2.textBaseline = "middle"; tempText2.textAlign = "center"; const bbox = tempText2.getBBox(); if (!bbox) return; const yDirection = direction === "y" /* Y */; const { xTranslation, yTranslation } = calculateLabelTranslation({ yDirection, padding, position, bbox }); tempText2.x = x + xTranslation; tempText2.y = y + yTranslation; return tempText2.getBBox(); } calculatePadding(padding) { const { isRange, startLine, endLine, direction, label: { padding: labelPadding = 0, position = "top" } } = this; if (!isRange && !startLine && !endLine) return; const crossLineLabelBBox = this.computeLabelBBox(); if (crossLineLabelBBox?.x == null || crossLineLabelBBox?.y == null) return; const chartPadding = calculateLabelChartPadding({ yDirection: direction === "y" /* Y */, padding: labelPadding, position, bbox: crossLineLabelBBox }); padding.left = Math.max(padding.left ?? 0, chartPadding.left ?? 0); padding.right = Math.max(padding.right ?? 0, chartPadding.right ?? 0); padding.top = Math.max(padding.top ?? 0, chartPadding.top ?? 0); padding.bottom = Math.max(padding.bottom ?? 0, chartPadding.bottom ?? 0); } }; CartesianCrossLine.className = "CrossLine"; __decorateClass([ Validate(BOOLEAN, { optional: true }) ], CartesianCrossLine.prototype, "enabled", 2); __decorateClass([ Validate(UNION(["range", "line"], "a crossLine type"), { optional: true }) ], CartesianCrossLine.prototype, "type", 2); __decorateClass([ Validate(AND(MATCHING_CROSSLINE_TYPE("range"), ARRAY.restrict({ length: 2 })), { optional: true }) ], CartesianCrossLine.prototype, "range", 2); __decorateClass([ Validate(MATCHING_CROSSLINE_TYPE("value"), { optional: true }) ], CartesianCrossLine.prototype, "value", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], CartesianCrossLine.prototype, "fill", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], CartesianCrossLine.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], CartesianCrossLine.prototype, "stroke", 2); __decorateClass([ Validate(NUMBER, { optional: true }) ], CartesianCrossLine.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], CartesianCrossLine.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH, { optional: true }) ], CartesianCrossLine.prototype, "lineDash", 2); __decorateClass([ Validate(OBJECT) ], CartesianCrossLine.prototype, "label", 2); } }); // packages/ag-charts-community/src/chart/zIndexMap.ts var ZIndexMap; var init_zIndexMap = __esm({ "packages/ag-charts-community/src/chart/zIndexMap.ts"() { "use strict"; ZIndexMap = /* @__PURE__ */ ((ZIndexMap9) => { ZIndexMap9[ZIndexMap9["CHART_BACKGROUND"] = 0] = "CHART_BACKGROUND"; ZIndexMap9[ZIndexMap9["AXIS_GRID"] = 1] = "AXIS_GRID"; ZIndexMap9[ZIndexMap9["AXIS"] = 2] = "AXIS"; ZIndexMap9[ZIndexMap9["ZOOM_SELECTION"] = 3] = "ZOOM_SELECTION"; ZIndexMap9[ZIndexMap9["SERIES_CROSSLINE_RANGE"] = 4] = "SERIES_CROSSLINE_RANGE"; ZIndexMap9[ZIndexMap9["SERIES_LAYER"] = 5] = "SERIES_LAYER"; ZIndexMap9[ZIndexMap9["AXIS_FOREGROUND"] = 6] = "AXIS_FOREGROUND"; ZIndexMap9[ZIndexMap9["SERIES_CROSSHAIR"] = 7] = "SERIES_CROSSHAIR"; ZIndexMap9[ZIndexMap9["SERIES_CROSSLINE_LINE"] = 8] = "SERIES_CROSSLINE_LINE"; ZIndexMap9[ZIndexMap9["SERIES_ANNOTATION"] = 9] = "SERIES_ANNOTATION"; ZIndexMap9[ZIndexMap9["CHART_ANNOTATION"] = 10] = "CHART_ANNOTATION"; ZIndexMap9[ZIndexMap9["CHART_ANNOTATION_FOCUSED"] = 11] = "CHART_ANNOTATION_FOCUSED"; ZIndexMap9[ZIndexMap9["STATUS_BAR"] = 12] = "STATUS_BAR"; ZIndexMap9[ZIndexMap9["SERIES_LABEL"] = 13] = "SERIES_LABEL"; ZIndexMap9[ZIndexMap9["LEGEND"] = 14] = "LEGEND"; ZIndexMap9[ZIndexMap9["NAVIGATOR"] = 15] = "NAVIGATOR"; ZIndexMap9[ZIndexMap9["FOREGROUND"] = 16] = "FOREGROUND"; return ZIndexMap9; })(ZIndexMap || {}); } }); // packages/ag-charts-community/src/chart/axis/axisGridLine.ts var GRID_STYLE_KEYS, GRID_STYLE, AxisGridLine; var init_axisGridLine = __esm({ "packages/ag-charts-community/src/chart/axis/axisGridLine.ts"() { "use strict"; init_main(); init_validation2(); GRID_STYLE_KEYS = ["stroke", "lineDash"]; GRID_STYLE = ARRAY_OF( (value) => isObject(value) && Object.keys(value).every((key) => GRID_STYLE_KEYS.includes(key)), "objects with gridline style properties such as 'stroke' or 'lineDash'" ); AxisGridLine = class { constructor() { this.enabled = true; this.width = 1; this.style = [ { stroke: void 0, lineDash: [] } ]; } }; __decorateClass([ Validate(BOOLEAN) ], AxisGridLine.prototype, "enabled", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AxisGridLine.prototype, "width", 2); __decorateClass([ Validate(GRID_STYLE) ], AxisGridLine.prototype, "style", 2); } }); // packages/ag-charts-community/src/util/default.ts function Default(defaultValue, replaces = [void 0]) { return addTransformToInstanceProperty((_, __, v) => { if (replaces.includes(v)) { return isFunction(defaultValue) ? defaultValue(v) : defaultValue; } return v; }); } var init_default = __esm({ "packages/ag-charts-community/src/util/default.ts"() { "use strict"; init_main(); init_decorator(); } }); // packages/ag-charts-community/src/chart/axis/axisInterval.ts var TICK_INTERVAL, AxisInterval; var init_axisInterval = __esm({ "packages/ag-charts-community/src/chart/axis/axisInterval.ts"() { "use strict"; init_main(); init_default(); init_properties(); init_time(); init_validation2(); TICK_INTERVAL = predicateWithMessage( (value) => isFiniteNumber(value) && value > 0 || value instanceof TimeInterval, `a non-zero positive Number value or, for a time axis, a Time Interval such as 'agCharts.time.month'` ); AxisInterval = class extends BaseProperties { constructor() { super(...arguments); this.minSpacing = NaN; this.maxSpacing = NaN; } }; __decorateClass([ Validate(TICK_INTERVAL, { optional: true }) ], AxisInterval.prototype, "step", 2); __decorateClass([ Validate(ARRAY, { optional: true }) ], AxisInterval.prototype, "values", 2); __decorateClass([ Validate(MIN_SPACING), Default(NaN) ], AxisInterval.prototype, "minSpacing", 2); __decorateClass([ Validate(MAX_SPACING), Default(NaN) ], AxisInterval.prototype, "maxSpacing", 2); } }); // packages/ag-charts-community/src/chart/axis/axisLabel.ts var AxisLabel; var init_axisLabel = __esm({ "packages/ag-charts-community/src/chart/axis/axisLabel.ts"() { "use strict"; init_default(); init_properties(); init_validation2(); AxisLabel = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; this.fontSize = 12; this.fontFamily = "Verdana, sans-serif"; this.spacing = 5; this.minSpacing = NaN; this.color = "#575757"; this.avoidCollisions = true; this.mirrored = false; this.parallel = false; } /** * The side of the axis line to position the labels on. * -1 = left (default) * 1 = right */ getSideFlag() { return this.mirrored ? 1 : -1; } }; __decorateClass([ Validate(BOOLEAN) ], AxisLabel.prototype, "enabled", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], AxisLabel.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], AxisLabel.prototype, "fontWeight", 2); __decorateClass([ Validate(NUMBER.restrict({ min: 1 })) ], AxisLabel.prototype, "fontSize", 2); __decorateClass([ Validate(STRING) ], AxisLabel.prototype, "fontFamily", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AxisLabel.prototype, "spacing", 2); __decorateClass([ Validate(NUMBER_OR_NAN), Default(NaN) ], AxisLabel.prototype, "minSpacing", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], AxisLabel.prototype, "color", 2); __decorateClass([ Validate(NUMBER, { optional: true }) ], AxisLabel.prototype, "rotation", 2); __decorateClass([ Validate(BOOLEAN) ], AxisLabel.prototype, "avoidCollisions", 2); __decorateClass([ Validate(BOOLEAN) ], AxisLabel.prototype, "mirrored", 2); __decorateClass([ Validate(BOOLEAN) ], AxisLabel.prototype, "parallel", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], AxisLabel.prototype, "itemStyler", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], AxisLabel.prototype, "formatter", 2); __decorateClass([ Validate(STRING, { optional: true }) ], AxisLabel.prototype, "format", 2); } }); // packages/ag-charts-community/src/chart/axis/axisLine.ts var AxisLine; var init_axisLine = __esm({ "packages/ag-charts-community/src/chart/axis/axisLine.ts"() { "use strict"; init_validation2(); AxisLine = class { constructor() { this.enabled = true; this.width = 1; this.stroke = void 0; } }; __decorateClass([ Validate(BOOLEAN) ], AxisLine.prototype, "enabled", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AxisLine.prototype, "width", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], AxisLine.prototype, "stroke", 2); } }); // packages/ag-charts-community/src/chart/axis/axisTick.ts var AxisTick; var init_axisTick = __esm({ "packages/ag-charts-community/src/chart/axis/axisTick.ts"() { "use strict"; init_properties(); init_validation2(); AxisTick = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; this.width = 1; this.size = 6; } }; __decorateClass([ Validate(BOOLEAN) ], AxisTick.prototype, "enabled", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AxisTick.prototype, "width", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AxisTick.prototype, "size", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], AxisTick.prototype, "stroke", 2); } }); // packages/ag-charts-community/src/chart/axis/axisTitle.ts var AxisTitle; var init_axisTitle = __esm({ "packages/ag-charts-community/src/chart/axis/axisTitle.ts"() { "use strict"; init_properties(); init_validation2(); init_caption(); AxisTitle = class extends BaseProperties { constructor() { super(...arguments); this.caption = new Caption(); this.enabled = false; this.spacing = Caption.SMALL_PADDING; this.fontSize = 10; this.fontFamily = "sans-serif"; this.wrapping = "always"; } }; __decorateClass([ Validate(BOOLEAN) ], AxisTitle.prototype, "enabled", 2); __decorateClass([ Validate(STRING, { optional: true }) ], AxisTitle.prototype, "text", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], AxisTitle.prototype, "spacing", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], AxisTitle.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], AxisTitle.prototype, "fontWeight", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AxisTitle.prototype, "fontSize", 2); __decorateClass([ Validate(STRING) ], AxisTitle.prototype, "fontFamily", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], AxisTitle.prototype, "color", 2); __decorateClass([ Validate(TEXT_WRAP) ], AxisTitle.prototype, "wrapping", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], AxisTitle.prototype, "formatter", 2); } }); // packages/ag-charts-community/src/chart/axis/axisUtil.ts function prepareAxisAnimationContext(axis) { const [requestedRangeMin, requestedRangeMax] = findMinMax(axis.range); const min = Math.floor(requestedRangeMin); const max = Math.ceil(requestedRangeMax); return { min, max, visible: min !== max }; } function normaliseEndRotation(start2, end2) { const directDistance = Math.abs(end2 - start2); if (directDistance < halfCircle) { return end2; } else if (start2 > end2) { return end2 + fullCircle; } return end2 - fullCircle; } function prepareAxisAnimationFunctions(ctx) { const outOfBounds = (y, range4) => { const [min = ctx.min, max = ctx.max] = findMinMax(range4 ?? []); return y < min || y > max; }; const tick = { fromFn(node, datum, status) { let y = node.y1 + node.translationY; let opacity = node.opacity; if (status === "added" || outOfBounds(node.datum.translationY, node.datum.range)) { y = datum.translationY; opacity = 0; } return { y: 0, translationY: y, opacity, phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[status] }; }, toFn(_node, datum, status) { const y = datum.translationY; let opacity = 1; if (status === "removed") { opacity = 0; } return { y: 0, translationY: y, opacity, finish: { // Set explicit y after animation so it's pixel aligned y, translationY: 0 } }; }, applyFn(node, props) { node.setProperties(props); node.visible = !outOfBounds(node.y); } }; const label = { fromFn(node, newDatum, status) { const datum = node.previousDatum ?? newDatum; const x = datum.x; const y = datum.y; const rotationCenterX = datum.rotationCenterX; let translationY = Math.round(node.translationY); let rotation = datum.rotation; let opacity = node.opacity; if (status === "removed" || outOfBounds(datum.y, datum.range)) { rotation = newDatum.rotation; } else if (status === "added" || outOfBounds(node.datum.y, node.datum.range)) { translationY = Math.round(datum.translationY); opacity = 0; rotation = newDatum.rotation; } return { x, y, rotationCenterX, translationY, rotation, opacity, phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[status] }; }, toFn(node, datum, status) { const x = datum.x; const y = datum.y; const rotationCenterX = datum.rotationCenterX; const translationY = Math.round(datum.translationY); let rotation = 0; let opacity = 1; if (status === "added") { rotation = datum.rotation; } else if (status === "removed") { opacity = 0; rotation = datum.rotation; } else { rotation = normaliseEndRotation(node.previousDatum?.rotation ?? datum.rotation, datum.rotation); } return { x, y, rotationCenterX, translationY, rotation, opacity, finish: { rotation: datum.rotation } }; } }; const line = { fromFn(node, datum) { return { ...node.previousDatum ?? datum, phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING["updated"] }; }, toFn(_node, datum) { return { ...datum }; } }; const group = { fromFn(node, _datum) { const { rotation, translationX, translationY } = node; return { rotation, translationX, translationY, phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING["updated"] }; }, toFn(_node, datum) { const { rotation, translationX, translationY } = datum; return { rotation, translationX, translationY }; } }; return { tick, line, label, group }; } function resetAxisGroupFn() { return (_node, datum) => { return { rotation: datum.rotation, rotationCenterX: datum.rotationCenterX, rotationCenterY: datum.rotationCenterY, translationX: datum.translationX, translationY: datum.translationY }; }; } function resetAxisSelectionFn(ctx) { const { visible: rangeVisible, min, max } = ctx; return (_node, datum) => { const y = datum.translationY; const visible = rangeVisible && y >= min && y <= max; return { y, translationY: 0, opacity: 1, visible }; }; } function resetAxisLabelSelectionFn() { return (_node, datum) => { return { x: datum.x, y: datum.y, translationY: datum.translationY, rotation: datum.rotation, rotationCenterX: datum.rotationCenterX }; }; } function resetAxisLineSelectionFn() { return (_node, datum) => { return { ...datum }; }; } var NiceMode, fullCircle, halfCircle; var init_axisUtil = __esm({ "packages/ag-charts-community/src/chart/axis/axisUtil.ts"() { "use strict"; init_fromToMotion(); init_number(); NiceMode = /* @__PURE__ */ ((NiceMode2) => { NiceMode2[NiceMode2["TickAndDomain"] = 0] = "TickAndDomain"; NiceMode2[NiceMode2["TicksOnly"] = 1] = "TicksOnly"; NiceMode2[NiceMode2["Off"] = 2] = "Off"; return NiceMode2; })(NiceMode || {}); fullCircle = Math.PI * 2; halfCircle = fullCircle / 2; } }); // packages/ag-charts-community/src/chart/axis/axis.ts var TranslatableLine, AxisGroupZIndexMap, _Axis, Axis; var init_axis = __esm({ "packages/ag-charts-community/src/chart/axis/axis.ts"() { "use strict"; init_main(); init_moduleMap(); init_continuousScale(); init_ordinalTimeScale(); init_bbox(); init_group(); init_matrix(); init_selection(); init_line(); init_text(); init_transformable(); init_angle(); init_format_util(); init_id(); init_number(); init_object(); init_proxy(); init_validation2(); init_cartesianCrossLine(); init_axisGridLine(); init_axisInterval(); init_axisLabel(); init_axisLine(); init_axisTick(); init_axisTitle(); TranslatableLine = class extends Translatable(Line) { }; AxisGroupZIndexMap = /* @__PURE__ */ ((AxisGroupZIndexMap3) => { AxisGroupZIndexMap3[AxisGroupZIndexMap3["TickLines"] = 0] = "TickLines"; AxisGroupZIndexMap3[AxisGroupZIndexMap3["AxisLine"] = 1] = "AxisLine"; AxisGroupZIndexMap3[AxisGroupZIndexMap3["TickLabels"] = 2] = "TickLabels"; return AxisGroupZIndexMap3; })(AxisGroupZIndexMap || {}); _Axis = class _Axis { constructor(moduleCtx, scale2) { this.moduleCtx = moduleCtx; this.scale = scale2; this.id = createId(this); this.nice = true; this.reverse = false; this.keys = []; this.interval = new AxisInterval(); this.dataDomain = { domain: [], clipped: false }; this.layoutConstraints = { stacked: true, align: "start", width: 100, unit: "percent" }; this.boundSeries = []; this.includeInvisibleDomains = false; this.interactionEnabled = true; this.axisGroup = new TransformableGroup({ name: `${this.id}-axis` }); // Order is important to apply the correct z-index. this.tickLineGroup = this.axisGroup.appendChild( new Group({ name: `${this.id}-Axis-tick-lines`, zIndex: 0 /* TickLines */ }) ); this.tickLabelGroup = this.axisGroup.appendChild( new Group({ name: `${this.id}-Axis-tick-labels`, zIndex: 2 /* TickLabels */ }) ); this.labelGroup = new Group({ name: `${this.id}-Labels`, zIndex: 9 /* SERIES_ANNOTATION */ }); this.gridGroup = new TransformableGroup({ name: `${this.id}-Axis-grid`, zIndex: 1 /* AXIS_GRID */ }); this.gridLineGroup = this.gridGroup.appendChild(new Group({ name: `${this.id}-gridLines` })); this.crossLineRangeGroup = new TransformableGroup({ name: `${this.id}-CrossLines-Range`, zIndex: 4 /* SERIES_CROSSLINE_RANGE */ }); this.crossLineLineGroup = new TransformableGroup({ name: `${this.id}-CrossLines-Line`, zIndex: 8 /* SERIES_CROSSLINE_LINE */ }); this.crossLineLabelGroup = new TransformableGroup({ name: `${this.id}-CrossLines-Label`, zIndex: 13 /* SERIES_LABEL */ }); this.tickLineGroupSelection = Selection.select( this.tickLineGroup, TranslatableLine, false ); this.tickLabelGroupSelection = Selection.select( this.tickLabelGroup, TransformableText, false ); this.gridLineGroupSelection = Selection.select( this.gridLineGroup, TranslatableLine, false ); this._crossLines = []; this.line = new AxisLine(); this.tick = new AxisTick(); this.gridLine = new AxisGridLine(); this.label = this.createLabel(); this.defaultTickMinSpacing = _Axis.defaultTickMinSpacing; this.translation = { x: 0, y: 0 }; this.rotation = 0; // axis rotation angle in degrees this.layout = { label: { fractionDigits: 0, spacing: this.label.spacing, format: this.label.format } }; this.axisContext = void 0; this.labelFormatter = void 0; this.datumFormatter = void 0; this.scaleFormatterParams = void 0; this.destroyFns = []; this.range = [0, 1]; this.visibleRange = [0, 1]; this.title = new AxisTitle(); this.gridLength = 0; /** * The distance between the grid ticks and the axis ticks. */ this.gridPadding = 0; /** * Is used to avoid collisions between axis labels and series. */ this.seriesAreaPadding = 0; this.animatable = true; this._scaleNiceDomainInputDomain = void 0; this._scaleNiceDomainRangeExtent = NaN; this.moduleMap = new ModuleMap(); this.range = this.scale.range.slice(); this.crossLines.forEach((crossLine) => this.initCrossLine(crossLine)); } get type() { return this.constructor.type ?? ""; } get labelNodes() { return this.tickLabelGroupSelection.nodes(); } set crossLines(value) { const { CrossLineConstructor } = this.constructor; this._crossLines.forEach((crossLine) => this.detachCrossLine(crossLine)); this._crossLines = value.map((crossLine) => { const instance = new CrossLineConstructor(); instance.set(crossLine); return instance; }); this._crossLines.forEach((crossLine) => { this.attachCrossLine(crossLine); this.initCrossLine(crossLine); }); } get crossLines() { return this._crossLines; } resetAnimation(_phase) { } attachCrossLine(crossLine) { this.crossLineRangeGroup.appendChild(crossLine.rangeGroup); this.crossLineLineGroup.appendChild(crossLine.lineGroup); this.crossLineLabelGroup.appendChild(crossLine.labelGroup); } detachCrossLine(crossLine) { this.crossLineRangeGroup.removeChild(crossLine.rangeGroup); this.crossLineLineGroup.removeChild(crossLine.lineGroup); this.crossLineLabelGroup.removeChild(crossLine.labelGroup); } destroy() { this.moduleMap.destroy(); this.destroyFns.forEach((f) => f()); } updateScale() { const { range: rr, visibleRange: vr, scale: scale2 } = this; const span = (rr[1] - rr[0]) / (vr[1] - vr[0]); const shift = span * vr[0]; const start2 = rr[0] - shift; scale2.range = [start2, start2 + span]; this.crossLines.forEach((crossLine) => { crossLine.clippedRange = [rr[0], rr[1]]; }); } setCrossLinesVisible(visible) { this.crossLineRangeGroup.visible = visible; this.crossLineLineGroup.visible = visible; this.crossLineLabelGroup.visible = visible; } attachAxis(groups) { groups.gridNode.appendChild(this.gridGroup); groups.axisNode.appendChild(this.axisGroup); groups.labelNode.appendChild(this.labelGroup); groups.crossLineRangeNode.appendChild(this.crossLineRangeGroup); groups.crossLineLineNode.appendChild(this.crossLineLineGroup); groups.crossLineLabelNode.appendChild(this.crossLineLabelGroup); } detachAxis(groups) { groups.gridNode.removeChild(this.gridGroup); groups.axisNode.removeChild(this.axisGroup); groups.labelNode.removeChild(this.labelGroup); groups.crossLineRangeNode.removeChild(this.crossLineRangeGroup); groups.crossLineLineNode.removeChild(this.crossLineLineGroup); groups.crossLineLabelNode.removeChild(this.crossLineLabelGroup); } attachLabel(axisLabelNode) { this.labelGroup.append(axisLabelNode); } /** * Checks if a point or an object is in range. * @param value A point (or object's starting point). * @param tolerance Expands the range on both ends by this amount. */ inRange(value, tolerance = 0) { const [min, max] = findMinMax(this.range); return value >= min - tolerance && value <= max + tolerance; } defaultDatumFormatter(datum, fractionDigits) { return formatValue(datum, fractionDigits + 1); } defaultLabelFormatter(datum, fractionDigits) { return formatValue(datum, fractionDigits); } onGridLengthChange(value, prevValue) { if (prevValue ^ value) { this.onGridVisibilityChange(); } this.crossLines.forEach((crossLine) => this.initCrossLine(crossLine)); } onGridVisibilityChange() { this.gridLineGroupSelection.clear(); } createLabel() { return new AxisLabel(); } /** * Creates/removes/updates the scene graph nodes that constitute the axis. */ update() { this.updatePosition(); this.updateSelections(); this.tickLineGroup.visible = this.tick.enabled; this.gridLineGroup.visible = this.gridLine.enabled; this.tickLabelGroup.visible = this.label.enabled; this.updateLabels(); this.updateGridLines(); this.updateTickLines(); this.updateCrossLines(); } getAxisLineCoordinates() { const [min, max] = findMinMax(this.range); return { x: 0, y1: min, y2: max }; } getLabelStyles(params, additionalStyles) { const { label } = this; const defaultStyle = { color: label.color, spacing: label.spacing, fontFamily: label.fontFamily, fontSize: label.fontSize, fontStyle: label.fontStyle, fontWeight: label.fontWeight }; let stylerOutput; if (label.itemStyler) { stylerOutput = this.moduleCtx.callbackCache.call(label.itemStyler, { ...params, ...defaultStyle }); } const { color: fill, fontFamily, fontSize, fontStyle, fontWeight, spacing } = mergeDefaults(stylerOutput, additionalStyles, defaultStyle); return { fill, fontFamily, fontSize, fontStyle, fontWeight, spacing }; } getTickSize() { return this.tick.enabled ? this.tick.size : 0; } setTitleProps(caption, params) { const { title } = this; if (!title.enabled) { caption.enabled = false; caption.node.visible = false; return; } caption.enabled = true; caption.color = title.color; caption.fontFamily = title.fontFamily; caption.fontSize = title.fontSize; caption.fontStyle = title.fontStyle; caption.fontWeight = title.fontWeight; caption.wrapping = title.wrapping; const titleNode = caption.node; const padding = (title.spacing ?? 0) + params.spacing; const sideFlag = this.label.getSideFlag(); const parallelFlipRotation = normalizeAngle360(this.rotation); const titleRotationFlag = sideFlag === -1 && parallelFlipRotation > Math.PI && parallelFlipRotation < Math.PI * 2 ? -1 : 1; const rotation = titleRotationFlag * sideFlag * Math.PI / 2; const textBaseline = titleRotationFlag === 1 ? "bottom" : "top"; const { range: range4 } = this; const x = Math.floor(titleRotationFlag * sideFlag * (range4[0] + range4[1]) / 2); const y = sideFlag === -1 ? Math.floor(titleRotationFlag * -padding) : Math.floor(-padding); const { callbackCache } = this.moduleCtx; const { formatter = (p) => p.defaultValue } = title; const text3 = callbackCache.call(formatter, this.getTitleFormatterParams()); caption.text = text3; titleNode.setProperties({ visible: true, text: text3, textBaseline, x, y, rotation }); } processData() { const { includeInvisibleDomains, boundSeries, direction } = this; const visibleSeries = includeInvisibleDomains ? boundSeries : boundSeries.filter((s) => s.isEnabled()); const domains = visibleSeries.map((series) => series.getDomain(direction)); this.setDomains(...domains); } setDomains(...domains) { let domain; let animatable; if (domains.length > 0) { ({ domain, animatable } = this.scale.normalizeDomains(...domains)); } else { domain = []; animatable = true; } this.dataDomain = this.normaliseDataDomain(domain); if (this.reverse) { this.dataDomain.domain.reverse(); } this.animatable = animatable; } calculateLayout(initialPrimaryTickCount) { const { scale: scale2, label, visibleRange, nice } = this; this.updateScale(); const rangeExtent = findRangeExtent(this.range); const domain = this.dataDomain.domain; let tickLayoutDomain; if (visibleRange[0] === 0 && visibleRange[1] === 1) { tickLayoutDomain = void 0; } else if (!nice) { tickLayoutDomain = domain; } else if (this._scaleNiceDomainInputDomain === domain && this._scaleNiceDomainRangeExtent === rangeExtent) { tickLayoutDomain = this.scale.domain; } else { tickLayoutDomain = this.calculateTickLayout(domain, 0 /* TickAndDomain */, [0, 1]).niceDomain; } let niceMode; if (!nice) { niceMode = 2 /* Off */; } else if (tickLayoutDomain == null) { niceMode = 0 /* TickAndDomain */; } else { niceMode = 1 /* TicksOnly */; } const { niceDomain, primaryTickCount, ticks, tickDomain, fractionDigits, bbox } = this.calculateTickLayout( tickLayoutDomain ?? domain, niceMode, visibleRange, initialPrimaryTickCount ); this.scale.domain = niceDomain; this._scaleNiceDomainInputDomain = nice ? domain : void 0; this._scaleNiceDomainRangeExtent = nice ? rangeExtent : NaN; const specifier = label.format; this.labelFormatter = scale2.tickFormatter({ domain: tickDomain, specifier, ticks, fractionDigits }) ?? ((value) => this.defaultLabelFormatter(value, fractionDigits)); this.datumFormatter = scale2.datumFormatter({ domain: tickDomain, specifier, ticks, fractionDigits }) ?? ((value) => this.defaultDatumFormatter(value, fractionDigits)); this.scaleFormatterParams = { domain: tickDomain, ticks, fractionDigits }; this.layout.label = { fractionDigits, spacing: this.label.spacing, format: this.label.format }; const sideFlag = label.getSideFlag(); const anySeriesActive = this.isAnySeriesActive(); const { rotation, parallelFlipRotation, regularFlipRotation } = this.calculateRotations(); this.crossLines.forEach((crossLine) => { var _a; crossLine.sideFlag = -sideFlag; crossLine.direction = rotation === -Math.PI / 2 ? "x" /* X */ : "y" /* Y */; if (crossLine instanceof CartesianCrossLine) { (_a = crossLine.label).parallel ?? (_a.parallel = label.parallel); } crossLine.parallelFlipRotation = parallelFlipRotation; crossLine.regularFlipRotation = regularFlipRotation; crossLine.calculateLayout?.(anySeriesActive, this.reverse); }); return { primaryTickCount, bbox }; } getTransformBox(bbox) { const matrix = new Matrix(); const { rotation, translationX, translationY } = this.getAxisTransform(); Matrix.updateTransformMatrix(matrix, 1, 1, rotation, translationX, translationY); return matrix.transformBBox(bbox); } calculateRotations() { const rotation = toRadians(this.rotation); const parallelFlipRotation = normalizeAngle360(rotation); const regularFlipRotation = normalizeAngle360(rotation - Math.PI / 2); return { rotation, parallelFlipRotation, regularFlipRotation }; } updateCrossLines() { const anySeriesActive = this.isAnySeriesActive(); this.crossLines.forEach((crossLine) => { crossLine.update(anySeriesActive); }); } updateTickLines() { const { tick, label } = this; const sideFlag = label.getSideFlag(); this.tickLineGroupSelection.each((line, datum) => { line.strokeWidth = datum.tickWidth ?? tick.width; line.stroke = datum.tickStroke ?? tick.stroke; line.x1 = sideFlag * (datum.tickSize ?? this.getTickSize()); line.x2 = 0; }); } getAxisTransform() { return { rotation: toRadians(this.rotation), translationX: Math.floor(this.translation.x), translationY: Math.floor(this.translation.y) }; } updatePosition() { const { crossLineRangeGroup, crossLineLineGroup, crossLineLabelGroup, gridGroup, translation } = this; const { rotation } = this.calculateRotations(); const translationX = Math.floor(translation.x); const translationY = Math.floor(translation.y); crossLineRangeGroup.setProperties({ rotation, translationX, translationY }); crossLineLineGroup.setProperties({ rotation, translationX, translationY }); crossLineLabelGroup.setProperties({ rotation, translationX, translationY }); gridGroup.setProperties({ rotation, translationX, translationY }); } updateGridLines() { const sideFlag = this.label.getSideFlag(); const { gridLine: { style, width: width2 }, gridPadding, gridLength } = this; if (gridLength === 0 || style.length === 0) { return; } this.gridLineGroupSelection.each((line, _, index) => { const { stroke: stroke3, lineDash } = style[index % style.length]; line.setProperties({ x1: gridPadding, x2: -sideFlag * gridLength + gridPadding, stroke: stroke3, strokeWidth: width2, lineDash }); }); } // For formatting (nice rounded) tick values. formatTick(value, index, fractionDigits, defaultFormatter) { const { labelFormatter, label: { formatter }, moduleCtx: { callbackCache } } = this; let result; if (formatter) { result = callbackCache.call(formatter, { value, index, fractionDigits }); } else if (defaultFormatter) { result = defaultFormatter(value); } else if (labelFormatter) { result = labelFormatter(value); } return String(result ?? value); } // For formatting arbitrary values between the ticks. formatDatum(value) { const { label: { formatter }, moduleCtx: { callbackCache }, datumFormatter: valueFormatter = this.labelFormatter } = this; let result; if (formatter) { result = callbackCache.call(formatter, { value, index: NaN }); } else if (valueFormatter) { result = callbackCache.call(valueFormatter, value); } else if (isArray(value)) { result = value.filter(Boolean).join(" - "); } return String(result ?? value); } getScaleValueFormatter(format) { const { scaleFormatterParams } = this; let formatter; try { if (format != null && scaleFormatterParams != null) { formatter = this.scale.tickFormatter({ ...scaleFormatterParams, specifier: format }); } } catch { logger_exports.warnOnce(`the format string ${format} is invalid, ignoring.`); } formatter ?? (formatter = (value) => this.formatDatum(value)); return formatter; } getBBox() { return this.axisGroup.getBBox(); } initCrossLine(crossLine) { crossLine.scale = this.scale; crossLine.gridLength = this.gridLength; } isAnySeriesActive() { return this.boundSeries.some((s) => this.includeInvisibleDomains || s.isEnabled()); } clipTickLines(x, y, width2, height2) { this.tickLineGroup.setClipRect(new BBox(x, y, width2, height2)); } clipGrid(x, y, width2, height2) { this.gridGroup.setClipRect(new BBox(x, y, width2, height2)); } getTitleFormatterParams() { const { direction } = this; const boundSeries = []; for (const series of this.boundSeries) { const keys = series.getKeys(direction); const names = series.getNames(direction); for (let idx = 0; idx < keys.length; idx++) { boundSeries.push({ key: keys[idx], name: names[idx] }); } } return { direction, boundSeries, defaultValue: this.title?.text }; } normaliseDataDomain(d) { return { domain: [...d], clipped: false }; } getLayoutState() { return { id: this.id, rect: this.getBBox(), gridPadding: this.gridPadding, seriesAreaPadding: this.seriesAreaPadding, tickSize: this.getTickSize(), direction: this.direction, domain: this.dataDomain.domain, scale: this.scale, ...this.layout }; } getModuleMap() { return this.moduleMap; } createModuleContext() { this.axisContext ?? (this.axisContext = this.createAxisContext()); return { ...this.moduleCtx, parent: this.axisContext }; } createAxisContext() { const { scale: scale2 } = this; return { axisId: this.id, scale: this.scale, direction: this.direction, continuous: ContinuousScale.is(scale2) || OrdinalTimeScale.is(scale2), getCanvasBounds: () => { return Transformable.toCanvas(this.axisGroup); }, seriesKeyProperties: () => this.boundSeries.reduce((keys, series) => { const seriesKeys = series.getKeyProperties(this.direction); seriesKeys.forEach((key) => keys.add(key)); return keys; }, /* @__PURE__ */ new Set()), seriesIds: () => this.boundSeries.map((series) => series.id), scaleValueFormatter: (specifier) => this.getScaleValueFormatter(specifier), scaleInvert: (val) => scale2.invert(val, true), scaleInvertNearest: (val) => scale2.invert(val, true), attachLabel: (node) => this.attachLabel(node), inRange: (x, tolerance) => this.inRange(x, tolerance) }; } isReversed() { return this.reverse; } }; _Axis.defaultTickMinSpacing = 50; _Axis.CrossLineConstructor = CartesianCrossLine; __decorateClass([ Validate(BOOLEAN) ], _Axis.prototype, "nice", 2); __decorateClass([ Validate(BOOLEAN) ], _Axis.prototype, "reverse", 2); __decorateClass([ Validate(STRING_ARRAY) ], _Axis.prototype, "keys", 2); __decorateClass([ Validate(OBJECT) ], _Axis.prototype, "interval", 2); __decorateClass([ Validate(OBJECT) ], _Axis.prototype, "title", 2); __decorateClass([ ObserveChanges((target, value, oldValue) => target.onGridLengthChange(value, oldValue)) ], _Axis.prototype, "gridLength", 2); Axis = _Axis; } }); // packages/ag-charts-community/src/scene/util/labelPlacement.ts function circleRectOverlap(c, unitCenter, x, y, w, h) { if (c.size === 0) { return false; } let cx = c.x; let cy = c.y; if (unitCenter != null) { cx -= (unitCenter.x - 0.5) * c.size; cy -= (unitCenter.y - 0.5) * c.size; } let edgeX = cx; if (cx < x) { edgeX = x; } else if (cx > x + w) { edgeX = x + w; } let edgeY = cy; if (cy < y) { edgeY = y; } else if (cy > y + h) { edgeY = y + h; } const dx2 = cx - edgeX; const dy2 = cy - edgeY; const d = Math.sqrt(dx2 * dx2 + dy2 * dy2); return d <= c.size * 0.5; } function rectRectOverlap(r1, x2, y2, w2, h2) { const xOverlap = r1.x + r1.width > x2 && r1.x < x2 + w2; const yOverlap = r1.y + r1.height > y2 && r1.y < y2 + h2; return xOverlap && yOverlap; } function rectContainsRect(r1, r2x, r2y, r2w, r2h) { return r2x + r2w < r1.x + r1.width && r2x > r1.x && r2y > r1.y && r2y + r2h < r1.y + r1.height; } function isPointLabelDatum(x) { return x != null && typeof x.point === "object" && typeof x.label === "object"; } function placeLabels(data, bounds, padding = 5) { const result = /* @__PURE__ */ new Map(); const previousResults = []; const sortedDataClone = new Map( [...data.entries()].map(([k, d]) => [k, d.toSorted((a, b) => b.point.size - a.point.size)]) ); const dataValues = [...sortedDataClone.values()].flat(); for (const [seriesId, datums] of sortedDataClone.entries()) { const labels = []; if (!datums[0]?.label) continue; for (let index = 0, ln = datums.length; index < ln; index++) { const d = datums[index]; const { point, label, anchor } = d; const { text: text3, width: width2, height: height2 } = label; const r = point.size * 0.5; let dx2 = 0; let dy2 = 0; if (r > 0 && d.placement != null) { const placement = labelPlacements[d.placement]; dx2 = (width2 * 0.5 + r + padding) * placement.x; dy2 = (height2 * 0.5 + r + padding) * placement.y; } const x = point.x - width2 * 0.5 + dx2 - ((anchor?.x ?? 0.5) - 0.5) * point.size; const y = point.y - height2 * 0.5 + dy2 - ((anchor?.y ?? 0.5) - 0.5) * point.size; const withinBounds = !bounds || rectContainsRect(bounds, x, y, width2, height2); if (!withinBounds) continue; const overlapPoints = dataValues.some( (dataDatum) => circleRectOverlap(dataDatum.point, dataDatum.anchor, x, y, width2, height2) ); if (overlapPoints) continue; const overlapLabels = previousResults.some((pr) => rectRectOverlap(pr, x, y, width2, height2)); if (overlapLabels) continue; const resultDatum = { index, text: text3, x, y, width: width2, height: height2, datum: d }; labels.push(resultDatum); previousResults.push(resultDatum); } result.set(seriesId, labels); } return result; } function axisLabelsOverlap(data, padding = 0) { const result = []; for (let index = 0; index < data.length; index++) { const datum = data[index]; const { point: { x, y }, label: { text: text3 } } = datum; let { width: width2, height: height2 } = datum.label; width2 += padding; height2 += padding; if (result.some((l) => rectRectOverlap(l, x, y, width2, height2))) { return true; } result.push({ index, text: text3, x, y, width: width2, height: height2, datum }); } return false; } var labelPlacements; var init_labelPlacement = __esm({ "packages/ag-charts-community/src/scene/util/labelPlacement.ts"() { "use strict"; labelPlacements = { top: { x: 0, y: -1 }, bottom: { x: 0, y: 1 }, left: { x: -1, y: 0 }, right: { x: 1, y: 0 }, "top-left": { x: -1, y: -1 }, "top-right": { x: 1, y: -1 }, "bottom-left": { x: -1, y: 1 }, "bottom-right": { x: 1, y: 1 } }; } }); // packages/ag-charts-community/src/util/secondaryAxisTicks.ts function calculateNiceSecondaryAxis(domain, primaryTickCount, reverse) { let [start2, stop] = findMinMax(domain); start2 = calculateNiceStart(Math.floor(start2), stop, primaryTickCount); const step = getTickStep(start2, stop, primaryTickCount); const segments = primaryTickCount - 1; stop = start2 + segments * step; const d = reverse ? [stop, start2] : [start2, stop]; const ticks = getTicks(start2, step, primaryTickCount); return { domain: d, ticks }; } function calculateNiceStart(a, b, count) { const rawStep = Math.abs(b - a) / (count - 1); const order = Math.floor(Math.log10(rawStep)); const magnitude = Math.pow(10, order); return Math.floor(a / magnitude) * magnitude; } function getTicks(start2, step, count) { const stepPower = Math.floor(Math.log10(step)); const fractionDigits = step > 0 && step < 1 ? Math.abs(stepPower) : 0; const f = Math.pow(10, fractionDigits); const ticks = []; for (let i = 0; i < count; i++) { const tick = start2 + step * i; ticks[i] = Math.round(tick * f) / f; } return ticks; } function getTickStep(start2, stop, count) { const segments = count - 1; const rawStep = (stop - start2) / segments; return calculateNextNiceStep(rawStep); } function calculateNextNiceStep(rawStep) { const order = Math.floor(Math.log10(rawStep)); const magnitude = Math.pow(10, order); const step = rawStep / magnitude * 10; if (step > 0 && step <= 1) { return magnitude / 10; } if (step > 1 && step <= 2) { return 2 * magnitude / 10; } if (step > 1 && step <= 5) { return 5 * magnitude / 10; } if (step > 5 && step <= 10) { return 10 * magnitude / 10; } if (step > 10 && step <= 20) { return 20 * magnitude / 10; } if (step > 20 && step <= 40) { return 40 * magnitude / 10; } if (step > 40 && step <= 50) { return 50 * magnitude / 10; } if (step > 50 && step <= 100) { return 100 * magnitude / 10; } return step; } var init_secondaryAxisTicks = __esm({ "packages/ag-charts-community/src/util/secondaryAxisTicks.ts"() { "use strict"; init_number(); } }); // packages/ag-charts-community/src/util/tempUtils.ts function createIdsGenerator() { const idsCounter = /* @__PURE__ */ new Map(); return (name) => { const counter = idsCounter.get(name); if (counter) { idsCounter.set(name, counter + 1); return `${name}_${counter}`; } idsCounter.set(name, 1); return name; }; } var init_tempUtils = __esm({ "packages/ag-charts-community/src/util/tempUtils.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/axis/axisTickGenerator.ts var AxisTickGenerator; var init_axisTickGenerator = __esm({ "packages/ag-charts-community/src/chart/axis/axisTickGenerator.ts"() { "use strict"; init_main(); init_continuousScale(); init_ordinalTimeScale(); init_matrix(); init_labelPlacement(); init_angle(); init_number(); init_secondaryAxisTicks(); init_tempUtils(); init_textMeasurer(); init_ticks(); init_label(); AxisTickGenerator = class { constructor(axis) { this.axis = axis; } estimateTickCount(visibleRange, minSpacing, maxSpacing) { return estimateTickCount( findRangeExtent(this.axis.range), findRangeExtent(visibleRange), minSpacing, maxSpacing, ContinuousScale.defaultTickCount, this.axis.defaultTickMinSpacing ); } filterTicks(ticks, tickCount) { const { minSpacing, maxSpacing } = this.axis.interval; const tickSpacing = !isNaN(minSpacing) || !isNaN(maxSpacing); const keepEvery = tickSpacing ? Math.ceil(ticks.length / tickCount) : 2; const offset4 = ticks.length % keepEvery ? -1 : 0; return ticks.filter((_, i) => (i + offset4) % keepEvery === 0); } generateTicks({ domain, primaryTickCount, visibleRange, niceMode, parallelFlipRotation, regularFlipRotation, labelX, sideFlag }) { const { scale: scale2, label, interval: { minSpacing, maxSpacing } } = this.axis; const { parallel, rotation, fontFamily, fontSize, fontStyle, fontWeight } = label; const secondaryAxis = primaryTickCount !== void 0; const { defaultRotation, configuredRotation, parallelFlipFlag, regularFlipFlag } = calculateLabelRotation({ rotation, parallel, regularFlipRotation, parallelFlipRotation }); const initialRotation = configuredRotation + defaultRotation; const labelMatrix = new Matrix(); const { maxTickCount } = this.estimateTickCount(visibleRange, minSpacing, maxSpacing); const continuous = ContinuousScale.is(scale2) || OrdinalTimeScale.is(scale2); const maxIterations = !continuous || isNaN(maxTickCount) ? 10 : maxTickCount; let textAlign = getTextAlign(parallel, configuredRotation, 0, sideFlag, regularFlipFlag); const textBaseline = getTextBaseline(parallel, configuredRotation, sideFlag, parallelFlipFlag); const font3 = TextUtils.toFontString({ fontFamily, fontSize, fontStyle, fontWeight }); const textMeasurer = CachedTextMeasurerPool.getMeasurer({ font: font3 }); const textProps = { fontFamily, fontSize, fontStyle, fontWeight, textBaseline, textAlign }; const checkLabelOverlap = label.enabled && label.avoidCollisions; const getLabelOverlap = ({ ticks }, iterationRotation) => { if (!checkLabelOverlap) return false; const rotated = configuredRotation !== 0 || iterationRotation !== 0; const labelRotation = initialRotation + iterationRotation; const labelSpacing = getLabelSpacing(label.minSpacing, rotated); Matrix.updateTransformMatrix(labelMatrix, 1, 1, labelRotation, 0, 0); const labelData = createLabelData(ticks, labelX, labelMatrix, textMeasurer); return axisLabelsOverlap(labelData, labelSpacing); }; let tickData = { tickDomain: [], ticks: [], rawTicks: [], fractionDigits: 0, niceDomain: void 0 }; let index = 0; let autoRotation = 0; let labelOverlap = true; let terminate = false; while (!terminate && labelOverlap && index <= maxIterations) { autoRotation = 0; for (const strategy of this.getTickStrategies({ domain, niceMode, secondaryAxis, index })) { ({ tickData, index, autoRotation, terminate } = strategy({ index, tickData, textProps, terminate, primaryTickCount, visibleRange, // Lazily generate as only one strategy actually uses this, and it's expensive to compute get labelOverlap() { return getLabelOverlap(tickData, autoRotation); } })); } labelOverlap = getLabelOverlap(tickData, autoRotation); } textAlign = getTextAlign(parallel, configuredRotation, autoRotation, sideFlag, regularFlipFlag); const combinedRotation = defaultRotation + configuredRotation + autoRotation; if (!secondaryAxis && tickData.rawTicks.length > 0) { primaryTickCount = tickData.rawTicks.length; } return { tickData, primaryTickCount, combinedRotation, textBaseline, textAlign }; } getTickStrategies({ domain, niceMode, index: iteration, secondaryAxis }) { const { scale: scale2, label, interval } = this.axis; const { minSpacing } = interval; const continuous = ContinuousScale.is(scale2) || OrdinalTimeScale.is(scale2); const avoidLabelCollisions = label.enabled && label.avoidCollisions; const filterTicks = !continuous && iteration !== 0 && avoidLabelCollisions; const autoRotate = label.autoRotate === true && label.rotation === void 0; const strategies = []; let tickGenerationType; if (interval.values) { tickGenerationType = 3 /* VALUES */; } else if (secondaryAxis) { tickGenerationType = 1 /* CREATE_SECONDARY */; } else if (filterTicks) { tickGenerationType = 2 /* FILTER */; } else { tickGenerationType = 0 /* CREATE */; } const tickGenerationStrategy = ({ index, tickData, primaryTickCount, visibleRange, terminate }) => this.createTickData( domain, niceMode, visibleRange, primaryTickCount, tickGenerationType, index, tickData, terminate ); strategies.push(tickGenerationStrategy); if (!continuous && !isNaN(minSpacing)) { const tickFilterStrategy = ({ index, tickData, primaryTickCount, visibleRange, terminate }) => this.createTickData( domain, niceMode, visibleRange, primaryTickCount, 2 /* FILTER */, index, tickData, terminate ); strategies.push(tickFilterStrategy); } if (avoidLabelCollisions && autoRotate) { const autoRotateStrategy = ({ index, tickData, labelOverlap, terminate }) => ({ index, tickData, autoRotation: labelOverlap ? normalizeAngle360(toRadians(label.autoRotateAngle ?? 0)) : 0, terminate }); strategies.push(autoRotateStrategy); } return strategies; } createTickData(domain, niceMode, visibleRange, primaryTickCount, tickGenerationType, index, tickData, terminate) { const { scale: scale2, interval } = this.axis; const { step, values, minSpacing, maxSpacing } = interval; const { maxTickCount, minTickCount, tickCount } = this.estimateTickCount(visibleRange, minSpacing, maxSpacing); const continuous = ContinuousScale.is(scale2) || OrdinalTimeScale.is(scale2); const maxIterations = !continuous || isNaN(maxTickCount) ? 10 : maxTickCount; const countTicks = (i) => continuous ? Math.max(tickCount - i, minTickCount) : maxTickCount; const regenerateTicks = step == null && values == null && countTicks(index) > minTickCount && (continuous || tickGenerationType === 2 /* FILTER */); while (index <= maxIterations) { const previousTicks = tickData.rawTicks; tickData = this.getTicks({ domain, niceMode, visibleRange, tickGenerationType, previousTicks, minTickCount, maxTickCount, primaryTickCount, tickCount: countTicks(index) }); index++; if (!regenerateTicks || !arraysEqual(tickData.rawTicks, previousTicks)) break; } terminate || (terminate = step != null || values != null); return { tickData, index, autoRotation: 0, terminate }; } getTicks({ domain, niceMode, visibleRange, tickGenerationType, previousTicks, tickCount, minTickCount, maxTickCount, primaryTickCount }) { const { axis } = this; const { label, range: range4, scale: scale2, interval } = axis; const idGenerator = createIdsGenerator(); const domainParams = { nice: niceMode === 0 /* TickAndDomain */, interval: interval.step, tickCount, minTickCount, maxTickCount }; const tickParams = { ...domainParams, nice: niceMode === 0 /* TickAndDomain */ || niceMode === 1 /* TicksOnly */ }; let niceDomain = niceMode === 0 /* TickAndDomain */ ? scale2.niceDomain(domainParams, domain) : domain; let tickDomain = niceDomain; let rawTicks; switch (tickGenerationType) { case 3 /* VALUES */: tickDomain = interval.values; rawTicks = interval.values; if (ContinuousScale.is(scale2)) { const [d0, d1] = findMinMax(niceDomain.map(Number)); rawTicks = rawTicks.filter((value) => Number(value) >= d0 && Number(value) <= d1).sort((a, b) => Number(a) - Number(b)); } break; case 1 /* CREATE_SECONDARY */: if (ContinuousScale.is(scale2)) { const secondaryAxisTicks = calculateNiceSecondaryAxis( domain.map(Number), primaryTickCount ?? 0, axis.reverse ); rawTicks = secondaryAxisTicks.ticks; niceDomain = secondaryAxisTicks.domain.map((d) => scale2.toDomain(d)); } else { rawTicks = scale2.ticks(tickParams, niceDomain, visibleRange) ?? []; } break; case 2 /* FILTER */: rawTicks = this.filterTicks(previousTicks, tickCount); break; default: rawTicks = scale2.ticks(tickParams, niceDomain, visibleRange) ?? []; } const fractionDigits = rawTicks.reduce( (max, tick) => Math.max(max, typeof tick === "number" ? countFractionDigits(tick) : 0), 0 ); const formatParams = { domain: tickDomain, ticks: rawTicks, fractionDigits, specifier: label.format }; const labelFormatter = scale2.tickFormatter(formatParams); const scaleDomain = scale2.domain; scale2.domain = niceDomain; const halfBandwidth = (scale2.bandwidth ?? 0) / 2; const ticks = []; for (let i = 0; i < rawTicks.length; i++) { const tick = rawTicks[i]; const translationY = scale2.convert(tick) + halfBandwidth; if (range4.length > 0 && !axis.inRange(translationY, 1e-3)) continue; const tickLabel = label.enabled ? axis.formatTick(tick, i, fractionDigits, labelFormatter) : ""; ticks.push({ tick, tickId: idGenerator(tickLabel), tickLabel, translationY: Math.floor(translationY) }); } scale2.domain = scaleDomain; return { tickDomain, rawTicks, fractionDigits, ticks, niceDomain }; } }; } }); // packages/ag-charts-community/src/chart/axis/cartesianAxisLabel.ts var CartesianAxisLabel; var init_cartesianAxisLabel = __esm({ "packages/ag-charts-community/src/chart/axis/cartesianAxisLabel.ts"() { "use strict"; init_validation2(); init_axisLabel(); CartesianAxisLabel = class extends AxisLabel { constructor() { super(...arguments); this.autoRotateAngle = 335; } }; __decorateClass([ Validate(BOOLEAN, { optional: true }) ], CartesianAxisLabel.prototype, "autoRotate", 2); __decorateClass([ Validate(NUMBER) ], CartesianAxisLabel.prototype, "autoRotateAngle", 2); } }); // packages/ag-charts-community/src/chart/axis/cartesianAxis.ts var _CartesianAxis, CartesianAxis; var init_cartesianAxis = __esm({ "packages/ag-charts-community/src/chart/axis/cartesianAxis.ts"() { "use strict"; init_main(); init_fromToMotion(); init_resetMotion(); init_bbox(); init_group(); init_text(); init_stateMachine(); init_validation2(); init_caption(); init_axis(); init_axisTickGenerator(); init_axisUtil(); init_cartesianAxisLabel(); _CartesianAxis = class _CartesianAxis extends Axis { constructor(moduleCtx, scale2) { super(moduleCtx, scale2); this.lineNode = this.axisGroup.appendChild( new TranslatableLine({ name: `${this.id}-Axis-line`, zIndex: 1 /* AxisLine */ }) ); this.tempText = new TransformableText(); this.tempCaption = new Caption(); this.tickGenerator = new AxisTickGenerator(this); this.generatedTicks = void 0; this.animationManager = moduleCtx.animationManager; this.animationState = new StateMachine("empty", { empty: { update: { target: "ready", action: () => this.resetSelectionNodes() }, reset: "empty" }, ready: { update: (data) => this.animateReadyUpdate(data), resize: () => this.resetSelectionNodes(), reset: "empty" } }); this.axisGroup.appendChild(this.title.caption.node); let previousSize = void 0; this.destroyFns.push( moduleCtx.layoutManager.addListener("layout:complete", (e) => { const size = [e.chart.width, e.chart.height]; if (previousSize != null && !arraysEqual(size, previousSize)) { this.animationState.transition("resize"); } previousSize = size; }), this.title.caption.registerInteraction(this.moduleCtx, "afterend") ); } static is(value) { return value instanceof _CartesianAxis; } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } } get direction() { return this.position === "top" || this.position === "bottom" ? "x" /* X */ : "y" /* Y */; } createAxisContext() { return { ...super.createAxisContext(), position: this.position }; } createLabel() { return new CartesianAxisLabel(); } updateDirection() { switch (this.position) { case "top": this.rotation = -90; this.label.mirrored = true; this.label.parallel = true; break; case "right": this.rotation = 0; this.label.mirrored = true; this.label.parallel = false; break; case "bottom": this.rotation = -90; this.label.mirrored = false; this.label.parallel = true; break; case "left": this.rotation = 0; this.label.mirrored = false; this.label.parallel = false; break; } if (this.axisContext) { this.axisContext.position = this.position; this.axisContext.direction = this.direction; } } calculateLayout(primaryTickCount) { this.updateDirection(); return super.calculateLayout(primaryTickCount); } calculateTickLayout(domain, niceMode, visibleRange, initialPrimaryTickCount) { const sideFlag = this.label.getSideFlag(); const { parallelFlipRotation, regularFlipRotation } = this.calculateRotations(); const labelX = sideFlag * (this.getTickSize() + this.label.spacing + this.seriesAreaPadding); const tickGenerationResult = this.tickGenerator.generateTicks({ domain, niceMode, visibleRange, primaryTickCount: initialPrimaryTickCount, parallelFlipRotation, regularFlipRotation, labelX, sideFlag }); const { tickData, primaryTickCount = initialPrimaryTickCount } = tickGenerationResult; const { ticks, tickDomain, rawTicks, fractionDigits, niceDomain = domain } = tickData; const labels = ticks.map((d) => this.getTickLabelProps(d, tickGenerationResult)); const bbox = this.tickBBox(ticks, labels); this.generatedTicks = { ticks, labels }; return { ticks: rawTicks, tickDomain, niceDomain, primaryTickCount, fractionDigits, bbox }; } update() { this.updateDirection(); const previousTicksIds = Array.from(this.tickLabelGroupSelection.nodes(), (node) => node.datum.tickId); super.update(); if (!this.animatable) { this.moduleCtx.animationManager.skipCurrentBatch(); } if (this.generatedTicks) { const { ticks } = this.generatedTicks; if (this.animationManager.isSkipped()) { this.resetSelectionNodes(); } else { const tickIds = ticks.map((datum) => datum.tickId); const diff8 = diffArrays(previousTicksIds, tickIds); this.animationState.transition("update", diff8); } } const { enabled, stroke: stroke3, width: width2 } = this.line; this.lineNode.setProperties({ stroke: stroke3, strokeWidth: enabled ? width2 : 0 }); this.updateTitle(!this.generatedTicks?.ticks.length); } updatePosition() { super.updatePosition(); this.axisGroup.datum = this.getAxisTransform(); } tickBBox(ticks, labels) { const sideFlag = this.label.getSideFlag(); const boxes = []; const { x, y1, y2 } = this.getAxisLineCoordinates(); const lineBox = new BBox( x + Math.min(sideFlag * this.seriesAreaPadding, 0), y1, this.seriesAreaPadding, y2 - y1 ); boxes.push(lineBox); if (this.tick.enabled) { for (const datum of ticks) { const { x1, x2, y } = this.getTickLineCoordinates(datum); const tickLineBox = new BBox(x1, y, x2 - x1, 0); boxes.push(tickLineBox); } } const { tempText: tempText2 } = this; if (this.label.enabled) { for (const datum of labels) { if (!datum.visible) continue; tempText2.setProperties({ ...datum, translationY: Math.round(datum.translationY) }); const box = tempText2.getBBox(); if (box) { boxes.push(box); } } } if (this.title?.enabled) { const spacing = BBox.merge(boxes).width; this.setTitleProps(this.tempCaption, { spacing }); const titleBox = this.tempCaption.node.getBBox(); if (titleBox) { boxes.push(titleBox); } } const bbox = BBox.merge(boxes); return this.getTransformBox(bbox); } getTickLabelProps(datum, tickGenerationResult) { const { combinedRotation, textBaseline, textAlign } = tickGenerationResult; const { range: range4 } = this.scale; const text3 = datum.tickLabel; const sideFlag = this.label.getSideFlag(); const labelX = sideFlag * (this.getTickSize() + this.label.spacing + this.seriesAreaPadding); const visible = text3 !== "" && text3 != null; return { ...this.getLabelStyles({ value: datum.tickLabel }), tickId: datum.tickId, rotation: combinedRotation, rotationCenterX: labelX, translationY: datum.translationY, text: text3, textAlign, textBaseline, visible, x: labelX, y: 0, range: range4 }; } getTickLineCoordinates(datum) { const sideFlag = this.label.getSideFlag(); const x = sideFlag * this.getTickSize(); const x1 = Math.min(0, x); const x2 = x1 + Math.abs(x); const y = datum.translationY; return { x1, x2, y }; } updateSelections() { if (!this.generatedTicks) return; const lineData = this.getAxisLineCoordinates(); const { ticks, labels } = this.generatedTicks; const getDatumId = (datum) => datum.tickId; this.lineNode.datum = lineData; this.gridLineGroupSelection.update(this.gridLength ? ticks : [], void 0, getDatumId); this.tickLineGroupSelection.update(ticks, void 0, getDatumId); this.tickLabelGroupSelection.update(labels, void 0, getDatumId); } updateTitle(noVisibleTicks, spacing) { const { title, tickLineGroup, tickLabelGroup, lineNode } = this; if (title.enabled && !noVisibleTicks && spacing == null) { const tickBBox = Group.computeChildrenBBox([tickLineGroup, tickLabelGroup, lineNode]); spacing = tickBBox.width + (tickLabelGroup.visible ? 0 : this.seriesAreaPadding); } spacing ?? (spacing = 0); this.setTitleProps(title.caption, { spacing }); } updateLabels() { if (!this.label.enabled) return; this.tickLabelGroupSelection.each((node, datum) => { node.fill = datum.fill; node.fontFamily = datum.fontFamily; node.fontSize = datum.fontSize; node.fontStyle = datum.fontStyle; node.fontWeight = datum.fontWeight; node.text = datum.text; node.textBaseline = datum.textBaseline; node.textAlign = datum.textAlign ?? "center"; }); } animateReadyUpdate(diff8) { const { animationManager } = this.moduleCtx; const selectionCtx = prepareAxisAnimationContext(this); const fns = prepareAxisAnimationFunctions(selectionCtx); fromToMotion(this.id, "axis-group", animationManager, [this.axisGroup], fns.group); fromToMotion(this.id, "line", animationManager, [this.lineNode], fns.line); fromToMotion( this.id, "line-paths", animationManager, [this.gridLineGroupSelection, this.tickLineGroupSelection], fns.tick, (_, d) => d.tickId, diff8 ); fromToMotion( this.id, "tick-labels", animationManager, [this.tickLabelGroupSelection], fns.label, (_, d) => d.tickId, diff8 ); } resetSelectionNodes() { const selectionCtx = prepareAxisAnimationContext(this); resetMotion([this.axisGroup], resetAxisGroupFn()); resetMotion([this.gridLineGroupSelection, this.tickLineGroupSelection], resetAxisSelectionFn(selectionCtx)); resetMotion([this.tickLabelGroupSelection], resetAxisLabelSelectionFn()); resetMotion([this.lineNode], resetAxisLineSelectionFn()); } }; __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], _CartesianAxis.prototype, "thickness", 2); __decorateClass([ Validate(POSITION) ], _CartesianAxis.prototype, "position", 2); CartesianAxis = _CartesianAxis; } }); // packages/ag-charts-community/src/chart/axis/categoryAxis.ts var _CategoryAxis, CategoryAxis; var init_categoryAxis = __esm({ "packages/ag-charts-community/src/chart/axis/categoryAxis.ts"() { "use strict"; init_main(); init_categoryScale(); init_validation2(); init_cartesianAxis(); _CategoryAxis = class _CategoryAxis extends CartesianAxis { constructor(moduleCtx, scale2 = new CategoryScale()) { super(moduleCtx, scale2); this.groupPaddingInner = 0.1; this.includeInvisibleDomains = true; } static is(value) { return value instanceof _CategoryAxis; } normaliseDataDomain(domain) { return { domain, clipped: false }; } updateScale() { super.updateScale(); let { paddingInner, paddingOuter } = this; if (!isFiniteNumber(paddingInner) || !isFiniteNumber(paddingOuter)) { const padding = this.reduceBandScalePadding(); paddingInner ?? (paddingInner = padding.inner); paddingOuter ?? (paddingOuter = padding.outer); } this.scale.paddingInner = paddingInner ?? 0; this.scale.paddingOuter = paddingOuter ?? 0; } reduceBandScalePadding() { return this.boundSeries.reduce( (result, series) => { const padding = series.getBandScalePadding?.(); if (padding) { if (result.inner > padding.inner) { result.inner = padding.inner; } if (result.outer < padding.outer) { result.outer = padding.outer; } } return result; }, { inner: Infinity, outer: -Infinity } ); } }; _CategoryAxis.className = "CategoryAxis"; _CategoryAxis.type = "category"; __decorateClass([ Validate(RATIO) ], _CategoryAxis.prototype, "groupPaddingInner", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], _CategoryAxis.prototype, "paddingInner", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], _CategoryAxis.prototype, "paddingOuter", 2); CategoryAxis = _CategoryAxis; } }); // packages/ag-charts-community/src/module/module.ts var BaseModuleInstance, ModuleRegistry2, moduleRegistry; var init_module = __esm({ "packages/ag-charts-community/src/module/module.ts"() { "use strict"; BaseModuleInstance = class { constructor() { this.destroyFns = []; } destroy() { for (const destroyFn of this.destroyFns) { destroyFn(); } } }; ModuleRegistry2 = class { constructor() { this.modules = []; this.dependencies = /* @__PURE__ */ new Map(); this.modulesByOptionKey = /* @__PURE__ */ new Map(); } register(...modules) { for (const module2 of modules) { this.registerDependencies(module2); const otherModule = this.modules.find( (other) => module2.type === other.type && ("optionsKey" in module2 && "optionsKey" in other ? module2.optionsKey === other.optionsKey : true) && module2.identifier === other.identifier ); if (otherModule) { if (module2.packageType === "enterprise" && otherModule.packageType === "community") { const index = this.modules.indexOf(otherModule); this.modules.splice(index, 1, module2); if ("optionsKey" in module2) { this.modulesByOptionKey.set(module2.optionsKey, module2); } } } else { this.modules.push(module2); if ("optionsKey" in module2) { this.modulesByOptionKey.set(module2.optionsKey, module2); } } } } hasEnterpriseModules() { return this.modules.some((m) => m.packageType === "enterprise"); } *byType(...types) { const yielded = /* @__PURE__ */ new Set(); const modulesByType = this.modules.filter((module2) => types.includes(module2.type)); const calculateDependencies = (module2) => { const deps = this.dependencies.get(module2); return deps?.flatMap(calculateDependencies).concat(deps) ?? []; }; const unresolvable = []; for (const module2 of modulesByType) { const uniqueKey = "optionsKey" in module2 ? module2.optionsKey : module2.contextKey; if (yielded.has(uniqueKey)) continue; for (const dependency of calculateDependencies(uniqueKey)) { if (yielded.has(dependency)) continue; const dependencyModule = this.modulesByOptionKey.get(dependency); if (!dependencyModule) { unresolvable.push(dependency); continue; } if (!types.includes(dependencyModule.type)) continue; yield dependencyModule; yielded.add(dependency); } yield module2; yielded.add(uniqueKey); } if (unresolvable.length > 0) { throw new Error(`Could not resolve module dependencies: ${unresolvable}`); } } registerDependencies(module2) { if (module2.dependencies == null || module2.dependencies.length === 0) return; const uniqueKey = "optionsKey" in module2 ? module2.optionsKey : module2.contextKey; this.dependencies.set(uniqueKey, module2.dependencies); } }; moduleRegistry = new ModuleRegistry2(); } }); // packages/ag-charts-community/src/util/async.ts function pause() { return new Promise((resolve) => { setTimeout(resolve, 0); }); } var AsyncAwaitQueue; var init_async = __esm({ "packages/ag-charts-community/src/util/async.ts"() { "use strict"; AsyncAwaitQueue = class { constructor() { this.queue = []; } await(timeout = 50) { return new Promise((resolve) => { const successFn = () => { clearTimeout(timeoutHandle); resolve(true); }; const timeoutFn = () => { const queueIndex = this.queue.indexOf(successFn); if (queueIndex < 0) return; this.queue.splice(queueIndex, 1); resolve(false); }; const timeoutHandle = setTimeout(timeoutFn, timeout); this.queue.push(successFn); }); } notify() { this.queue.splice(0).forEach((cb) => cb()); } }; } }); // packages/ag-charts-community/src/util/dom.ts function setElementBBox(element2, bbox) { if (!element2) return; bbox = BBoxValues.normalize(bbox); if (bbox.width == null) { element2.style.removeProperty("width"); } else { element2.style.width = `${bbox.width}px`; } if (bbox.height == null) { element2.style.removeProperty("height"); } else { element2.style.height = `${bbox.height}px`; } if (bbox.x == null) { element2.style.removeProperty("left"); } else { element2.style.left = `${bbox.x}px`; } if (bbox.y == null) { element2.style.removeProperty("top"); } else { element2.style.top = `${bbox.y}px`; } } function getElementBBox(element2) { const width2 = parseFloat(element2.style.width) || element2.offsetWidth; const height2 = parseFloat(element2.style.height) || element2.offsetHeight; const x = parseFloat(element2.style.left) || element2.offsetLeft; const y = parseFloat(element2.style.top) || element2.offsetTop; return { x, y, width: width2, height: height2 }; } function focusCursorAtEnd(element2) { element2.focus({ preventScroll: true }); if (element2.lastChild?.textContent == null) return; const range4 = getDocument().createRange(); range4.setStart(element2.lastChild, element2.lastChild.textContent.length); range4.setEnd(element2.lastChild, element2.lastChild.textContent.length); const selection = getWindow().getSelection(); selection?.removeAllRanges(); selection?.addRange(range4); } function createElementId(label) { return `${label ?? "ag-charts-element"}-${_id++}`; } 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}`; } var _id; var init_dom = __esm({ "packages/ag-charts-community/src/util/dom.ts"() { "use strict"; init_core(); init_bboxinterface(); _id = 0; } }); // packages/ag-charts-community/src/util/json.ts function jsonDiff(source, target, skip) { if (isArray(target)) { if (!isArray(source) || source.length !== target.length || target.some((v, i) => jsonDiff(source[i], v) != null)) { return target; } } else if (isPlainObject(target)) { if (!isPlainObject(source)) { return target; } const result = {}; const allKeys = /* @__PURE__ */ new Set([ ...Object.keys(source), ...Object.keys(target) ]); for (const key of allKeys) { if (source[key] === target[key] || skip?.includes(key)) { continue; } if (typeof source[key] === typeof target[key]) { const diff8 = jsonDiff(source[key], target[key]); if (diff8 !== null) { result[key] = diff8; } } else { result[key] = target[key]; } } return Object.keys(result).length ? result : null; } else if (source !== target) { return target; } return null; } function jsonPropertyCompare(source, target) { for (const key of Object.keys(source)) { if (source[key] === target?.[key]) continue; return false; } return true; } function deepClone(source, shallow) { if (isArray(source)) { return source.map((item) => deepClone(item, shallow)); } if (isPlainObject(source)) { return clonePlainObject(source, shallow); } if (source instanceof Map) { return new Map(deepClone(Array.from(source))); } return shallowClone(source); } function clonePlainObject(source, shallow) { const target = {}; for (const key of Object.keys(source)) { target[key] = shallow?.has(key) ? shallowClone(source[key]) : deepClone(source[key], shallow); } return target; } function shallowClone(source) { if (isArray(source)) { return source.slice(0); } if (isPlainObject(source)) { return { ...source }; } if (isDate(source)) { return new Date(source); } if (isRegExp(source)) { return new RegExp(source.source, source.flags); } return source; } function jsonWalk(json, visit, skip, parallelJson, ctx, acc) { if (isArray(json)) { acc = visit(json, parallelJson, ctx, acc); let index = 0; for (const node of json) { acc = jsonWalk(node, visit, skip, parallelJson?.[index], ctx, acc); index++; } } else if (isPlainObject(json)) { acc = visit(json, parallelJson, ctx, acc); for (const key of Object.keys(json)) { if (skip?.has(key)) { continue; } const value = json[key]; acc = jsonWalk(value, visit, skip, parallelJson?.[key], ctx, acc); } } return acc; } function jsonApply(target, source, params = {}) { const { path, matcherPath = path?.replace(/(\[[0-9+]+])/i, "[]"), skip = [] } = params; if (target == null) { throw new Error(`AG Charts - target is uninitialised: ${path ?? ""}`); } if (source == null) { return target; } if (isProperties(target)) { return target.set(source); } const targetAny = target; const targetType = classify(target); for (const property of Object.keys(source)) { if (SKIP_JS_BUILTINS.has(property)) continue; const propertyMatcherPath = `${matcherPath ? matcherPath + "." : ""}${property}`; if (skip.includes(propertyMatcherPath)) continue; const newValue = source[property]; const propertyPath = `${path ? path + "." : ""}${property}`; const targetClass = targetAny.constructor; const currentValue = targetAny[property]; try { const currentValueType = classify(currentValue); const newValueType = classify(newValue); if (targetType === CLASS_INSTANCE_TYPE && !(property in target)) { if (newValue === void 0) continue; logger_exports.warn(`unable to set [${propertyPath}] in ${targetClass?.name} - property is unknown`); continue; } if (currentValueType != null && newValueType != null && newValueType !== currentValueType && (currentValueType !== CLASS_INSTANCE_TYPE || newValueType !== "object")) { logger_exports.warn( `unable to set [${propertyPath}] in ${targetClass?.name} - can't apply type of [${newValueType}], allowed types are: [${currentValueType}]` ); continue; } if (isProperties(currentValue)) { targetAny[property].set(newValue); } else if (newValueType === "object") { if (currentValue == null) { logger_exports.warn(`unable to set [${propertyPath}] in ${targetClass?.name} - property is unknown`); continue; } jsonApply(currentValue, newValue, { ...params, path: propertyPath, matcherPath: propertyMatcherPath }); } else { targetAny[property] = newValue; } } catch (error3) { logger_exports.warn(`unable to set [${propertyPath}] in [${targetClass?.name}]; nested error is: ${error3.message}`); } } return target; } function classify(value) { if (value == null) { return null; } if (isHtmlElement(value) || isDate(value)) { return "primitive"; } if (isArray(value)) { return "array"; } if (isObject(value)) { return isPlainObject(value) ? "object" : CLASS_INSTANCE_TYPE; } if (isFunction(value)) { return "function"; } return "primitive"; } function jsonResolveOperations(source, params, skip) { return jsonResolveInner(source, params, source, skip); } function jsonResolveInner(json, params, source, skip, path = [], modifiedPaths = {}) { if (isArray(json)) { jsonResolveVisitor(json, params, source, path, modifiedPaths); let index = 0; for (const node of json) { jsonResolveInner(node, params, source, skip, [...path, `${index}`], modifiedPaths); index++; } } else if (isPlainObject(json)) { jsonResolveVisitor(json, params, source, path, modifiedPaths); for (const key of Object.keys(json)) { if (skip?.has(key)) { continue; } const value = json[key]; jsonResolveInner(value, params, source, skip, [...path, key], modifiedPaths); } } return modifiedPaths; } function jsonResolveVisitor(node, params, source, path, modifiedPaths) { if (isArray(node)) { for (let i = 0; i < node.length; i++) { node[i] = jsonResolveVisitorValue(node[i], params, source, [...path, `${i}`], modifiedPaths); } } else { for (const [name, value] of Object.entries(node)) { node[name] = jsonResolveVisitorValue(value, params, source, [...path, name], modifiedPaths); } } } function jsonResolveVisitorValue(value, params, source, path, modifiedPaths) { const { operation, values } = getOperation(value); if (!operation) return value; modifiedPaths[path.join(".")] = value; return resolveOperation(operation, values, params, source, path, /* @__PURE__ */ new Set()); } function getOperation(value) { if (!isPlainObject(value)) return {}; const [operation, ...otherKeys] = Object.keys(value); if (otherKeys.length !== 0 || !operationKeys.has(operation)) return {}; return { operation, values: value[operation] }; } function resolveOperation(operation, value, params, source, path, referencedParams) { if (isArray(value)) { value = value.map((v) => { const { operation: nestedOperation, values } = getOperation(v); if (!nestedOperation) return v; return resolveOperation(nestedOperation, values, params, source, path, referencedParams); }); } return operations[operation](value, params, source, path, referencedParams); } function isRatio(value) { return isNumber(value) && value >= 0 && value <= 1; } var CLASS_INSTANCE_TYPE, Operation, operationKeys, operations; var init_json = __esm({ "packages/ag-charts-community/src/util/json.ts"() { "use strict"; init_main(); init_color(); init_object(); init_properties(); CLASS_INSTANCE_TYPE = "class-instance"; Operation = /* @__PURE__ */ ((Operation2) => { Operation2["Ref"] = "$ref"; Operation2["Path"] = "$path"; Operation2["If"] = "$if"; Operation2["Eq"] = "$eq"; Operation2["Not"] = "$not"; Operation2["Or"] = "$or"; Operation2["And"] = "$and"; Operation2["Mul"] = "$mul"; Operation2["Round"] = "$round"; Operation2["Rem"] = "$rem"; Operation2["Mix"] = "$mix"; Operation2["ForegroundBackgroundMix"] = "$foregroundBackgroundMix"; Operation2["ForegroundBackgroundAccentMix"] = "$foregroundBackgroundAccentMix"; return Operation2; })(Operation || {}); operationKeys = new Set(Object.values(Operation)); operations = { $ref: (key, params, source, path, referencedParams) => { if (isString(key) && key in params) { const { operation, values } = getOperation(params[key]); if (operation !== "$ref" /* Ref */) { return params[key]; } if (referencedParams?.has(values)) { logger_exports.warnOnce( `\`$ref\` json operation failed on [${String(key)}] at [${path.join(".")}], circular reference detected with [${[...referencedParams].join(", ")}].` ); return; } referencedParams?.add(values); return operations.$ref(values, params, source, path, referencedParams); } logger_exports.warnOnce( `\`$ref\` json operation failed on [${String(key)}] at [${path.join(".")}], expecting one of [${Object.keys(params).join(", ")}].` ); }, $path: (relativePath, _params, source, currentPath) => { if (!isString(relativePath)) { logger_exports.warnOnce( `\`$path\` json operation failed on [${String(relativePath)}] at [${currentPath.join(".")}], expecting a string.` ); return; } const relativePathParts = relativePath.split("/"); const resolvedPath = [...currentPath]; for (const part of relativePathParts) { if (part === "..") { resolvedPath.pop(); resolvedPath.pop(); } else if (part === ".") { resolvedPath.pop(); } else { resolvedPath.push(part); } } let resolvedValue = source; for (const part of resolvedPath) { if (!(part in resolvedValue)) { logger_exports.warnOnce( `\`$path\` json operation failed on [${String(relativePath)}] at [${currentPath.join(".")}], could not find path in object.` ); return; } resolvedValue = resolvedValue[part]; } return resolvedValue; }, $if: ([condition, thenValue, elseValue]) => condition ? thenValue : elseValue, $eq: ([a, b]) => a === b, $not: ([a, b]) => a !== b, $or: ([a, b]) => a || b, $and: ([a, b]) => a && b, $mul: ([a, b], _params, _source, path) => { if (typeof a === "number" && typeof b === "number") return a * b; logger_exports.warnOnce( `\`$mul\` json operation failed on [${String(a)}] and [${String(b)}] at [${path.join(".")}], expecting two numbers.` ); }, $round: ([a], _params, _source, path) => { if (typeof a === "number") return Math.round(a); logger_exports.warnOnce( `\`$round\` json operation failed on [${String(a)}] at [${path.join(".")}], expecting a number.` ); }, $rem: ([a], params) => { if (typeof a === "number") return Math.round(a * params.fontSize); }, $mix: ([a, b, c], _params, _source, path) => { if (typeof a === "string" && typeof b === "string" && isRatio(c)) { try { return Color.mix(Color.fromString(a), Color.fromString(b), c).toString(); } catch { } } logger_exports.warnOnce( `\`$mix\` json operation failed on [${String(a)}, ${String(b)}, ${String(c)}] at [${path.join(".")}], expecting two colors and a number between 0 and 1.` ); }, $foregroundBackgroundMix: ([a], params, _source, path) => { if (isRatio(a)) { return Color.mix( Color.fromString(params.foregroundColor), Color.fromString(params.backgroundColor), a ).toString(); } logger_exports.warnOnce( `\`$foregroundBackgroundMix\` json operation failed on [${String(a)}}}] at [${path.join(".")}], expecting a number between 0 and 1.` ); }, $foregroundBackgroundAccentMix: ([background, accent], params, _source, path) => { if (isRatio(background) && isRatio(accent)) { return Color.mix( Color.mix( Color.fromString(params.foregroundColor), Color.fromString(params.backgroundColor), background ), Color.fromString(params.accentColor), accent ).toString(); } logger_exports.warnOnce( `\`$foregroundBackgroundAccentMix\` json operation failed on [${String(background)}, ${String(accent)}}] at [${path.join(".")}], expecting two numbers between 0 and 1.` ); } }; } }); // packages/ag-charts-community/src/util/mutex.ts var Mutex; var init_mutex = __esm({ "packages/ag-charts-community/src/util/mutex.ts"() { "use strict"; init_main(); Mutex = class { constructor() { this.available = true; this.acquireQueue = []; } acquire(cb) { return new Promise((resolve) => { this.acquireQueue.push([cb, resolve]); if (this.available) { this.dispatchNext().catch((e) => logger_exports.errorOnce(e)); } }); } async acquireImmediately(cb) { if (!this.available) { return false; } await this.acquire(cb); return true; } async waitForClearAcquireQueue() { return this.acquire(() => Promise.resolve(void 0)); } async dispatchNext() { this.available = false; let [next, done] = this.acquireQueue.shift() ?? []; while (next) { try { await next(); done?.(); } catch (error3) { logger_exports.error("mutex callback error", error3); done?.(); } [next, done] = this.acquireQueue.shift() ?? []; } this.available = true; } }; } }); // packages/ag-charts-community/src/util/observable.ts var Observable; var init_observable = __esm({ "packages/ag-charts-community/src/util/observable.ts"() { "use strict"; Observable = class { constructor() { this.eventListeners = /* @__PURE__ */ new Map(); } addEventListener(eventType, listener) { if (typeof listener !== "function") { throw new Error("AG Charts - listener must be a Function"); } const eventTypeListeners = this.eventListeners.get(eventType); if (eventTypeListeners) { eventTypeListeners.add(listener); } else { this.eventListeners.set(eventType, /* @__PURE__ */ new Set([listener])); } } removeEventListener(type, listener) { this.eventListeners.get(type)?.delete(listener); if (this.eventListeners.size === 0) { this.eventListeners.delete(type); } } hasEventListener(type) { return this.eventListeners.has(type); } clearEventListeners() { this.eventListeners.clear(); } fireEvent(event) { this.eventListeners.get(event.type)?.forEach((listener) => listener(event)); } }; } }); // packages/ag-charts-community/src/util/padding.ts var Padding; var init_padding = __esm({ "packages/ag-charts-community/src/util/padding.ts"() { "use strict"; init_properties(); init_validation2(); Padding = class extends BaseProperties { constructor(top = 0, right = top, bottom = top, left = right) { super(); this.top = top; this.right = right; this.bottom = bottom; this.left = left; } }; __decorateClass([ Validate(POSITIVE_NUMBER) ], Padding.prototype, "top", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Padding.prototype, "right", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Padding.prototype, "bottom", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Padding.prototype, "left", 2); } }); // packages/ag-charts-community/src/util/render.ts function debouncedAnimationFrame(cb) { return buildScheduler((innerCb, _delayMs) => getWindow().requestAnimationFrame(innerCb), cb); } function debouncedCallback(cb) { return buildScheduler((innerCb, delayMs = 0) => { if (delayMs === 0) { queueMicrotask(innerCb); } else { setTimeout(innerCb, delayMs); } }, cb); } function buildScheduler(scheduleFn, cb) { let scheduleCount = 0; let promiseRunning = false; let awaitingPromise; let awaitingDone; const busy = () => { return promiseRunning; }; const done = () => { promiseRunning = false; awaitingDone?.(); awaitingDone = void 0; awaitingPromise = void 0; if (scheduleCount > 0) { scheduleFn(scheduleCb); } }; const scheduleCb = () => { const count = scheduleCount; scheduleCount = 0; promiseRunning = true; const maybePromise = cb({ count }); if (!maybePromise) { done(); return; } maybePromise.then(done, done); }; return { schedule(delayMs) { if (scheduleCount === 0 && !busy()) { scheduleFn(scheduleCb, delayMs); } scheduleCount++; }, async await() { if (!busy()) { return; } if (awaitingPromise == null) { awaitingPromise = new Promise((resolve) => { awaitingDone = resolve; }); } while (busy()) { await awaitingPromise; } } }; } var init_render = __esm({ "packages/ag-charts-community/src/util/render.ts"() { "use strict"; init_core(); } }); // packages/ag-charts-community/src/util/attributeUtil.ts function booleanParser(value) { return value === "true"; } function numberParser(value) { return Number(value); } function stringParser(value) { return value; } function setAttribute(e, qualifiedName, value) { if (value == null || value === "" || value === "") { e?.removeAttribute(qualifiedName); } else { e?.setAttribute(qualifiedName, value.toString()); } } function setAttributes(e, attrs) { if (attrs == null) return; for (const [key, value] of Object.entries(attrs)) { if (key === "class") continue; setAttribute(e, key, value); } } function getAttribute(e, qualifiedName, defaultValue) { if (!(e instanceof HTMLElement)) return void 0; const value = e.getAttribute(qualifiedName); if (value === null) return defaultValue; return AttributeTypeParsers[qualifiedName]?.(value) ?? void 0; } function setElementStyle(e, property, value) { if (e == null) return; if (value == null) { e.style.removeProperty(property); } else { e.style.setProperty(property, value.toString()); } } function setElementStyles(e, styles) { for (const [key, value] of Object.entries(styles)) { setElementStyle(e, key, value); } } var AttributeTypeParsers; var init_attributeUtil = __esm({ "packages/ag-charts-community/src/util/attributeUtil.ts"() { "use strict"; AttributeTypeParsers = { role: stringParser, "aria-checked": booleanParser, "aria-controls": stringParser, "aria-describedby": stringParser, "aria-disabled": booleanParser, "aria-expanded": booleanParser, "aria-haspopup": booleanParser, "aria-hidden": booleanParser, "aria-label": stringParser, "aria-labelledby": stringParser, "aria-live": stringParser, "aria-orientation": stringParser, "aria-selected": booleanParser, "data-preventdefault": booleanParser, class: stringParser, id: stringParser, tabindex: numberParser, title: stringParser, placeholder: stringParser }; } }); // packages/ag-charts-community/src/widget/widgetEvents.ts function allocMouseEvent(type, sourceEvent, current) { const { offsetX, offsetY, clientX, clientY } = sourceEvent; const { currentX, currentY } = WidgetEventUtil.calcCurrentXY(current, sourceEvent); return { type, offsetX, offsetY, clientX, clientY, currentX, currentY, sourceEvent }; } function allocTouchEvent(type, sourceEvent, _current) { return { type, sourceEvent }; } var WIDGET_HTML_EVENTS, WidgetAllocators, WidgetEventUtil; var init_widgetEvents = __esm({ "packages/ag-charts-community/src/widget/widgetEvents.ts"() { "use strict"; WIDGET_HTML_EVENTS = [ "blur", "change", "contextmenu", "focus", "keydown", "keyup", "click", "dblclick", "mouseenter", "mousemove", "mouseleave", "wheel", "touchstart", "touchmove", "touchend", "touchcancel" ]; WidgetAllocators = { blur: (sourceEvent) => { return { type: "blur", sourceEvent }; }, change: (sourceEvent) => { return { type: "change", sourceEvent }; }, contextmenu: (sourceEvent, current) => { return allocMouseEvent("contextmenu", sourceEvent, current); }, focus: (sourceEvent) => { return { type: "focus", sourceEvent }; }, keydown: (sourceEvent) => { return { type: "keydown", sourceEvent }; }, keyup: (sourceEvent) => { return { type: "keyup", sourceEvent }; }, click: (sourceEvent, current) => { return allocMouseEvent("click", sourceEvent, current); }, dblclick: (sourceEvent, current) => { return allocMouseEvent("dblclick", sourceEvent, current); }, mouseenter: (sourceEvent, current) => { return allocMouseEvent("mouseenter", sourceEvent, current); }, mousemove: (sourceEvent, current) => { return allocMouseEvent("mousemove", sourceEvent, current); }, mouseleave: (sourceEvent, current) => { return allocMouseEvent("mouseleave", sourceEvent, current); }, wheel: (sourceEvent) => { const { offsetX, offsetY, clientX, clientY } = sourceEvent; const factor = sourceEvent.deltaMode === 0 ? 0.01 : 1; const deltaX = sourceEvent.deltaX * factor; const deltaY = sourceEvent.deltaY * factor; return { type: "wheel", offsetX, offsetY, clientX, clientY, deltaX, deltaY, sourceEvent }; }, touchstart: (sourceEvent, current) => { return allocTouchEvent("touchstart", sourceEvent, current); }, touchmove: (sourceEvent, current) => { return allocTouchEvent("touchmove", sourceEvent, current); }, touchend: (sourceEvent, current) => { return allocTouchEvent("touchend", sourceEvent, current); }, touchcancel: (sourceEvent, current) => { return allocTouchEvent("touchcancel", sourceEvent, current); } }; WidgetEventUtil = class { static alloc(type, sourceEvent, current) { return WidgetAllocators[type](sourceEvent, current); } static isHTMLEvent(type) { const htmlTypes = WIDGET_HTML_EVENTS; return htmlTypes.includes(type); } static calcCurrentXY(current, event) { const currentRect = current.getBoundingClientRect(); return { currentX: event.clientX - currentRect.x, currentY: event.clientY - currentRect.y }; } }; } }); // packages/ag-charts-community/src/widget/widgetListenerHTML.ts var WidgetListenerHTML; var init_widgetListenerHTML = __esm({ "packages/ag-charts-community/src/widget/widgetListenerHTML.ts"() { "use strict"; init_widgetEvents(); WidgetListenerHTML = class { constructor() { this.widgetListeners = {}; this.sourceListeners = {}; } initSourceHandler(type, handler) { this.sourceListeners ?? (this.sourceListeners = {}); this.sourceListeners[type] = handler; } lazyGetWidgetListeners(type, target) { var _a; if (!(type in (this.sourceListeners ?? {}))) { const sourceHandler = (sourceEvent) => { const widgetEvent = WidgetEventUtil.alloc(type, sourceEvent, target.getElement()); for (const widgetListener of this.widgetListeners?.[type] ?? []) { widgetListener(widgetEvent, target); } }; const opts = {}; if (type.startsWith("touch")) opts.passive = false; this.initSourceHandler(type, sourceHandler); target.getElement().addEventListener(type, sourceHandler, opts); } this.widgetListeners ?? (this.widgetListeners = {}); (_a = this.widgetListeners)[type] ?? (_a[type] = []); return this.widgetListeners[type]; } add(type, target, handler) { const listeners = this.lazyGetWidgetListeners(type, target); listeners.push(handler); } remove(type, target, handler) { const listeners = this.lazyGetWidgetListeners(type, target); const index = listeners.indexOf(handler); if (index > -1) listeners.splice(index, 1); } destroy(target) { for (const [key, sourceHandler] of Object.entries(this.sourceListeners ?? {})) { const type = key; target.getElement().removeEventListener(type, sourceHandler); } this.widgetListeners = void 0; this.sourceListeners = void 0; } }; } }); // packages/ag-charts-community/src/widget/mouseDragger.ts function startMouseDrag(glob, self, myCallbacks, downEvent) { if (glob.globalMouseDragCallbacks != null) return void 0; return new MouseDragger(glob, self, myCallbacks, downEvent); } var MouseDragger; var init_mouseDragger = __esm({ "packages/ag-charts-community/src/widget/mouseDragger.ts"() { "use strict"; init_core(); MouseDragger = class { constructor(glob, self, myCallbacks, downEvent) { this.glob = glob; this.self = self; this.window = getWindow(); this.mousegeneral = (generalEvent) => { generalEvent.stopPropagation(); generalEvent.stopImmediatePropagation(); }; this.mousemove = (moveEvent) => { moveEvent.stopPropagation(); moveEvent.stopImmediatePropagation(); this.glob.globalMouseDragCallbacks?.mousemove(moveEvent); }; this.mouseup = (upEvent) => { if (upEvent.button === 0) { upEvent.stopPropagation(); upEvent.stopImmediatePropagation(); this.glob.globalMouseDragCallbacks?.mouseup(upEvent); this.destroy(); } }; const { window: window2, mousegeneral, mousemove, mouseup } = this; window2.addEventListener("mousedown", mousegeneral, { capture: true }); window2.addEventListener("mouseenter", mousegeneral, { capture: true }); window2.addEventListener("mouseleave", mousegeneral, { capture: true }); window2.addEventListener("mouseout", mousegeneral, { capture: true }); window2.addEventListener("mouseover", mousegeneral, { capture: true }); window2.addEventListener("mousemove", mousemove, { capture: true }); window2.addEventListener("mouseup", mouseup, { capture: true }); self.mouseDragger = this; glob.globalMouseDragCallbacks = myCallbacks; glob.globalMouseDragCallbacks.mousedown(downEvent); } destroy() { const { window: window2, mousegeneral, mousemove, mouseup } = this; window2.removeEventListener("mousedown", mousegeneral, { capture: true }); window2.removeEventListener("mouseenter", mousegeneral, { capture: true }); window2.removeEventListener("mouseleave", mousegeneral, { capture: true }); window2.removeEventListener("mouseout", mousegeneral, { capture: true }); window2.removeEventListener("mouseover", mousegeneral, { capture: true }); window2.removeEventListener("mousemove", mousemove, { capture: true }); window2.removeEventListener("mouseup", mouseup, { capture: true }); this.glob.globalMouseDragCallbacks = void 0; this.self.mouseDragger = void 0; } }; } }); // packages/ag-charts-community/src/widget/touchDragger.ts function deltaClientSquared(a, b) { const dx2 = a.clientX - b.clientX; const dy2 = a.clientY - b.clientY; return dx2 * dx2 + dy2 * dy2; } function startOneFingerTouch(glob, self, myCallbacks, initialTouch, target) { if (glob.globalTouchDragCallbacks != null || gIsInLongTap) return void 0; return new TouchDragger(glob, self, myCallbacks, initialTouch, target); } var LONG_TAP_DURATION_MS, LONG_TAP_INTERRUPT_MIN_TOUCHMOVE_PXPX, gIsInLongTap, TouchDragger; var init_touchDragger = __esm({ "packages/ag-charts-community/src/widget/touchDragger.ts"() { "use strict"; init_core(); LONG_TAP_DURATION_MS = 500; LONG_TAP_INTERRUPT_MIN_TOUCHMOVE_PXPX = 100; gIsInLongTap = false; TouchDragger = class { constructor(glob, self, myCallbacks, initialTouch, target) { this.glob = glob; this.self = self; this.initialTouch = initialTouch; this.target = target; this.longTapInterrupted = false; this.longtap = () => { const { target, initialTouch } = this; if (!this.longTapInterrupted) { target.dispatchEvent(new TouchEvent("touchcancel", { touches: [initialTouch], bubbles: true })); gIsInLongTap = true; const longTapMove = (e) => { e.preventDefault(); }; const longTapEnd = (e) => { gIsInLongTap = false; e.preventDefault(); target.removeEventListener("touchmove", longTapMove); target.removeEventListener("touchend", longTapEnd); target.removeEventListener("touchcancel", longTapEnd); }; target.addEventListener("touchmove", longTapMove, { passive: false }); target.addEventListener("touchend", longTapEnd, { passive: false }); target.addEventListener("touchcancel", longTapEnd, { passive: false }); const { clientX, clientY } = initialTouch; const contextMenuEvent = new PointerEvent("contextmenu", { bubbles: true, cancelable: true, view: getWindow(), clientX, clientY, pointerType: "touch" }); target.dispatchEvent(contextMenuEvent); } }; this.touchmove = (moveEvent) => { const { glob, self, initialTouch } = this; const touch = this.findInitialFinger(moveEvent.targetTouches); if (touch != null) { this.longTapInterrupted = this.longTapInterrupted || deltaClientSquared(initialTouch, touch) > LONG_TAP_INTERRUPT_MIN_TOUCHMOVE_PXPX; if (self.dragTouchEnabled && touch != null) { glob.globalTouchDragCallbacks?.touchmove(moveEvent, touch); } } }; this.touchend = (endEvent) => { this.longTapInterrupted = true; const touch = this.findInitialFinger(endEvent.changedTouches, endEvent.touches); if (touch != null) { this.glob.globalTouchDragCallbacks?.touchend(endEvent, touch); } this.destroy(); }; this.longtapTimer = setTimeout(this.longtap, LONG_TAP_DURATION_MS); const { touchmove, touchend } = this; target.addEventListener("touchmove", touchmove, { passive: false }); target.addEventListener("touchstart", touchend, { passive: false }); target.addEventListener("touchend", touchend, { passive: false }); target.addEventListener("touchcancel", touchend, { passive: false }); self.touchDragger = this; glob.globalTouchDragCallbacks = myCallbacks; } destroy() { const { longtapTimer, touchmove, touchend } = this; clearTimeout(longtapTimer); this.target.removeEventListener("touchstart", touchend); this.target.removeEventListener("touchmove", touchmove); this.target.removeEventListener("touchend", touchend); this.target.removeEventListener("touchcancel", touchend); this.glob.globalTouchDragCallbacks = void 0; this.self.touchDragger = void 0; } findInitialFinger(...touchLists) { const touches = touchLists.map((touchList) => Array.from(touchList)).flat(); return Array.from(touches).find((v) => v.identifier === this.initialTouch.identifier); } }; } }); // packages/ag-charts-community/src/widget/widgetListenerInternal.ts function makeMouseDrag(current, type, origin3, sourceEvent) { const { currentX, currentY } = WidgetEventUtil.calcCurrentXY(current.getElement(), sourceEvent); const originDeltaX = sourceEvent.pageX - origin3.pageX; const originDeltaY = sourceEvent.pageY - origin3.pageY; return { type, device: "mouse", offsetX: origin3.offsetX + originDeltaX, offsetY: origin3.offsetY + originDeltaY, clientX: sourceEvent.clientX, clientY: sourceEvent.clientY, currentX, currentY, originDeltaX, originDeltaY, sourceEvent }; } function getTouchOffsets(current, { pageX, pageY }) { const { x, y } = current.getElement().getBoundingClientRect(); return { offsetX: pageX - x, offsetY: pageY - y }; } function makeTouchDrag(current, type, origin3, sourceEvent, touch) { const { currentX, currentY } = WidgetEventUtil.calcCurrentXY(current.getElement(), touch); const originDeltaX = touch.pageX - origin3.pageX; const originDeltaY = touch.pageY - origin3.pageY; return { type, device: "touch", offsetX: origin3.offsetX + originDeltaX, offsetY: origin3.offsetY + originDeltaY, clientX: touch.clientX, clientY: touch.clientY, currentX, currentY, originDeltaX, originDeltaY, sourceEvent }; } var GlobalCallbacks, WidgetListenerInternal; var init_widgetListenerInternal = __esm({ "packages/ag-charts-community/src/widget/widgetListenerInternal.ts"() { "use strict"; init_bboxinterface(); init_object(); init_mouseDragger(); init_touchDragger(); init_widgetEvents(); GlobalCallbacks = {}; WidgetListenerInternal = class { constructor(dispatchCallback) { this.dispatchCallback = dispatchCallback; this.dragTouchEnabled = true; } destroy() { this.dragTriggerRemover?.(); this.dragTriggerRemover = void 0; this.dragStartListeners = void 0; this.dragMoveListeners = void 0; this.dragEndListeners = void 0; this.mouseDragger?.destroy(); this.touchDragger?.destroy(); } add(type, target, handler) { switch (type) { case "drag-start": { this.dragStartListeners ?? (this.dragStartListeners = []); this.dragStartListeners.push(handler); this.registerDragTrigger(target); break; } case "drag-move": { this.dragMoveListeners ?? (this.dragMoveListeners = []); this.dragMoveListeners.push(handler); this.registerDragTrigger(target); break; } case "drag-end": { this.dragEndListeners ?? (this.dragEndListeners = []); this.dragEndListeners.push(handler); this.registerDragTrigger(target); break; } } } remove(type, _target, handler) { switch (type) { case "drag-start": return this.removeHandler(this.dragStartListeners, handler); case "drag-move": return this.removeHandler(this.dragMoveListeners, handler); case "drag-end": return this.removeHandler(this.dragEndListeners, handler); } } removeHandler(array2, handler) { const index = array2?.indexOf(handler); if (index !== void 0) array2?.splice(index, 1); } registerDragTrigger(target) { if (this.dragTriggerRemover == null) { const mouseTrigger = (event) => this.triggerMouseDrag(target, event); const touchTrigger = (event) => this.triggerTouchDrag(target, event); target.getElement().addEventListener("mousedown", mouseTrigger); target.getElement().addEventListener("touchstart", touchTrigger, { passive: false }); this.dragTriggerRemover = () => { target.getElement().removeEventListener("mousedown", mouseTrigger); target.getElement().removeEventListener("touchstart", touchTrigger); }; } } triggerMouseDrag(current, downEvent) { if (downEvent.button === 0) { this.startMouseDrag(current, downEvent); } } startMouseDrag(current, initialDownEvent) { const origin3 = { pageX: NaN, pageY: NaN, offsetX: NaN, offsetY: NaN }; partialAssign(["pageX", "pageY", "offsetX", "offsetY"], origin3, initialDownEvent); const dragCallbacks = { mousedown: (downEvent) => { const dragStartEvent = makeMouseDrag(current, "drag-start", origin3, downEvent); this.dispatch("drag-start", current, dragStartEvent); }, mousemove: (moveEvent) => { const dragMoveEvent = makeMouseDrag(current, "drag-move", origin3, moveEvent); this.dispatch("drag-move", current, dragMoveEvent); }, mouseup: (upEvent) => { const dragEndEvent = makeMouseDrag(current, "drag-end", origin3, upEvent); this.dispatch("drag-end", current, dragEndEvent); this.endDrag(current, dragEndEvent); } }; this.mouseDragger = startMouseDrag(GlobalCallbacks, this, dragCallbacks, initialDownEvent); } endDrag(target, { sourceEvent, clientX, clientY }) { const elem = target.getElement(); const rect = elem.getBoundingClientRect(); if (!BBoxValues.containsPoint(rect, clientX, clientY)) { elem.dispatchEvent(new MouseEvent("mouseleave", sourceEvent)); sourceEvent.target?.dispatchEvent(new MouseEvent("mouseenter", sourceEvent)); } } triggerTouchDrag(current, startEvent) { const touch = startEvent.targetTouches.item(0); if (startEvent.targetTouches.length === 1 && touch != null) { this.startOneFingerTouch(current, startEvent, touch); } } startOneFingerTouch(current, initialEvent, initialTouch) { const origin3 = { pageX: NaN, pageY: NaN, ...getTouchOffsets(current, initialTouch) }; partialAssign(["pageX", "pageY"], origin3, initialTouch); const dragCallbacks = { touchmove: (moveEvent, touch) => { const dragMoveEvent = makeTouchDrag(current, "drag-move", origin3, moveEvent, touch); this.dispatch("drag-move", current, dragMoveEvent); }, touchend: (cancelEvent, touch) => { const dragMoveEvent = makeTouchDrag(current, "drag-end", origin3, cancelEvent, touch); this.dispatch("drag-end", current, dragMoveEvent); } }; const target = current.getElement(); this.touchDragger = startOneFingerTouch(GlobalCallbacks, this, dragCallbacks, initialTouch, target); const dragStartEvent = makeTouchDrag(current, "drag-start", origin3, initialEvent, initialTouch); this.dispatch("drag-start", current, dragStartEvent); } dispatch(type, current, event) { switch (type) { case "drag-start": this.dragStartListeners?.forEach((handler) => handler(event, current)); break; case "drag-move": this.dragMoveListeners?.forEach((handler) => handler(event, current)); break; case "drag-end": this.dragEndListeners?.forEach((handler) => handler(event, current)); break; } this.dispatchCallback(type, event); } }; } }); // packages/ag-charts-community/src/widget/widget.ts var WidgetBounds, Widget; var init_widget = __esm({ "packages/ag-charts-community/src/widget/widget.ts"() { "use strict"; init_core(); init_attributeUtil(); init_dom(); init_widgetEvents(); init_widgetListenerHTML(); init_widgetListenerInternal(); WidgetBounds = class { constructor(elem) { this.elem = elem; } setBounds(bounds) { setElementBBox(this.elemContainer ?? this.elem, bounds); } getBounds() { return getElementBBox(this.elemContainer ?? this.elem); } static setElementContainer(widget, elemContainer) { const currentBounds = widget.getBounds(); setElementBBox(elemContainer, currentBounds); setElementStyles(widget.elem, { width: "100%", height: "100%" }); widget.elem.remove(); widget.elemContainer = elemContainer; widget.elemContainer.replaceChildren(widget.elem); } }; Widget = class extends WidgetBounds { constructor(elem) { super(elem); this.elem = elem; this.index = NaN; this.children = []; } getElement() { return this.elem; } getBoundingClientRect() { return this.elem.getBoundingClientRect(); } get clientWidth() { return this.elem.clientWidth; } get clientHeight() { return this.elem.clientHeight; } destroy() { this.parent?.removeChild(this); this.children.forEach((child) => { child.parent = void 0; child.destroy(); }); this.children.length = 0; this.destructor(); this.elem.remove(); this.elemContainer?.remove(); this.internalListener?.destroy(); this.htmlListener?.destroy(this); } setHidden(hidden) { setElementStyle(this.elem, "display", hidden ? "none" : void 0); } isHidden() { return getWindow()?.getComputedStyle?.(this.elem).display === "none"; } setCursor(cursor) { setElementStyle(this.elem, "cursor", cursor); } setTextContent(textContent) { this.elem.textContent = textContent ?? null; } setAriaDescribedBy(ariaDescribedBy) { setAttribute(this.elem, "aria-describedby", ariaDescribedBy); } setAriaHidden(ariaHidden) { setAttribute(this.elem, "aria-hidden", ariaHidden); } setAriaLabel(ariaLabel) { setAttribute(this.elem, "aria-label", ariaLabel); } setInnerHTML(html) { this.elem.innerHTML = html; } isDisabled() { return getAttribute(this.elem, "aria-disabled", false); } parseFloat(s) { return s === "" ? 0 : parseFloat(s); } cssLeft() { return this.parseFloat(this.elem.style.left); } cssTop() { return this.parseFloat(this.elem.style.top); } cssWidth() { return this.parseFloat(this.elem.style.width); } cssHeight() { return this.parseFloat(this.elem.style.height); } focus() { this.elem.focus(); } setPreventsDefault(preventDefault) { setAttribute(this.elem, "data-preventdefault", preventDefault); } setTabIndex(tabIndex) { setAttribute(this.elem, "tabindex", tabIndex); } addChild(child) { this.addChildToDOM(child, this.getBefore(child)); this.children.push(child); child.index = this.children.length - 1; child.parent = this; this.onChildAdded(child); } removeChild(child) { const i = this.children.findIndex((value) => value === child); this.children.splice(i, 1); this.removeChildFromDOM(child); this.onChildRemoved(child); } moveChild(child, domIndex) { if (child.domIndex === domIndex) return; child.domIndex = domIndex; this.removeChildFromDOM(child); this.addChildToDOM(child, this.getBefore(child)); } addClass(...tokens) { this.elem.classList.add(...tokens); } removeClass(...tokens) { this.elem.classList.remove(...tokens); } toggleClass(token, force) { this.elem.classList.toggle(token, force); } appendOrInsert(child, before) { if (before) { before.getElement().insertAdjacentElement("beforebegin", child); } else { this.elem.appendChild(child); } } addChildToDOM(child, before) { this.appendOrInsert(child.getElement(), before); } removeChildFromDOM(child) { this.elem.removeChild(child.getElement()); } onChildAdded(_child) { } onChildRemoved(_child) { } getBefore({ domIndex }) { if (domIndex === void 0) return void 0; return this.children.filter((child) => child.domIndex !== void 0 && child.domIndex > domIndex).reduce((prev, curr) => !prev || curr.domIndex < prev.domIndex ? curr : prev, void 0); } addListener(type, listener) { if (WidgetEventUtil.isHTMLEvent(type)) { this.htmlListener ?? (this.htmlListener = new WidgetListenerHTML()); this.htmlListener.add(type, this, listener); } else { this.internalListener ?? (this.internalListener = new WidgetListenerInternal(this.onDispatch.bind(this))); this.internalListener.add(type, this, listener); } return () => this.removeListener(type, listener); } removeListener(type, listener) { if (WidgetEventUtil.isHTMLEvent(type)) { this.htmlListener?.remove(type, this, listener); } else if (this.htmlListener != null) { this.internalListener?.remove(type, this, listener); } } setDragTouchEnabled(dragTouchEnabled) { this.internalListener ?? (this.internalListener = new WidgetListenerInternal(this.onDispatch.bind(this))); this.internalListener.dragTouchEnabled = dragTouchEnabled; } onDispatch(type, event) { if (!event.sourceEvent.bubbles) return; let { parent } = this; while (parent != null) { const { internalListener } = parent; if (internalListener != null) { const parentEvent = { ...event, ...WidgetEventUtil.calcCurrentXY(parent.getElement(), event) }; internalListener.dispatch(type, parent, parentEvent); } parent = parent.parent; } } static addWindowEvent(_type, listener) { const pagehideHandler = (event) => { if (event.persisted) { return; } listener(); }; getWindow().addEventListener("pagehide", pagehideHandler); return () => getWindow().removeEventListener("pagehide", pagehideHandler); } }; } }); // packages/ag-charts-community/src/chart/layout/layoutManager.ts var LayoutElement, LayoutManager, LayoutContext; var init_layoutManager = __esm({ "packages/ag-charts-community/src/chart/layout/layoutManager.ts"() { "use strict"; init_main(); init_bbox(); LayoutElement = /* @__PURE__ */ ((LayoutElement6) => { LayoutElement6[LayoutElement6["Caption"] = 0] = "Caption"; LayoutElement6[LayoutElement6["Legend"] = 1] = "Legend"; LayoutElement6[LayoutElement6["ToolbarLeft"] = 2] = "ToolbarLeft"; LayoutElement6[LayoutElement6["ToolbarBottom"] = 3] = "ToolbarBottom"; LayoutElement6[LayoutElement6["Navigator"] = 4] = "Navigator"; LayoutElement6[LayoutElement6["Overlay"] = 5] = "Overlay"; return LayoutElement6; })(LayoutElement || {}); LayoutManager = class { constructor() { this.events = new EventEmitter(); this.elements = /* @__PURE__ */ new Map(); } addListener(eventName, listener) { return this.events.on(eventName, listener); } registerElement(element2, listener) { if (this.elements.has(element2)) { this.elements.get(element2).add(listener); } else { this.elements.set(element2, /* @__PURE__ */ new Set([listener])); } return () => this.elements.get(element2)?.delete(listener); } createContext(width2, height2) { const context = new LayoutContext(width2, height2); for (const element2 of Object.values(LayoutElement)) { if (typeof element2 !== "number") continue; this.elements.get(element2)?.forEach((listener) => listener(context)); } return context; } emitLayoutComplete(context, options) { const eventType = "layout:complete"; const { width: width2, height: height2 } = context; this.events.emit(eventType, { type: eventType, axes: options.axes ?? [], chart: { width: width2, height: height2 }, clipSeries: options.clipSeries ?? false, series: options.series }); } }; LayoutContext = class { constructor(width2, height2) { this.width = width2; this.height = height2; this.layoutBox = new BBox(0, 0, width2, height2); } }; } }); // packages/ag-charts-community/src/chart/chartCaptions.ts var ChartCaptions; var init_chartCaptions = __esm({ "packages/ag-charts-community/src/chart/chartCaptions.ts"() { "use strict"; init_textMeasurer(); init_validation2(); init_caption(); ChartCaptions = class { constructor() { this.title = new Caption(); this.subtitle = new Caption(); this.footnote = new Caption(); } positionCaptions(ctx) { const { title, subtitle, footnote } = this; const maxHeight = ctx.layoutBox.height / 10; if (title.enabled) { const { spacing = subtitle.enabled ? Caption.SMALL_PADDING : Caption.LARGE_PADDING } = title; this.positionCaption("top", title, ctx.layoutBox, maxHeight); this.shrinkLayoutByCaption("top", title, ctx.layoutBox, spacing); } if (subtitle.enabled) { this.positionCaption("top", subtitle, ctx.layoutBox, maxHeight); this.shrinkLayoutByCaption("top", subtitle, ctx.layoutBox, subtitle.spacing); } if (footnote.enabled) { this.positionCaption("bottom", footnote, ctx.layoutBox, maxHeight); this.shrinkLayoutByCaption("bottom", footnote, ctx.layoutBox, footnote.spacing); } } positionAbsoluteCaptions(ctx) { const { title, subtitle, footnote } = this; const { rect } = ctx.series; for (const caption of [title, subtitle, footnote]) { if (caption.layoutStyle !== "overlay") continue; if (caption.textAlign === "left") { caption.node.x = rect.x + caption.padding; } else if (caption.textAlign === "right") { const bbox = caption.node.getBBox(); caption.node.x = rect.x + rect.width - bbox.width - caption.padding; } } } computeX(align2, layoutBox) { if (align2 === "left") { return layoutBox.x; } else if (align2 === "right") { return layoutBox.x + layoutBox.width; } return layoutBox.x + layoutBox.width / 2; } positionCaption(vAlign, caption, layoutBox, maxHeight) { const containerHeight = Math.max(TextUtils.getLineHeight(caption.fontSize), maxHeight); caption.node.x = this.computeX(caption.textAlign, layoutBox) + caption.padding; caption.node.y = layoutBox.y + (vAlign === "top" ? 0 : layoutBox.height) + caption.padding; caption.node.textBaseline = vAlign; caption.computeTextWrap(layoutBox.width, containerHeight); } shrinkLayoutByCaption(vAlign, caption, layoutBox, spacing = 0) { if (caption.layoutStyle === "block") { const bbox = caption.node.getBBox(); layoutBox.shrink( vAlign === "top" ? Math.ceil(bbox.y - layoutBox.y + bbox.height + spacing) : Math.ceil(layoutBox.y + layoutBox.height - bbox.y + spacing), vAlign ); } } }; __decorateClass([ Validate(OBJECT) ], ChartCaptions.prototype, "title", 2); __decorateClass([ Validate(OBJECT) ], ChartCaptions.prototype, "subtitle", 2); __decorateClass([ Validate(OBJECT) ], ChartCaptions.prototype, "footnote", 2); } }); // packages/ag-charts-community/src/api/preset/chartTypeOriginator.ts var chartTypes, ChartTypeOriginator; var init_chartTypeOriginator = __esm({ "packages/ag-charts-community/src/api/preset/chartTypeOriginator.ts"() { "use strict"; init_main(); chartTypes = [ "candlestick", "hollow-candlestick", "ohlc", "line", "step-line", "hlc", "high-low" ]; ChartTypeOriginator = class { constructor(chartService) { this.chartService = chartService; this.mementoOriginatorKey = "chartType"; } createMemento() { let chartType = this.chartService.publicApi?.getOptions()?.chartType; if (chartType == null) chartType = "candlestick"; return chartType; } guardMemento(blob) { return blob == null || chartTypes.includes(blob); } restoreMemento(_version, _mementoVersion, memento) { if (memento == null) return; const options = { chartType: memento }; this.chartService.publicApi?.updateDelta(options).catch((e) => logger_exports.error("error restoring state", e)); } }; } }); // packages/ag-charts-community/src/util/destroy.ts var DestroyFns; var init_destroy = __esm({ "packages/ag-charts-community/src/util/destroy.ts"() { "use strict"; DestroyFns = class { constructor() { this.destroyFns = []; } destroy() { this.destroyFns.forEach((fn) => fn()); this.destroyFns.length = 0; } setFns(destroyFns) { this.destroy(); this.destroyFns = destroyFns; } push(...destroyFns) { this.destroyFns.push(...destroyFns); } }; } }); // packages/ag-charts-community/src/version.ts var VERSION; var init_version = __esm({ "packages/ag-charts-community/src/version.ts"() { "use strict"; VERSION = "11.1.1"; } }); // packages/ag-charts-community/src/api/state/historyManager.ts var NOT_FOUND, HistoryManager; var init_historyManager = __esm({ "packages/ag-charts-community/src/api/state/historyManager.ts"() { "use strict"; init_debug(); init_destroy(); init_version(); NOT_FOUND = Symbol("previous-memento-not-found"); HistoryManager = class { constructor(chartEventManager) { this.history = []; this.historyIndex = -1; this.originators = /* @__PURE__ */ new Map(); this.clearState = /* @__PURE__ */ new Map(); this.maxHistoryLength = 100; this.debug = Debug.create(true, "history"); this.destroyFns = new DestroyFns(); this.destroyFns.setFns([ chartEventManager.addListener("series-undo", this.undo.bind(this)), chartEventManager.addListener("series-redo", this.redo.bind(this)) ]); } destroy() { this.destroyFns.destroy(); } addMementoOriginator(originator) { this.originators.set(originator.mementoOriginatorKey, originator); this.clearState.set(originator.mementoOriginatorKey, originator.createMemento()); this.debugEvent("History add originator:", originator.mementoOriginatorKey); } clear() { this.debug(`History clear:`, Object.keys(this.originators)); this.history = []; this.historyIndex = -1; for (const [mementoOriginatorKey, originator] of this.originators.entries()) { this.clearState.set(mementoOriginatorKey, originator.createMemento()); } } record(label, ...originators) { if (this.historyIndex < this.history.length - 1) { this.history = this.history.slice(0, this.historyIndex + 1); } if (this.history.length > this.maxHistoryLength) { this.history = this.history.slice(-this.maxHistoryLength); } const mementos = /* @__PURE__ */ new Map(); for (const originator of originators) { if (!this.originators.has(originator.mementoOriginatorKey)) { throw new Error( `Originator [${originator.mementoOriginatorKey}] has not been added to the HistoryManager.` ); } mementos.set(originator.mementoOriginatorKey, originator.createMemento()); } this.history.push({ label, mementos }); this.historyIndex = this.history.length - 1; this.debugEvent(`History record: [${label}]`); } undo() { const undoAction = this.history[this.historyIndex]; if (!undoAction) return; for (const mementoOriginatorKey of undoAction.mementos.keys()) { const previousMemento = this.findPreviousMemento(mementoOriginatorKey); if (previousMemento === NOT_FOUND) { throw new Error(`Could not find previous memento for [${mementoOriginatorKey}].`); } this.restoreMemento(mementoOriginatorKey, previousMemento); } this.historyIndex -= 1; this.debugEvent(`History undo: [${undoAction.label}]`); } redo() { const redoAction = this.history[this.historyIndex + 1]; if (!redoAction) return; for (const [mementoOriginatorKey, memento] of redoAction.mementos.entries()) { this.restoreMemento(mementoOriginatorKey, memento); } this.historyIndex += 1; this.debugEvent(`History redo: [${redoAction.label}]`); } findPreviousMemento(mementoOriginatorKey) { for (let i = this.historyIndex - 1; i >= 0; i--) { if (this.history[i].mementos.has(mementoOriginatorKey)) { return this.history[i].mementos.get(mementoOriginatorKey); } } if (this.clearState.has(mementoOriginatorKey)) { return this.clearState.get(mementoOriginatorKey); } return NOT_FOUND; } restoreMemento(mementoOriginatorKey, memento) { this.originators.get(mementoOriginatorKey)?.restoreMemento(VERSION, VERSION, memento); } debugEvent(...logContent) { this.debug( ...logContent, this.history.map((action, index) => index === this.historyIndex ? `** ${action.label} **` : action.label) ); } }; } }); // packages/ag-charts-community/src/api/state/memento.ts var MementoCaretaker; var init_memento = __esm({ "packages/ag-charts-community/src/api/state/memento.ts"() { "use strict"; init_main(); MementoCaretaker = class _MementoCaretaker { constructor(version) { this.version = version.split("-")[0]; } save(...originators) { const packet = { version: this.version }; for (const originator of Object.values(originators)) { packet[originator.mementoOriginatorKey] = this.encode(originator, originator.createMemento()); } return packet; } restore(blob, ...originators) { if (typeof blob !== "object") { logger_exports.warnOnce(`Could not restore data of type [${typeof blob}], expecting an object, ignoring.`); return; } if (blob == null) { logger_exports.warnOnce(`Could not restore data of type [null], expecting an object, ignoring.`); return; } if (!("version" in blob) || typeof blob.version !== "string") { logger_exports.warnOnce(`Could not restore data, missing [version] string in object, ignoring.`); return; } for (const originator of originators) { const memento = this.decode(originator, blob[originator.mementoOriginatorKey]); const messages = []; if (!originator.guardMemento(memento, messages)) { const messagesString = messages.length > 0 ? ` ${messages.join("\n\n")} ` : ""; logger_exports.warnOnce( `Could not restore [${originator.mementoOriginatorKey}] data, value was invalid, ignoring.${messagesString}`, memento ); return; } originator.restoreMemento(this.version, blob.version, memento); } } /** * Encode a memento as a serializable object, encoding any non-serializble types. */ encode(originator, memento) { try { return JSON.parse(JSON.stringify(memento, _MementoCaretaker.encodeTypes)); } catch (error3) { throw new Error(`Failed to encode [${originator.mementoOriginatorKey}] value [${error3}].`, { cause: error3 }); } } /** * Decode an encoded memento, decoding any non-serializable types. */ decode(originator, encoded) { if (encoded == null) return encoded; try { return JSON.parse(JSON.stringify(encoded), _MementoCaretaker.decodeTypes); } catch (error3) { throw new Error(`Failed to decode [${originator.mementoOriginatorKey}] value [${error3}].`, { cause: error3 }); } } static encodeTypes(key, value) { if (isDate(this[key])) { return { __type: "date", value: this[key].toISOString() }; } return value; } static decodeTypes(key, value) { if (isObject(this[key]) && "__type" in this[key] && this[key].__type === "date") { return new Date(this[key].value); } return value; } }; } }); // packages/ag-charts-community/src/api/state/stateManager.ts var StateManager; var init_stateManager = __esm({ "packages/ag-charts-community/src/api/state/stateManager.ts"() { "use strict"; init_object(); init_version(); init_memento(); StateManager = class { constructor() { this.caretaker = new MementoCaretaker(VERSION); this.state = /* @__PURE__ */ new Map(); } setState(originator, value) { if (objectsEqual(this.state.get(originator.mementoOriginatorKey), value)) { return; } this.setStateAndRestore(originator, value); } setStateAndRestore(originator, value) { this.state.set(originator.mementoOriginatorKey, value); this.restoreState(originator); } restoreState(originator) { const { caretaker, state } = this; if (!state.has(originator.mementoOriginatorKey)) return; const value = state.get(originator.mementoOriginatorKey); caretaker.restore({ version: caretaker.version, [originator.mementoOriginatorKey]: value }, originator); } }; } }); // packages/ag-charts-community/src/styles.css var styles_default; var init_styles = __esm({ "packages/ag-charts-community/src/styles.css"() { styles_default = '.ag-charts-wrapper,.ag-charts-wrapper:after,.ag-charts-wrapper:before,.ag-charts-wrapper *,.ag-charts-wrapper *:after,.ag-charts-wrapper *:before{box-sizing:border-box}.ag-charts-wrapper{--align-items: center;--justify-content: center;position:relative;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ag-charts-wrapper--safe-horizontal{--justify-content: flex-start}.ag-charts-wrapper--safe-vertical{--align-items: flex-start}.ag-charts-tab-guard{width:0%;height:0%;position:absolute;pointer-events:none}.ag-charts-canvas-center{width:100%;height:100%;position:absolute;touch-action:auto;pointer-events:auto;display:flex;align-items:var(--align-items);justify-content:var(--justify-content)}.ag-charts-canvas-container,.ag-charts-canvas{position:relative;user-select:none;-webkit-user-select:none}.ag-charts-canvas-container>*,.ag-charts-canvas>*{display:block;pointer-events:none}.ag-charts-series-area{outline:none;pointer-events:auto;position:absolute}.ag-charts-swapchain{outline:none;opacity:0;pointer-events:none;position:absolute;width:100%;height:100%}.ag-charts-swapchain:focus-visible{opacity:1}.ag-charts-canvas-proxy,.ag-charts-canvas-overlay{inset:0;pointer-events:none;position:absolute;user-select:none;-webkit-user-select:none}.ag-charts-canvas-overlay>*{position:absolute;pointer-events:auto}.ag-charts-theme-default,.ag-charts-theme-default-dark{--ag-charts-accent-color: #2196f3;--ag-charts-background-color: #fff;--ag-charts-border-color: #dddddd;--ag-charts-foreground-color: #464646;--ag-charts-font-family: Verdana, sans-serif;--ag-charts-font-size: 12px;--ag-charts-font-weight: 400;--ag-charts-padding: 20px;--ag-charts-shadow-color: #00000080;--ag-charts-subtle-text-color: #8c8c8c;--ag-charts-text-color: #464646;--ag-charts-chrome-background-color: #fafafa;--ag-charts-chrome-font-family: Verdana, sans-serif;--ag-charts-chrome-font-size: 12px;--ag-charts-chrome-font-weight: 400;--ag-charts-chrome-subtle-text-color: #8c8c8c;--ag-charts-chrome-text-color: #181d1f;--ag-charts-input-background-color: #fff;--ag-charts-input-text-color: #464646;--ag-charts-crosshair-label-background-color: #fff;--ag-charts-crosshair-label-text-color: #464646;--ag-charts-spacing: 4px;--ag-charts-border-radius: 4px;--ag-charts-shadow: 0 2px 8px 0 color-mix(in srgb, black 8%, transparent);--ag-charts-focus-shadow: 0 0 0 3px var(--ag-charts-accent-color);--ag-charts-focus-color: color-mix(in srgb, var(--ag-charts-background-color), var(--ag-charts-accent-color) 12%);--ag-charts-input-border-color: var(--ag-charts-border-color);--ag-charts-input-border-radius: var(--ag-charts-border-radius);--ag-charts-input-focus-border-color: var(--ag-charts-accent-color);--ag-charts-input-focus-text-color: var(--ag-charts-accent-color);--ag-charts-input-disabled-background-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-foreground-color) 6% );--ag-charts-input-disabled-border-color: var(--ag-charts-border-color);--ag-charts-input-disabled-text-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-input-text-color) 50% );--ag-charts-input-placeholder-text-color: color-mix( in srgb, var(--ag-charts-input-background-color), var(--ag-charts-input-text-color) 60% );--ag-charts-button-background-color: var(--ag-charts-background-color);--ag-charts-button-border-color: var(--ag-charts-border-color);--ag-charts-button-border-radius: var(--ag-charts-border-radius);--ag-charts-button-text-color: var(--ag-charts-text-color);--ag-charts-button-focus-background-color: color-mix( in srgb, var(--ag-charts-button-background-color), var(--ag-charts-accent-color) 12% );--ag-charts-button-focus-border-color: var(--ag-charts-accent-color);--ag-charts-button-focus-text-color: var(--ag-charts-accent-color);--ag-charts-button-disabled-background-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-foreground-color) 6% );--ag-charts-button-disabled-border-color: var(--ag-charts-border-color);--ag-charts-button-disabled-text-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-chrome-text-color) 50% );--ag-charts-checkbox-background-color: color-mix( in srgb, var(--ag-charts-background-color), var(--ag-charts-foreground-color) 35% );--ag-charts-checkbox-checked-background-color: var(--ag-charts-accent-color);--ag-charts-chrome-font-size-small: var(--ag-charts-chrome-font-size);--ag-charts-chrome-font-size-medium: calc(var(--ag-charts-chrome-font-size) * (13 / 12));--ag-charts-chrome-font-size-large: calc(var(--ag-charts-chrome-font-size) * (14 / 12));--ag-charts-border: solid 1px var(--ag-charts-border-color);--ag-charts-focus-border: solid 1px var(--ag-charts-accent-color);--ag-charts-focus-border-shadow: 0 0 0 3px color-mix(in srgb, transparent, var(--ag-charts-accent-color) 20%);--ag-charts-layer-menu: 6;--ag-charts-layer-ui-overlay: 5;--ag-charts-layer-tooltip: 4;--ag-charts-layer-toolbar: 3;--ag-charts-layer-crosshair: 2;--ag-charts-layer-annotations: 1}.ag-charts-theme-default-dark{--ag-charts-shadow: 0 2px 12px 0 color-mix(in srgb, black 33.3%, transparent);--ag-charts-focus-color: color-mix(in srgb, var(--ag-charts-background-color), var(--ag-charts-accent-color) 22%)}.ag-chart-canvas-wrapper .ag-charts-theme-default{--ag-charts-border-radius: var(--ag-border-radius, 4px);--ag-charts-border: var(--ag-borders-critical, solid 1px) var(--ag-charts-border-color);--ag-charts-focus-shadow: var(--ag-focus-shadow, 0 0 0 3px var(--ag-charts-accent-color));--ag-charts-focus-border-shadow: var( --ag-focus-shadow, 0 0 0 3px color-mix(in srgb, transparent, var(--ag-charts-accent-color) 20%) )}.ag-charts-icon{display:block;width:20px;height:20px;speak:none;speak:never;mask:var(--icon) center / contain no-repeat;background-color:currentColor;transition:background-color .25s ease-in-out}.ag-charts-icon-align-center{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNNyAxMGg2djFIN3pNNCA3aDEydjFINHptMSA2aDEwdjFINXoiLz48L3N2Zz4=)}.ag-charts-icon-align-left{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNNCAxMGg2djFINHptMC0zaDEydjFINHptMCA2aDEwdjFINHoiLz48L3N2Zz4=)}.ag-charts-icon-align-right{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTAgMTBoNnYxaC02ek00IDdoMTJ2MUg0em0yIDZoMTB2MUg2eiIvPjwvc3ZnPg==)}.ag-charts-icon-arrow-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE1LjI5MyA0LjVIMTIuNXYtMUgxN3Y0aC0xVjUuMjA3bC05LjY0NiA5LjY0Ny0uNzA4LS43MDh6IiBmaWxsPSIjMDAwIi8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDE2YTIuNSAyLjUgMCAxIDEtNSAwIDIuNSAyLjUgMCAwIDEgNSAwbS0yLjUgMS41YTEuNSAxLjUgMCAxIDAgMC0zIDEuNSAxLjUgMCAwIDAgMCAzIiBmaWxsPSIjMDAwIi8+PC9zdmc+)}.ag-charts-icon-arrow-down-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik02IDhMMS41IDhMMTAgMThMMTguNSA4TDE0IDhMMTQgM0w2IDNMNiA4Wk03IDRMNyA5SDMuNjYyNDRMMTAgMTYuNDU2TDE2LjMzNzYgOUwxMyA5TDEzIDRMNyA0WiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+Cg==)}.ag-charts-icon-arrow-up-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNCAxMkgxOC41TDEwIDJMMS41IDEySDZMNi4wMDAwMiAxN0gxNFYxMlpNMTMgMTZWMTFIMTYuMzM3NkwxMCAzLjU0NDA1TDMuNjYyNDQgMTFIN0w3LjAwMDAyIDE2SDEzWiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+Cg==)}.ag-charts-icon-callout-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMyA0LjVBMS41IDEuNSAwIDAgMSA0LjUgM2gxMUExLjUgMS41IDAgMCAxIDE3IDQuNXY4YTEuNSAxLjUgMCAwIDEtMS41IDEuNWgtNC41MTRhMjYgMjYgMCAwIDAtMi4wMTcgMS41NGwtLjMxNC4yNmMtLjU1LjQ1Ny0xLjExNS45MjYtMS43NiAxLjQtLjY2OS40OTEtMS41NjItLjAxMi0xLjU2Mi0uOFYxNEg0LjVBMS41IDEuNSAwIDAgMSAzIDEyLjV6TTQuNSA0YS41LjUgMCAwIDAtLjUuNXY4YS41LjUgMCAwIDAgLjUuNWgxLjgzM3YzLjM3MmEzNiAzNiAwIDAgMCAxLjY3OC0xLjMzOGwuMzItLjI2NWEyNiAyNiAwIDAgMSAyLjIyNS0xLjY4NWwuMTI2LS4wODRIMTUuNWEuNS41IDAgMCAwIC41LS41di04YS41LjUgMCAwIDAtLjUtLjV6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-candlestick-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNyAxdjNoMnYxMkg3djNINnYtM0g0VjRoMlYxek01IDVoM3YxMEg1ek0xMSAxNFY2aDJWMy4yNWgxVjZoMnY4aC0ydjIuNzVoLTFWMTR6bTEtN2gzdjZoLTN6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-close{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSA1IDEwIDEwTTUgMTUgMTUgNSIgc3Ryb2tlPSIjMDAwIi8+PC9zdmc+)}.ag-charts-icon-comment-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNy41MTMgMy45OTVhNi41IDYuNSAwIDAgMSA2LjA5OCAxMS40MWMtLjU4OC4zOTMtMS4yMTcuNTM2LTEuODI5LjU4NWExMyAxMyAwIDAgMS0xLjI3LjAxN0EyNyAyNyAwIDAgMCAxMCAxNkg0LjVhLjUuNSAwIDAgMS0uNS0uNVYxMHEwLS4yNDctLjAwNy0uNTEzYy0uMDA4LS40MTYtLjAxNi0uODU3LjAxNy0xLjI2OS4wNS0uNjEyLjE5Mi0xLjI0LjU4NS0xLjgzYTYuNSA2LjUgMCAwIDEgMi45MTgtMi4zOTNtMy41Ni42MWE1LjUgNS41IDAgMCAwLTUuNjQ2IDIuMzRjLS4yNjYuMzk3LS4zNzkuODQyLS40MiAxLjM1NC0uMDMuMzYtLjAyMi43MTgtLjAxNSAxLjEwOFE1IDkuNjg5IDUgMTB2NWg1cS4zMTEuMDAxLjU5My4wMDhjLjM5LjAwNy43NDcuMDE1IDEuMTA4LS4wMTUuNTEyLS4wNDEuOTU3LS4xNTQgMS4zNTUtLjQyYTUuNSA1LjUgMCAwIDAtMS45ODMtOS45NjciIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-crosshair-add-line{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTEwIDUuNWEuNS41IDAgMCAxIC41LjV2My41aDMuODc1YS41LjUgMCAwIDEgMCAxSDEwLjV2NC4yNWEuNS41IDAgMSAxLTEgMFYxMC41SDUuNjI1YS41LjUgMCAxIDEgMC0xSDkuNVY2YS41LjUgMCAwIDEgLjUtLjUiLz48L3N2Zz4=)}.ag-charts-icon-date-range-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMiAyaDF2MTZIMnptMTUgMGgxdjE2aC0xeiIgZmlsbD0iIzE4MUQxRiIvPjxwYXRoIGQ9Ik0xMy4xNTcgMTFINXYtMWg3Ljc5M0wxMSA4LjIwN2wuNzA3LS43MDcgMy4xODIgMy4xODItMy4xODIgMy4xODItLjcwNy0uNzA3eiIgZmlsbD0iIzAwMCIvPjwvc3ZnPg==)}.ag-charts-icon-date-price-range-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMyAySDJ2MTZoMXptMy41MDcgNC44OUw4LjUgNC44OTVWMTBINXYxaDMuNXY3aDF2LTdoNS4wODhsLTEuOTU3IDEuOTU3LjcwNy43MDcgMy4xODItMy4xODJMMTMuMzM4IDcuM2wtLjcwNy43MDdMMTQuNjI0IDEwSDkuNVY0LjkzMmwxLjk1NyAxLjk1Ny43MDctLjcwN0w4Ljk4MiAzIDUuOCA2LjE4MnoiIGZpbGw9IiMxODFEMUYiLz48L3N2Zz4=)}.ag-charts-icon-delete{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZD0iTTguNDk2IDguOTk2QS41LjUgMCAwIDEgOSA5LjQ5MnY0YS41LjUgMCAxIDEtMSAuMDA4di00YS41LjUgMCAwIDEgLjQ5Ni0uNTA0TTEyIDkuNWEuNS41IDAgMCAwLTEgMHY0YS41LjUgMCAwIDAgMSAweiIvPjxwYXRoIGZpbGw9IiMxMzE3MjIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTYgNVYzLjVBMi41IDIuNSAwIDAgMSA4LjUgMWgzQTIuNSAyLjUgMCAwIDEgMTQgMy41VjVoMi44MzNhLjUuNSAwIDAgMSAwIDFIMTV2MTAuMjVjMCAuNDE1LS4wNjYuODYzLS4zIDEuMjIxLS4yNTcuMzk0LS42NzIuNjEyLTEuMi42MTJoLTdjLS41MjggMC0uOTQzLS4yMTgtMS4yLS42MTItLjIzNC0uMzU4LS4zLS44MDYtLjMtMS4yMjFWNkgzLjMzM2EuNS41IDAgMCAxIDAtMXptMS0xLjVBMS41IDEuNSAwIDAgMSA4LjUgMmgzQTEuNSAxLjUgMCAwIDEgMTMgMy41VjVIN3pNNiAxNi4yNVY2aDh2MTAuMjVjMCAuMzM1LS4wNTkuNTU0LS4xMzguNjc1LS4wNTUuMDg1LS4xNC4xNTgtLjM2Mi4xNThoLTdjLS4yMjIgMC0uMzA3LS4wNzMtLjM2Mi0uMTU4LS4wOC0uMTIxLS4xMzgtLjM0LS4xMzgtLjY3NSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-disjoint-channel,.ag-charts-icon-disjoint-channel-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTkuMDI4IDE3LjQ2YTIuMjUgMi4yNSAwIDAgMC00LjA5Mi0xLjg1bC05LjUxMS0yLjM3OGEyLjI1IDIuMjUgMCAxIDAtLjIyNS45NzRsOS40NzUgMi4zNjlhMi4yNTEgMi4yNTEgMCAwIDAgNC4zNTMuODg2bS0xLjY2Mi0xLjk2NWExLjI1IDEuMjUgMCAxIDEtLjg4NSAyLjMzOCAxLjI1IDEuMjUgMCAwIDEgLjg4NS0yLjMzOE00LjM0MyAxMy42NjlhMS4yNSAxLjI1IDAgMSAwLTIuMzM4LS44ODUgMS4yNSAxLjI1IDAgMCAwIDIuMzM4Ljg4NU0zLjk3IDguNzY5YTIuMjUgMi4yNSAwIDAgMCAxLjQ1NS0yLjExbDkuNTExLTIuMzc4YTIuMjUgMi4yNSAwIDEgMC0uMjYtLjk2NUw1LjIgNS42ODVhMi4yNSAyLjI1IDAgMSAwLTEuMjMgMy4wODRtLjM3My0yLjU0N2ExLjI1IDEuMjUgMCAxIDEtMi4zMzguODg1IDEuMjUgMS4yNSAwIDAgMSAyLjMzOC0uODg1bTEzLjc1LTMuNDM4YTEuMjUgMS4yNSAwIDEgMS0yLjMzOC44ODUgMS4yNSAxLjI1IDAgMCAxIDIuMzM4LS44ODUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-drag-handle{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSI1Ljc1IiBjeT0iNy43NSIgcj0iLjc1IiBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41Ii8+PGNpcmNsZSBjeD0iOS43NSIgY3k9IjcuNzUiIHI9Ii43NSIgZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIvPjxjaXJjbGUgY3g9IjEzLjc1IiBjeT0iNy43NSIgcj0iLjc1IiBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41Ii8+PGNpcmNsZSBjeD0iMTMuNzUiIGN5PSIxMS43NSIgcj0iLjc1IiBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41Ii8+PGNpcmNsZSBjeD0iOS43NSIgY3k9IjExLjc1IiByPSIuNzUiIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjUiLz48Y2lyY2xlIGN4PSI1Ljc1IiBjeT0iMTEuNzUiIHI9Ii43NSIgZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIvPjwvc3ZnPg==)}.ag-charts-icon-fibonacci-retracement-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMiA1aDEydjFIMnoiLz48Y2lyY2xlIGN4PSIxNS43NSIgY3k9IjUuNSIgcj0iMS43NSIgc3Ryb2tlPSIjMDAwIi8+PGNpcmNsZSBjeD0iNC4yNSIgY3k9IjE0LjUiIHI9IjEuNzUiIHN0cm9rZT0iIzAwMCIvPjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0xOCAxNUg2di0xaDEyem0wLTQuNUgydi0xaDE2eiIvPjwvc3ZnPg==)}.ag-charts-icon-fibonacci-retracement-trend-based-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJtNC45OTYgMTIuNjc0IDMuMjkxLTUuNzQzLjg2OC40OTctMy4yOTEgNS43NDN6Ii8+PGNpcmNsZSBjeD0iOS43NSIgY3k9IjUuNSIgcj0iMS43NSIgc3Ryb2tlPSIjMDAwIi8+PGNpcmNsZSBjeD0iNC4zNTEiIGN5PSIxNC41IiByPSIxLjc1IiBzdHJva2U9IiMwMDAiLz48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTggNmgtN1Y1aDd6bTAgNC41aC03di0xaDd6bTAgNC41SDZ2LTFoMTJ6Ii8+PC9zdmc+)}.ag-charts-icon-fill-color{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtOC4wNzEgNC4wNi0uOTI0LS45MjQuNzA3LS43MDcgNy4yODggNy4yODgtNC45NSA0Ljk1YTMuNSAzLjUgMCAwIDEtNC45NSAwbC0xLjQxNC0xLjQxNGEzLjUgMy41IDAgMCAxIDAtNC45NXptLjcwNy43MDhMNC41MzYgOS4wMWEyLjUgMi41IDAgMCAwIDAgMy41MzZMNS45NSAxMy45NmEyLjUgMi41IDAgMCAwIDMuNTM1IDBsNC4yNDMtNC4yNDN6bTYuOSA3LjIwMi0uMzQ1LjM2My0uMzQ0LS4zNjNhLjUuNSAwIDAgMSAuNjg4IDBtLS4zNDUgMS4wOGE4IDggMCAwIDAtLjI4LjMyMyA0LjMgNC4zIDAgMCAwLS40MDkuNTgyYy0uMTEzLjIwMS0uMTQ0LjMyNi0uMTQ0LjM3OGEuODMzLjgzMyAwIDAgMCAxLjY2NyAwYzAtLjA1Mi0uMDMxLS4xNzctLjE0NC0uMzc4YTQuMyA0LjMgMCAwIDAtLjQxLS41ODIgOCA4IDAgMCAwLS4yOC0uMzIybS0uMzQ0LTEuMDguMzQ0LjM2My4zNDQtLjM2My4wMDIuMDAyLjAwNC4wMDQuMDEzLjAxMmE2IDYgMCAwIDEgLjIwNi4yMDhjLjEzMS4xMzYuMzA4LjMyNy40ODUuNTQ1LjE3Ni4yMTUuMzYzLjQ2Ny41MDcuNzI0LjEzNy4yNDMuMjczLjU1My4yNzMuODY4YTEuODMzIDEuODMzIDAgMSAxLTMuNjY3IDBjMC0uMzE1LjEzNi0uNjI1LjI3My0uODY4LjE0NC0uMjU3LjMzLS41MDkuNTA3LS43MjRhOSA5IDAgMCAxIC42NDUtLjcwOGwuMDQ2LS4wNDUuMDEzLS4wMTIuMDA0LS4wMDR6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-hollow-candlestick-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1vcGFjaXR5PSIuMTUiIGQ9Ik01IDVoM3YxMEg1eiIvPjxwYXRoIGZpbGw9IiMxMzE3MjIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTcgMXYzaDJ2MTJIN3YzSDZ2LTNINFY0aDJWMXpNNSA1aDN2MTBINXptNyAyaDN2NmgtM3ptLTEgN1Y2aDJWMy4yNWgxVjZoMnY4aC0ydjIuNzVoLTFWMTR6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-horizontal-line,.ag-charts-icon-horizontal-line-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNLjUgOS41aDcuMzA2YTIuMjUgMi4yNSAwIDAgMSA0LjM4OCAwSDE5LjV2MWgtNy4zMDZhMi4yNSAyLjI1IDAgMCAxLTQuMzg4IDBILjV6bTkuNSAxLjc1YTEuMjUgMS4yNSAwIDEgMCAwLTIuNSAxLjI1IDEuMjUgMCAwIDAgMCAyLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-line-color{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQuMjQyIDIuNzIyYy0uNjEyIDAtMS4yLjI0My0xLjYzMi42NzVsLTEuMzQzIDEuMzQ0YS41LjUgMCAwIDAtLjExMi4xMTJMNC4wNSAxMS45NTljLS4yMDcuMjA3LS4zNi40Ni0uNDQ2Ljc0di4wMDFsLS42OSAyLjc2N3YuMDAyYS44Mi44MiAwIDAgMCAxLjAyMiAxLjAyMWguMDAybDIuNjM0LS44MjJjLjI4LS4wODUuNTM0LS4yMzcuNzQtLjQ0M2w3LjEwNy03LjEwOGEuNS41IDAgMCAwIC4xMTItLjExMmwxLjM0My0xLjM0M2EyLjMwOCAyLjMwOCAwIDAgMC0xLjYzMi0zLjk0TTE0LjEyMiA3bDEuMDQ0LTEuMDQ1YTEuMzA4IDEuMzA4IDAgMSAwLTEuODQ5LTEuODVMMTIuMjcxIDUuMTV6bS0yLjU1OC0xLjE0Mi02LjgwNyA2LjgwOWEuOC44IDAgMCAwLS4xOTYuMzI1bC0uNzUgMi40NjggMi40Ny0uNzQ5YS44LjggMCAwIDAgLjMyNS0uMTk0bDYuODA4LTYuODF6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-line-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMTcuMzYyIDQuODczLTQuNTk0IDYuNjU0LTQuODUtMy4zMTctNC4yNTEgNi45NzctLjg1NC0uNTJMNy42MTIgNi43OWw0Ljg5OSAzLjM1IDQuMDI4LTUuODM2eiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-line-style-dashed{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMiA5aDR2MUgyem0xMiAwaDR2MWgtNHpNOCA5aDR2MUg4eiIvPjwvc3ZnPg==)}.ag-charts-icon-line-style-dotted{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIyLjUiIGN5PSI5LjUiIHI9Ii41IiBmaWxsPSIjMDAwIi8+PGNpcmNsZSBjeD0iNC41IiBjeT0iOS41IiByPSIuNSIgZmlsbD0iIzAwMCIvPjxjaXJjbGUgY3g9IjYuNSIgY3k9IjkuNSIgcj0iLjUiIGZpbGw9IiMwMDAiLz48Y2lyY2xlIGN4PSI4LjUiIGN5PSI5LjUiIHI9Ii41IiBmaWxsPSIjMDAwIi8+PGNpcmNsZSBjeD0iMTAuNSIgY3k9IjkuNSIgcj0iLjUiIGZpbGw9IiMwMDAiLz48Y2lyY2xlIGN4PSIxMi41IiBjeT0iOS41IiByPSIuNSIgZmlsbD0iIzAwMCIvPjxjaXJjbGUgY3g9IjE0LjUiIGN5PSI5LjUiIHI9Ii41IiBmaWxsPSIjMDAwIi8+PGNpcmNsZSBjeD0iMTYuNSIgY3k9IjkuNSIgcj0iLjUiIGZpbGw9IiMwMDAiLz48L3N2Zz4=)}.ag-charts-icon-line-style-solid{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMiA5aDE2djFIMnoiLz48L3N2Zz4=)}.ag-charts-icon-line-with-markers-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMTguMTk4IDQuODg4LTMuNTU2IDQuOTE4YTIuMjUgMi4yNSAwIDEgMS0zLjg2Ni43NWwtMS40MzItLjlhMi4yNCAyLjI0IDAgMCAxLTIuMDA5LjQzNWwtMy44MjggNi40MjgtLjg2LS41MTJMNi40NSA5LjYyM2EyLjI1IDIuMjUgMCAxIDEgMy41MS0uNzYxbDEuMzI5LjgzNWEyLjI0IDIuMjQgMCAwIDEgMi41NTctLjQ5N2wzLjU0Mi00Ljg5OHptLTQuOTYgNS4xNTNhMS4yNSAxLjI1IDAgMSAwLS42NCAyLjQxOSAxLjI1IDEuMjUgMCAwIDAgLjY0LTIuNDE5TTkuMSA4LjMyMXEuMDY2LS4xOTIuMDY3LS40MDRhMS4yNSAxLjI1IDAgMSAwLS4wNjcuNDA0IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-lock,.ag-charts-icon-locked{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAuMjA3IDMuNzY0YTIuODk0IDIuODk0IDAgMCAwLTIuODk1IDIuODk0VjloNS43ODlWNi42NThhMi44OTQgMi44OTQgMCAwIDAtMi44OTUtMi44OTRNMTQuMSA5VjYuNjU4YTMuODk0IDMuODk0IDAgMSAwLTcuNzg5IDB2Mi4zNDlBMi41IDIuNSAwIDAgMCA0IDExLjV2M0EyLjUgMi41IDAgMCAwIDYuNSAxN2g4YTIuNSAyLjUgMCAwIDAgMi41LTIuNXYtM0EyLjUgMi41IDAgMCAwIDE0LjUgOXpNNi41IDEwQTEuNSAxLjUgMCAwIDAgNSAxMS41djNBMS41IDEuNSAwIDAgMCA2LjUgMTZoOGExLjUgMS41IDAgMCAwIDEuNS0xLjV2LTNhMS41IDEuNSAwIDAgMC0xLjUtMS41eiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-measurer-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTQuNDYxIDEyLjcxIDEuNTMyLTEuNTMxIDEuNDE0IDEuNDE0LjcwNy0uNzA3TDYuNyAxMC40NzJsMS41MzItMS41MzMgMiAyIC43MDctLjcwNy0yLTIgNi4wMS02LjAxIDIuODMgMi44MjhMNS4wNSAxNy43NzggMi4yMjIgMTQuOTVsMS41MzItMS41MzIgMS40MTQgMS40MTQuNzA3LS43MDd6TS44MDggMTQuOTVsLjcwNy0uNzA3TDE0LjI0MyAxLjUxNWwuNzA3LS43MDcuNzA3LjcwNyAyLjgyOCAyLjgyOC43MDcuNzA3LS43MDcuNzA3TDUuNzU3IDE4LjQ4NWwtLjcwNy43MDctLjcwNy0uNzA3LTIuODI4LTIuODI4em0xMS4wNzgtNi44MzVMMTAuNDcgNi43bC43MDctLjcwNyAxLjQxNSAxLjQxNHptLjgyNC0zLjY1NCAxIDEgLjcwOC0uNzA3LTEtMXoiIGZpbGw9IiMxODFEMUYiLz48L3N2Zz4=)}.ag-charts-icon-note-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMyA0LjVBMS41IDEuNSAwIDAgMSA0LjUgM2gxMUExLjUgMS41IDAgMCAxIDE3IDQuNXY4YTEuNSAxLjUgMCAwIDEtMS41IDEuNWgtMy4yMWwtMS40NjkgMi41N2ExIDEgMCAwIDEtMS42ODIuMDg1TDcuMjQzIDE0SDQuNUExLjUgMS41IDAgMCAxIDMgMTIuNXpNNC41IDRhLjUuNSAwIDAgMC0uNS41djhhLjUuNSAwIDAgMCAuNS41aDMuMjU3bDIuMTk2IDMuMDc0TDExLjcxIDEzaDMuNzlhLjUuNSAwIDAgMCAuNS0uNXYtOGEuNS41IDAgMCAwLS41LS41eiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNi41IDYuNUEuNS41IDAgMCAxIDcgNmg2YS41LjUgMCAwIDEgMCAxSDdhLjUuNSAwIDAgMS0uNS0uNU02LjUgOS41QS41LjUgMCAwIDEgNyA5aDZhLjUuNSAwIDAgMSAwIDFIN2EuNS41IDAgMCAxLS41LS41IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-ohlc-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZD0iTTEzIDExaC0zdi0xaDNWM2gxdjJoNHYxaC00djExaC0xek02IDE3di0yaDN2LTFINlY0SDV2MUgydjFoM3YxMXoiLz48L3N2Zz4=)}.ag-charts-icon-pan-end{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0ibTYuNjQ2IDEzLjgxMy0uMzUzLjM1NC43MDcuNzA3LjM1NC0uMzU0ek0xMS4xNjYgMTBsLjM1NC4zNTQuMzU0LS4zNTQtLjM1NC0uMzU0ek03LjM1NSA1LjQ4IDcgNS4xMjZsLS43MDcuNzA3LjM1My4zNTR6bTAgOS4wNCA0LjE2Ni00LjE2Ni0uNzA3LS43MDgtNC4xNjcgNC4xNjd6bTQuMTY2LTQuODc0TDcuMzU0IDUuNDhsLS43MDguNzA3IDQuMTY3IDQuMTY3ek0xMy4wODMgNXYxMGgxVjV6Ii8+PC9zdmc+)}.ag-charts-icon-pan-left{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTIuNzkgNS44MzMgOC42MjUgMTBsNC4xNjYgNC4xNjctLjcwNy43MDdMNy4yMSAxMGw0Ljg3My00Ljg3NHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-pan-right{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNy4yMSAxNC4xNjcgMTEuMzc2IDEwIDcuMjEgNS44MzNsLjcwNy0uNzA3TDEyLjc5IDEwbC00Ljg3MyA0Ljg3NHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-pan-start{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTYgNXYxMGgxVjV6TTkuNjI0IDEwbDQuMTY2LTQuMTY3LS43MDctLjcwN0w4LjIxIDEwbDQuODc0IDQuODc0LjcwNy0uNzA3eiIvPjwvc3ZnPg==)}.ag-charts-icon-parallel-channel,.ag-charts-icon-parallel-channel-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTcuNzIgNS4zMzFBMi4yNSAyLjI1IDAgMSAwIDE0LjcwNSAzLjZsLTkuNDkgNC41NjJhMi4yNSAyLjI1IDAgMSAwIC4yMDkgMS4wMWw5LjY2Mi00LjY0NmEyLjI1IDIuMjUgMCAwIDAgMi42MzQuODA1bS4zNzMtMi41NDdhMS4yNSAxLjI1IDAgMSAxLTIuMzM4Ljg4NSAxLjI1IDEuMjUgMCAwIDEgMi4zMzgtLjg4NU00LjM0MyA4LjY3YTEuMjUgMS4yNSAwIDEgMS0yLjMzOC44ODUgMS4yNSAxLjI1IDAgMCAxIDIuMzM4LS44ODVNNS4zMDcgMTYuNzI4YTIuMjUgMi4yNSAwIDEgMS0uNTI1LS44NThsOS45MjMtNC43N2EyLjI1IDIuMjUgMCAxIDEgLjM4MS45MjZ6bS0uOTY0LjI3NGExLjI1IDEuMjUgMCAxIDEtMi4zMzguODg1IDEuMjUgMS4yNSAwIDAgMSAyLjMzOC0uODg1bTEzLjAyMy01LjEwNmExLjI1IDEuMjUgMCAxIDAtLjg4NS0yLjMzOSAxLjI1IDEuMjUgMCAwIDAgLjg4NSAyLjMzOSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-position-bottom{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii4yNSIgZD0iTTMgMTBoMTR2MUgzem0zLTNoOHYxSDZ6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTYgMTNoOHYxSDZ6Ii8+PC9zdmc+)}.ag-charts-icon-position-center{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMyAxMGgxNHYxSDN6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuMjUiIGQ9Ik02IDdoOHYxSDZ6bTAgNmg4djFINnoiLz48L3N2Zz4=)}.ag-charts-icon-position-top{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii4yNSIgZD0iTTMgMTBoMTR2MUgzeiIvPjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik02IDdoOHYxSDZ6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuMjUiIGQ9Ik02IDEzaDh2MUg2eiIvPjwvc3ZnPg==)}.ag-charts-icon-price-label-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNC41IDNBMS41IDEuNSAwIDAgMCAzIDQuNVYxM2ExLjUgMS41IDAgMCAwIDEuNSAxLjVoLjgzM3YuMDU3Yy4yNDItLjI5OS41OTctLjUwMyAxLS41NDhWMTMuNUg0LjVBLjUuNSAwIDAgMSA0IDEzVjQuNWEuNS41IDAgMCAxIC41LS41aDExYS41LjUgMCAwIDEgLjUuNXY4YS41LjUgMCAwIDEtLjUuNWgtNC44MThsLS4xMjYuMDg0YTI2IDI2IDAgMCAwLTIuMjI1IDEuNjg1bC0uMzIuMjY1LS4wNjguMDU2YTEuNSAxLjUgMCAwIDEtMi42MDkgMS4zNTRjLjAzMy43NjMuOTA1IDEuMjM4IDEuNTYuNzU2LjY0Ni0uNDc0IDEuMjEtLjk0MyAxLjc2MS0xLjRsLjMxMy0uMjZBMjYgMjYgMCAwIDEgMTAuOTg2IDE0SDE1LjVhMS41IDEuNSAwIDAgMCAxLjUtMS41di04QTEuNSAxLjUgMCAwIDAgMTUuNSAzeiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOC43MTYgMTQuODE1YTIuMjUgMi4yNSAwIDEgMS00LjIxIDEuNTkzIDIuMjUgMi4yNSAwIDAgMSA0LjIxLTEuNTkzbS0xLjY2MiAxLjk2NmExLjI1IDEuMjUgMCAxIDAtLjg4NS0yLjMzOSAxLjI1IDEuMjUgMCAwIDAgLjg4NSAyLjMzOSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-price-range-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOS4wNDYgMTVWNS44NzdoLjk0MlYxNXoiIGZpbGw9IiMxODFEMUYiLz48cGF0aCBkPSJNOS4wNDYgMTVWNS44NzdoLjk0MlYxNXoiIGZpbGw9IiMxODFEMUYiLz48cGF0aCBkPSJNOS41IDYuMjI4IDcuMTY3IDguMzc2IDYuNSA3Ljc2MiA5LjUgNWwzIDIuNzYyLS42NjcuNjE0eiIgZmlsbD0iIzAwMCIvPjxwYXRoIGQ9Ik0yIDE4di0xaDE2djF6TTIgM1YyaDE2djF6IiBmaWxsPSIjMTgxRDFGIi8+PC9zdmc+)}.ag-charts-icon-reset{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTIuMDQgNC40NDVhNS44MSA1LjgxIDAgMCAwLTcuMjU3IDIuNDUzLjUuNSAwIDAgMS0uODY1LS41MDJBNi44MSA2LjgxIDAgMSAxIDMgOS44MTNhLjUuNSAwIDAgMSAxIDAgNS44MSA1LjgxIDAgMSAwIDguMDQtNS4zNjgiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQuMjg5IDMuMDAyYS41LjUgMCAwIDEgLjUuNXYyLjY1NWgyLjY1NWEuNS41IDAgMCAxIDAgMUg0LjI5YS41LjUgMCAwIDEtLjUtLjVWMy41MDJhLjUuNSAwIDAgMSAuNS0uNSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-settings{--icon: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkIj48cGF0aCBkPSJNMTAgMTNhMyAzIDAgMSAwIDAtNiAzIDMgMCAwIDAgMCA2bTAtMWEyIDIgMCAxIDEtLjAwMS0zLjk5OUEyIDIgMCAwIDEgMTAgMTIiLz48cGF0aCBkPSJNMi4zMSAxNC4zNDVjLS44MTctMS40OTEuMDI3LTIuNDk5LjQ3NC0yLjg2NS41MzEtLjQzNC45NjktLjM2NS45NzItMS40OC0uMDAzLTEuMTE1LS40NDEtMS4wNDYtLjk3Mi0xLjQ4MS0uNDU0LS4zNzEtMS4zMTctMS40MDUtLjQzNC0yLjkzNmwuMDA1LS4wMDljLjg4NC0xLjUyIDIuMjA3LTEuMjkgMi43NTUtMS4wODMuNjQxLjI0My44MDEuNjU2IDEuNzY4LjEwMS45NjQtLjU2LjY4Ni0uOTA0Ljc5Ni0xLjU4Mi4wOTQtLjU3OC41NTktMS44NDMgMi4zMjYtMS44NDNoLjAxYzEuNzU5LjAwNSAyLjIyMiAxLjI2NiAyLjMxNiAxLjg0My4xMS42NzgtLjE2OCAxLjAyMi43OTYgMS41ODIuOTY3LjU1NSAxLjEyNy4xNDIgMS43NjgtLjEwMS41NDktLjIwOCAxLjg3Ni0uNDM4IDIuNzYgMS4wOTJzLjAyIDIuNTY1LS40MzQgMi45MzZjLS41MzEuNDM1LS45NjkuMzY2LS45NzIgMS40ODEuMDAzIDEuMTE1LjQ0MSAxLjA0Ni45NzIgMS40OC40NTQuMzcyIDEuMzE3IDEuNDA2LjQzNCAyLjkzN2wtLjAwNS4wMDljLS44ODQgMS41Mi0yLjIwNyAxLjI5LTIuNzU1IDEuMDgzLS42NDEtLjI0My0uODAxLS42NTYtMS43NjgtLjEwMS0uOTY0LjU2LS42ODYuOTA0LS43OTYgMS41ODEtLjA5NC41NzktLjU1OSAxLjg0NC0yLjMyNiAxLjg0NGgtLjAxYy0xLjc1OS0uMDA1LTIuMjIyLTEuMjY2LTIuMzE2LTEuODQ0LS4xMS0uNjc3LjE2OC0xLjAyMS0uNzk2LTEuNTgxLS45NjctLjU1NS0xLjEyNy0uMTQyLTEuNzY4LjEwMS0uNTQ5LjIwOC0xLjg3Ni40MzgtMi43Ni0xLjA5MmwtLjAyLS4wMzZ6TTkuOTg0IDIuMTYySDEwYzEuMzU1IDAgMS4zNDIgMS4wMzkgMS4zNTMgMS40MjUuMDA4LjMxMi4wNCAxLjE2IDEuMjU5IDEuODcybC4wMTUuMDA4YzEuMjI1LjcgMS45NzYuMzA0IDIuMjUxLjE1NS4zMzctLjE4MyAxLjIyNi0uNzExIDEuOTAyLjQ0NWwuMDA4LjAxNGMuNjc4IDEuMTczLS4yMjkgMS42ODItLjU1OCAxLjg4NC0uMjY2LjE2My0uOTg0LjYxNS0uOTkxIDIuMDI3di4wMTZjLjAwNyAxLjQxMi43MjUgMS44NjQuOTkxIDIuMDI3LjMyOC4yMDEgMS4yMjkuNzA3LjU2NiAxLjg3bC0uMDA4LjAxNGMtLjY3NyAxLjE3NC0xLjU3MS42NDMtMS45MS40NTktLjI3NS0uMTQ5LTEuMDI2LS41NDUtMi4yNTEuMTU0bC0uMDE1LjAwOWMtMS4yMTkuNzEyLTEuMjUxIDEuNTYtMS4yNTkgMS44NzItLjAxMS4zODYuMDAyIDEuNDI1LTEuMzUzIDEuNDI1cy0xLjM0Mi0xLjAzOS0xLjM1My0xLjQyNWMtLjAwOC0uMzEyLS4wNC0xLjE2LTEuMjU5LTEuODcybC0uMDE1LS4wMDljLTEuMjI1LS42OTktMS45NzYtLjMwMy0yLjI1MS0uMTU0LS4zMzYuMTgzLTEuMjE5LjcwNi0xLjg5NC0uNDMybC0uMDE2LS4wMjdjLS42NzgtMS4xNzQuMjI5LTEuNjgyLjU1OC0xLjg4NC4yNjYtLjE2My45ODQtLjYxNS45OTEtMi4wMjd2LS4wMTZjLS4wMDctMS40MTItLjcyNS0xLjg2NC0uOTkxLTIuMDI3LS4zMjgtLjIwMS0xLjIyOS0uNzA3LS41NjYtMS44N2wuMDA4LS4wMTRjLjY3Ny0xLjE3NCAxLjU3MS0uNjQzIDEuOTEtLjQ1OS4yNzUuMTQ5IDEuMDI2LjU0NSAyLjI1MS0uMTU1bC4wMTUtLjAwOGMxLjIxOS0uNzEyIDEuMjUxLTEuNTYgMS4yNTktMS44NzIuMDEtLjM4NC0uMDAyLTEuNDE3IDEuMzM3LTEuNDI1Ii8+PC9zdmc+)}.ag-charts-icon-step-line-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzE4MUQxRiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiA0aDV2OGgzVjhoNXYxaC00djRoLTVWNUg3djEwSDJ2LTFoNHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-text-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00IDRIMTZWN0gxNVY1SDEwLjVWMTVIMTRWMTZINlYxNUg5LjVWNUg1VjdINFY0WiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+Cg==)}.ag-charts-icon-trend-line,.ag-charts-icon-trend-line-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS4zMTQgMTAuOTM4YTIuMjUgMi4yNSAwIDEgMSAuMDEtMWg5LjM1MmEyLjI1IDIuMjUgMCAxIDEgLjAxIDF6bS0yLjE4OS43MjlhMS4yNSAxLjI1IDAgMSAwIDAtMi41IDEuMjUgMS4yNSAwIDAgMCAwIDIuNW0xMy43NSAwYTEuMjUgMS4yNSAwIDEgMCAwLTIuNSAxLjI1IDEuMjUgMCAwIDAgMCAyLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-unlock,.ag-charts-icon-unlocked{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAuNjUxIDMuNWEyLjg5NCAyLjg5NCAwIDAgMC0yLjg5NCAyLjg5NFY5SDE0LjVhMi41IDIuNSAwIDAgMSAyLjUgMi41djNhMi41IDIuNSAwIDAgMS0yLjUgMi41aC04QTIuNSAyLjUgMCAwIDEgNCAxNC41di0zQTIuNSAyLjUgMCAwIDEgNi41IDloLjI1N1Y2LjM5NGEzLjg5NCAzLjg5NCAwIDEgMSA3Ljc4OSAwIC41LjUgMCAwIDEtMSAwQTIuODk0IDIuODk0IDAgMCAwIDEwLjY1IDMuNU02LjUgMTBBMS41IDEuNSAwIDAgMCA1IDExLjV2M0ExLjUgMS41IDAgMCAwIDYuNSAxNmg4YTEuNSAxLjUgMCAwIDAgMS41LTEuNXYtM2ExLjUgMS41IDAgMCAwLTEuNS0xLjV6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-vertical-line,.ag-charts-icon-vertical-line-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAuNSA3LjgwNmEyLjI1IDIuMjUgMCAwIDEgMCA0LjM4OFYxOS41aC0xdi03LjMwNmEyLjI1IDIuMjUgMCAwIDEgMC00LjM4OFYuNWgxem0tLjUuOTQ0YTEuMjUgMS4yNSAwIDEgMSAwIDIuNSAxLjI1IDEuMjUgMCAwIDEgMC0yLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-zoom-in{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTEwIDUuNWEuNS41IDAgMCAxIC41LjV2My41aDMuODc1YS41LjUgMCAwIDEgMCAxSDEwLjV2NC4yNWEuNS41IDAgMSAxLTEgMFYxMC41SDUuNjI1YS41LjUgMCAxIDEgMC0xSDkuNVY2YS41LjUgMCAwIDEgLjUtLjUiLz48L3N2Zz4=)}.ag-charts-icon-zoom-out{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS41IDEwYS41LjUgMCAwIDEgLjUtLjVoOGEuNS41IDAgMCAxIDAgMUg2YS41LjUgMCAwIDEtLjUtLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-high-low-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNyA0aDJ2MTJINFY0aDNNNSA1aDN2MTBINXpNMTEgMTRWNmg1djhoLTVtMS03aDN2NmgtM3oiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-hlc-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMTguMTYzIDEuODM3LTUuMzM0IDExLjYyMUw2Ljk1NyA4LjEybC00LjE5OSA5LjYyMi0uOTE2LS40IDQuNzU2LTEwLjlMMTIuNDkgMTEuOCAxNy4yNTQgMS40MnoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuODI1IDIuNzA0LjU1IDEzLjc4NWwuOTAyLjQzIDQuNzI0LTkuOTE5IDYuMDM0IDUuMDI5IDMuMjU1LTguMTQtLjkyOC0uMzctMi43NDUgNi44NnptNy44NTIgMTQuNjM2IDUuNzgtMTMuMTM5LS45MTUtLjQwMi01LjIxOSAxMS44Ni02LjAwNS01LjUwNC0zLjI3OCA3LjY0OC45Mi4zOTQgMi43MjItNi4zNTJ6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-zoom-in-alt{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXpvb20taW4iPjxjaXJjbGUgY3g9IjExIiBjeT0iMTEiIHI9IjgiLz48bGluZSB4MT0iMjEiIHgyPSIxNi42NSIgeTE9IjIxIiB5Mj0iMTYuNjUiLz48bGluZSB4MT0iMTEiIHgyPSIxMSIgeTE9IjgiIHkyPSIxNCIvPjxsaW5lIHgxPSI4IiB4Mj0iMTQiIHkxPSIxMSIgeTI9IjExIi8+PC9zdmc+)}.ag-charts-icon-zoom-out-alt{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXpvb20tb3V0Ij48Y2lyY2xlIGN4PSIxMSIgY3k9IjExIiByPSI4Ii8+PGxpbmUgeDE9IjIxIiB4Mj0iMTYuNjUiIHkxPSIyMSIgeTI9IjE2LjY1Ii8+PGxpbmUgeDE9IjgiIHgyPSIxNCIgeTE9IjExIiB5Mj0iMTEiLz48L3N2Zz4=)}.ag-charts-input{--input-layer-active: 1;--input-layer-focus: 2;--input-padding: calc(var(--ag-charts-spacing) * 2);--input-padding-large: calc(var(--ag-charts-spacing) * 2.5);color:var(--ag-charts-input-text-color);font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size-large);transition-duration:.25s;transition-property:none;transition-timing-function:ease-out}.ag-charts-input:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:var(--input-layer-focus)}.ag-charts-button{background:var(--ag-charts-button-background-color);border:1px solid var(--ag-charts-border-color);border-radius:var(--ag-charts-button-border-radius);color:var(--ag-charts-button-text-color);cursor:pointer;padding:var(--input-padding);transition-property:background,border-color}.ag-charts-button:hover{background:var(--ag-charts-focus-color)}.ag-charts-button:has(.ag-charts-icon){padding:2px}.ag-charts-checkbox{--checkbox-transition-duration: .1s;appearance:none;background:var(--ag-charts-checkbox-background-color);border-radius:calc(var(--ag-charts-border-radius) * 9);cursor:pointer;height:18px;margin:0;transition-duration:var(--checkbox-transition-duration);transition-property:margin;width:29px}.ag-charts-checkbox:before{display:block;background:var(--ag-charts-input-background-color);border-radius:calc(var(--ag-charts-border-radius) * 7);content:" ";height:14px;margin:2px;transition-duration:var(--checkbox-transition-duration);transition-property:margin;transition-timing-function:var(--ag-charts-input-transition-easing);width:14px}.ag-charts-checkbox:checked{background:var(--ag-charts-checkbox-checked-background-color)}.ag-charts-checkbox:checked:before{margin-left:13px}.ag-charts-select{background:var(--ag-charts-input-background-color);border:1px solid var(--ag-charts-input-border-color);border-radius:var(--ag-charts-input-border-radius);padding:3px 2px 4px;font-size:inherit}.ag-charts-textarea{--textarea-line-height: 1.38;background:var(--ag-charts-input-background-color);border:1px solid var(--ag-charts-border-color);border-radius:var(--ag-charts-input-border-radius);line-height:var(--textarea-line-height);font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size-large);padding:var(--input-padding-large) var(--input-padding)}.ag-charts-textarea::placeholder{color:var(--ag-charts-input-placeholder-text-color)}.ag-charts-proxy-container{pointer-events:none;position:absolute}.ag-charts-proxy-elem{-webkit-appearance:none;appearance:none;background:none;border:none;color:#0000;overflow:hidden;pointer-events:auto;position:absolute}.ag-charts-proxy-elem::-moz-range-thumb,.ag-charts-proxy-elem::-moz-range-track{opacity:0}.ag-charts-proxy-elem::-webkit-slider-runnable-track,.ag-charts-proxy-elem::-webkit-slider-thumb{opacity:0}.ag-charts-proxy-elem:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow)}.ag-charts-focus-indicator{position:absolute;display:block;pointer-events:none;user-select:none;-webkit-user-select:none;width:100%;height:100%}.ag-charts-focus-indicator>div{position:absolute;outline:solid 1px var(--ag-charts-chrome-background-color);box-shadow:var(--ag-charts-focus-shadow)}.ag-charts-focus-indicator>svg{width:100%;height:100%;fill:none;overflow:visible}.ag-charts-focus-svg-outer-path{stroke:var(--ag-charts-chrome-background-color);stroke-width:4px}.ag-charts-focus-svg-inner-path{stroke:var(--ag-charts-accent-color);stroke-width:2px}.ag-charts-overlay{color:#181d1f;pointer-events:none}.ag-charts-overlay.ag-charts-dark-overlay{color:#fff}.ag-charts-overlay--loading{color:#8c8c8c}.ag-charts-overlay__loading-background{background:#fff;pointer-events:none}.ag-charts-overlay.ag-charts-dark-overlay .ag-charts-overlay__loading-background{background:#192232}.ag-charts-tooltip{--tooltip-arrow-size: 8px;position:fixed;inset:unset;margin:0;padding:0;overflow:visible;width:max-content;max-width:100%;font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size);font-weight:var(--ag-charts-chrome-font-weight);color:var(--ag-charts-chrome-text-color);background:var(--ag-charts-chrome-background-color);border:var(--ag-charts-border);border-radius:var(--ag-charts-border-radius);box-shadow:var(--ag-charts-shadow)}.ag-charts-tooltip--compact .ag-charts-tooltip-content{padding:3px 6px}.ag-charts-tooltip--arrow:before{content:"";position:absolute;top:100%;left:50%;margin:0 auto;transform:translate(-50%) translateY(calc(var(--tooltip-arrow-size) * -.5)) rotate(45deg);display:block;width:var(--tooltip-arrow-size);height:var(--tooltip-arrow-size);border:inherit;border-top:none;border-left:none;clip-path:polygon(0% 100%,100% 0%,100% 100%)}.ag-charts-tooltip--arrow:after{--tooltip-inner-size: calc(var(--tooltip-arrow-size) - 2px);content:"";position:absolute;top:100%;left:50%;margin:0 auto;transform:translate(-50%) translateY(calc(var(--tooltip-inner-size) * -.5)) rotate(45deg);display:block;width:var(--tooltip-inner-size);height:var(--tooltip-inner-size);border:inherit;border-color:transparent;background:inherit;clip-path:polygon(-10% 100%,100% -10%,100% 100%)}.ag-charts-tooltip--no-interaction{pointer-events:none;user-select:none;-webkit-user-select:none}.ag-charts-tooltip--wrap-always{overflow-wrap:break-word;word-break:break-word;hyphens:none}.ag-charts-tooltip--wrap-hyphenate{overflow-wrap:break-word;word-break:break-word;hyphens:auto}.ag-charts-tooltip--wrap-on-space{overflow-wrap:normal;word-break:normal}.ag-charts-tooltip--wrap-never{white-space:nowrap}.ag-charts-tooltip-heading,.ag-charts-tooltip-title,.ag-charts-tooltip-label,.ag-charts-tooltip-value{overflow:hidden;text-overflow:ellipsis}.ag-charts-tooltip-content{display:grid;grid:auto-flow minmax(1em,auto) / 1fr;padding:8px 12px;gap:8px}.ag-charts-tooltip-content:has(.ag-charts-tooltip-symbol){grid:auto-flow minmax(1em,auto) / auto 1fr}.ag-charts-tooltip-heading{grid-column:1 / -1}.ag-charts-tooltip-symbol{grid-column:1 / 2;align-self:center}.ag-charts-tooltip-symbol svg{display:block}.ag-charts-tooltip-title{grid-column:-2 / -1}.ag-charts-tooltip-row{grid-column:1 / -1;display:flex;gap:16px;align-items:baseline;justify-content:space-between;overflow:hidden}.ag-charts-tooltip-row--inline{grid-column:-2 / -1}.ag-charts-tooltip-label{flex:1;min-width:0}.ag-charts-tooltip-value{min-width:0}.ag-charts-popover{position:absolute;border:var(--ag-charts-border);border-radius:var(--ag-charts-border-radius);background:var(--ag-charts-chrome-background-color);color:var(--ag-charts-chrome-text-color);font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size);font-weight:var(--ag-charts-chrome-font-weight);box-shadow:var(--ag-charts-shadow);z-index:var(--ag-charts-layer-ui-overlay)}.ag-charts-menu{--item-padding: 6px 12px;--icon-color: var(--ag-charts-chrome-text-color);display:grid;grid:auto-flow auto / 1fr;column-gap:12px;font-size:var(--ag-charts-chrome-font-size)}.ag-charts-menu:has(.ag-charts-menu__icon,.ag-charts-menu__row--stroke-width-visible){grid:auto-flow auto / auto 1fr}.ag-charts-menu__row--stroke-width-visible:before{content:"";height:var(--strokeWidth);width:12px;background:var(--icon-color)}.ag-charts-menu__row--stroke-width-visible[aria-disabled=true]:before{filter:grayscale(1);opacity:.5}.ag-charts-menu__row{display:grid;grid-column:1 / -1;grid-template-columns:subgrid;align-items:center;padding:var(--item-padding)}.ag-charts-menu__row:not(.ag-charts-menu__row--active){cursor:pointer}.ag-charts-menu__row:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.ag-charts-menu__row:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.ag-charts-menu__row:focus{background:var(--ag-charts-focus-color)}.ag-charts-menu__row:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:var(--ag-charts-layer-menu)}.ag-charts-menu__row--active{--icon-color: var(--ag-charts-accent-color);background:var(--ag-charts-focus-color);color:var(--ag-charts-accent-color)}.ag-charts-menu__label{grid-column:-1 / span 1}.ag-charts-toolbar{--toolbar-gap: calc(var(--ag-charts-spacing) * 2);--toolbar-size: 34px;--toolbar-button-padding: 6px;align-items:center;display:flex;flex-wrap:nowrap;position:absolute}.ag-charts-toolbar__button{align-items:center;background:var(--ag-charts-chrome-background-color);border:var(--ag-charts-border);color:var(--ag-charts-chrome-text-color);cursor:pointer;display:flex;font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size-medium);font-weight:var(--ag-charts-chrome-font-weight);justify-content:center;min-height:var(--toolbar-size);min-width:var(--toolbar-size);padding:var(--toolbar-button-padding);position:relative;transition:background-color .25s ease-in-out,border-color .25s ease-in-out,color .25s ease-in-out;white-space:nowrap}.ag-charts-toolbar__button:hover{background:var(--ag-charts-focus-color);z-index:1}.ag-charts-toolbar__button:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:calc(var(--ag-charts-layer-ui-overlay) + 1)}.ag-charts-toolbar__button--active{background:var(--ag-charts-focus-color);border-color:var(--ag-charts-accent-color);color:var(--ag-charts-accent-color);z-index:2}.ag-charts-toolbar__button[aria-disabled=true]{background:var(--ag-charts-button-disabled-background-color);color:var(--ag-charts-button-disabled-text-color);cursor:default}.ag-charts-toolbar--horizontal{flex-direction:row;.ag-charts-toolbar__button{margin:0 0 0 -1px}.ag-charts-toolbar__button--first{border-bottom-left-radius:var(--ag-charts-border-radius);border-top-left-radius:var(--ag-charts-border-radius);margin:0}.ag-charts-toolbar__button--last{border-bottom-right-radius:var(--ag-charts-border-radius);border-top-right-radius:var(--ag-charts-border-radius)}}.ag-charts-toolbar--vertical{flex-direction:column;.ag-charts-toolbar__button{margin:-1px 0 0;max-width:100%}.ag-charts-toolbar__button--first{border-top-left-radius:var(--ag-charts-border-radius);border-top-right-radius:var(--ag-charts-border-radius);margin:0}.ag-charts-toolbar__button--last{border-bottom-left-radius:var(--ag-charts-border-radius);border-bottom-right-radius:var(--ag-charts-border-radius)}}.ag-charts-toolbar__icon+.ag-charts-toolbar__label{margin-left:var(--toolbar-gap)}.ag-charts-toolbar__icon,.ag-charts-toolbar__label{pointer-events:none}.ag-charts-floating-toolbar{border:none;display:flex;.ag-charts-toolbar{align-items:unset;position:unset}}.ag-charts-floating-toolbar__drag-handle{align-items:center;background:var(--ag-charts-chrome-background-color);border:var(--ag-charts-border);border-bottom-left-radius:var(--ag-charts-border-radius);border-top-left-radius:var(--ag-charts-border-radius);cursor:grab;display:flex;justify-content:center;min-width:24px;padding-left:0;padding-right:0}.ag-charts-floating-toolbar__drag-handle--dragging{cursor:grabbing}\n'; } }); // packages/ag-charts-community/src/util/listeners.ts var Listeners; var init_listeners = __esm({ "packages/ag-charts-community/src/util/listeners.ts"() { "use strict"; init_main(); Listeners = class { constructor() { this.registeredListeners = /* @__PURE__ */ new Map(); } addListener(eventType, handler) { const record = { symbol: Symbol(eventType), handler }; if (this.registeredListeners.has(eventType)) { this.registeredListeners.get(eventType).push(record); } else { this.registeredListeners.set(eventType, [record]); } return () => this.removeListener(record.symbol); } removeListener(eventSymbol) { for (const [type, listeners] of this.registeredListeners.entries()) { const matchIndex = listeners.findIndex((listener) => listener.symbol === eventSymbol); if (matchIndex >= 0) { listeners.splice(matchIndex, 1); if (listeners.length === 0) { this.registeredListeners.delete(type); } break; } } } dispatch(eventType, ...params) { for (const listener of this.getListenersByType(eventType)) { try { listener.handler(...params); } catch (e) { logger_exports.errorOnce(String(e)); } } } getListenersByType(eventType) { return this.registeredListeners.get(eventType) ?? []; } destroy() { this.registeredListeners.clear(); } }; } }); // packages/ag-charts-community/src/util/baseManager.ts var BaseManager; var init_baseManager = __esm({ "packages/ag-charts-community/src/util/baseManager.ts"() { "use strict"; init_listeners(); BaseManager = class { constructor() { this.listeners = new Listeners(); this.destroyFns = []; } addListener(type, handler) { return this.listeners.addListener(type, handler); } destroy() { this.listeners.destroy(); this.destroyFns.forEach((fn) => fn()); } }; } }); // packages/ag-charts-community/src/util/guardedElement.ts var GuardedElement; var init_guardedElement = __esm({ "packages/ag-charts-community/src/util/guardedElement.ts"() { "use strict"; init_core(); init_attributeUtil(); GuardedElement = class _GuardedElement { constructor(element2, topTabGuard, bottomTabGuard) { this.element = element2; this.topTabGuard = topTabGuard; this.bottomTabGuard = bottomTabGuard; this.destroyFns = []; this.guardTabIndex = 0; this.hasFocus = false; this.initTabGuard(this.topTabGuard, (el) => this.onTab(el, false)); this.initTabGuard(this.bottomTabGuard, (el) => this.onTab(el, true)); this.element.addEventListener("focus", () => this.onFocus(), { capture: true }); this.element.addEventListener("blur", (ev) => this.onBlur(ev), { capture: true }); } set tabIndex(index) { this.guardTabIndex = index; if (this.guardTabIndex === 0) { this.setGuardIndices(void 0); } else if (!this.hasFocus) { this.setGuardIndices(this.guardTabIndex); } } destroy() { for (const fn of this.destroyFns) fn(); this.destroyFns.length = 0; } initTabGuard(guard, handler) { const handlerBinding = () => handler(guard); guard.addEventListener("focus", handlerBinding); this.destroyFns.push(() => guard.removeEventListener("focus", handlerBinding)); } setGuardIndices(index) { const tabindex = index; setAttribute(this.topTabGuard, "tabindex", tabindex); setAttribute(this.bottomTabGuard, "tabindex", tabindex); } onFocus() { this.hasFocus = true; if (this.guardTabIndex !== 0) { this.setGuardIndices(0); } } onBlur({ relatedTarget }) { const { topTabGuard: top, bottomTabGuard: bot } = this; this.hasFocus = false; if (this.guardTabIndex !== 0 && relatedTarget !== top && relatedTarget !== bot) { this.setGuardIndices(this.guardTabIndex); } } onTab(guard, reverse) { if (this.guardTabIndex !== 0) { let focusTarget; if (guard.tabIndex === 0) { focusTarget = this.findExitTarget(!reverse); this.setGuardIndices(this.guardTabIndex); } else { focusTarget = this.findEnterTarget(reverse); } focusTarget?.focus(); } } static queryFocusable(element2, selectors) { const myWindow = getWindow(); return Array.from(element2.querySelectorAll(selectors)).filter((e) => { if (e instanceof HTMLElement) { const style = myWindow.getComputedStyle(e); return style.display !== "none" && style.visibility !== "none"; } return false; }); } findEnterTarget(reverse) { const focusables = _GuardedElement.queryFocusable(this.element, '[tabindex="0"]'); const index = reverse ? focusables.length - 1 : 0; return focusables[index]; } findExitTarget(reverse) { const focusables = _GuardedElement.queryFocusable(getDocument(), "[tabindex]").filter((e) => e.tabIndex > 0).sort((a, b) => a.tabIndex - b.tabIndex); const { before, after } = _GuardedElement.findBeforeAndAfter(focusables, this.guardTabIndex); return reverse ? before : after; } static findBeforeAndAfter(elements, targetTabIndex) { let left = 0; let right = elements.length - 1; let before = void 0; let after = void 0; while (left <= right) { const mid = Math.floor((left + right) / 2); const currentTabIndex = elements[mid].tabIndex; if (currentTabIndex === targetTabIndex) { before = elements[mid - 1] || void 0; after = elements[mid + 1] || void 0; break; } else if (currentTabIndex < targetTabIndex) { before = elements[mid]; left = mid + 1; } else { after = elements[mid]; right = mid - 1; } } return { before, after }; } }; } }); // packages/ag-charts-community/src/util/keynavUtil.ts function addRemovableEventListener(destroyFns, elem, type, listener, options) { elem.addEventListener(type, listener); const remover = () => elem.removeEventListener(type, listener, options); destroyFns.push(remover); return remover; } function addEscapeEventListener(destroyFns, elem, onEscape) { addRemovableEventListener(destroyFns, elem, "keydown", (event) => { if (event.key === "Escape") { onEscape(event); } }); } function addMouseCloseListener(destroyFns, menu, hideCallback) { const self = addRemovableEventListener(destroyFns, window, "mousedown", (event) => { if ([0, 2].includes(event.button) && !containsPoint2(menu, event)) { hideCallback(); self(); } }); return self; } function addTouchCloseListener(destroyFns, menu, hideCallback) { const self = addRemovableEventListener(destroyFns, window, "touchstart", (event) => { const touches = Array.from(event.targetTouches); if (touches.some((touch) => !containsPoint2(menu, touch))) { hideCallback(); self(); } }); return self; } function containsPoint2(container, event) { if (event.target instanceof Element) { const { x, y, width: width2, height: height2 } = container.getBoundingClientRect(); const { clientX: ex, clientY: ey } = event; return ex >= x && ey >= y && ex <= x + width2 && ey <= y + height2; } return false; } function hasNoModifiers(event) { return !(event.shiftKey || event.altKey || event.ctrlKey || event.metaKey); } function matchesKey(event, key, ...morekeys) { return hasNoModifiers(event) && (event.key === key || morekeys.some((altkey) => event.key === altkey)); } function linkTwoButtons(destroyFns, src, dst, key) { if (!dst) return; addRemovableEventListener(destroyFns, src, "keydown", (event) => { if (matchesKey(event, key)) { dst.focus(); } }); } function linkThreeButtons(destroyFns, curr, next, nextKey, prev, prevKey) { linkTwoButtons(destroyFns, curr, prev, prevKey); linkTwoButtons(destroyFns, curr, next, nextKey); addRemovableEventListener(destroyFns, curr, "keydown", (event) => { if (matchesKey(event, nextKey, prevKey)) { event.preventDefault(); } }); } function initRovingTabIndex(opts) { const { orientation, buttons: buttons2, wrapAround = false, onEscape, onFocus, onBlur } = opts; const { nextKey, prevKey } = PREV_NEXT_KEYS[orientation]; const setTabIndices = (event) => { if (event.target && "tabIndex" in event.target) { buttons2.forEach((b) => b.tabIndex = -1); event.target.tabIndex = 0; } }; const [c, m] = wrapAround ? [buttons2.length, buttons2.length] : [0, Infinity]; const destroyFns = []; for (let i = 0; i < buttons2.length; i++) { const prev = buttons2[(c + i - 1) % m]; const curr = buttons2[i]; const next = buttons2[(c + i + 1) % m]; addRemovableEventListener(destroyFns, curr, "focus", setTabIndices); if (onFocus) addRemovableEventListener(destroyFns, curr, "focus", onFocus); if (onBlur) addRemovableEventListener(destroyFns, curr, "blur", onBlur); if (onEscape) addEscapeEventListener(destroyFns, curr, onEscape); linkThreeButtons(destroyFns, curr, next, nextKey, prev, prevKey); curr.tabIndex = i === 0 ? 0 : -1; } return destroyFns; } function initMenuKeyNav(opts) { const { sourceEvent, orientation, menu, buttons: buttons2, closeCallback, overrideFocusVisible, autoCloseOnBlur = false } = opts; const { nextKey, prevKey } = PREV_NEXT_KEYS[orientation]; const lastFocus = getLastFocus(sourceEvent); setAttribute(lastFocus, "aria-expanded", true); const menuCloser = new MenuCloserImp(menu, lastFocus, closeCallback); const onEscape = () => menuCloser.close(); const { destroyFns } = menuCloser; menu.role = "menu"; menu.ariaOrientation = orientation; destroyFns.push(...initRovingTabIndex({ orientation, buttons: buttons2, onEscape, wrapAround: true })); menu.tabIndex = -1; addEscapeEventListener(destroyFns, menu, onEscape); addRemovableEventListener(destroyFns, menu, "keydown", (ev) => { if (ev.target === menu && (ev.key === nextKey || ev.key === prevKey)) { ev.preventDefault(); buttons2[0]?.focus(); } }); if (autoCloseOnBlur) { const handler = (ev) => { const buttonArray = buttons2; const isLeavingMenu = !buttonArray.includes(ev.relatedTarget); if (isLeavingMenu) { onEscape(); } }; for (const button of buttons2) { addRemovableEventListener(destroyFns, button, "blur", handler); } } buttons2[0]?.focus({ preventScroll: true }); if (overrideFocusVisible !== void 0) { buttons2.forEach((b) => b.setAttribute("data-focus-visible-override", overrideFocusVisible.toString())); const keydownTrueOverrider = () => { buttons2.forEach((b) => b.setAttribute("data-focus-visible-override", "true")); }; addRemovableEventListener(destroyFns, menu, "keydown", keydownTrueOverrider, { once: true }); } return menuCloser; } function makeAccessibleClickListener(element2, onclick) { return (event) => { if (element2.ariaDisabled === "true") { return event.preventDefault(); } onclick(event); }; } function isButtonClickEvent(event) { if ("button" in event) { return event.button === 0; } return hasNoModifiers(event) && (event.code === "Space" || event.key === "Enter"); } function getLastFocus(sourceEvent) { if (sourceEvent?.target instanceof HTMLElement && "tabindex" in sourceEvent.target.attributes) { return sourceEvent.target; } return void 0; } function stopPageScrolling(element2) { const handler = (event) => { if (event.defaultPrevented) return; const shouldPrevent = getAttribute(event.target, "data-preventdefault", true); if (shouldPrevent && matchesKey(event, "ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp")) { event.preventDefault(); } }; element2.addEventListener("keydown", handler); return () => element2.removeEventListener("keydown", handler); } var PREV_NEXT_KEYS, MenuCloserImp; var init_keynavUtil = __esm({ "packages/ag-charts-community/src/util/keynavUtil.ts"() { "use strict"; init_attributeUtil(); PREV_NEXT_KEYS = { horizontal: { nextKey: "ArrowRight", prevKey: "ArrowLeft" }, vertical: { nextKey: "ArrowDown", prevKey: "ArrowUp" } }; MenuCloserImp = class { constructor(menu, lastFocus, closeCallback) { this.lastFocus = lastFocus; this.closeCallback = closeCallback; this.destroyFns = []; this.destroyFns.push(addMouseCloseListener(this.destroyFns, menu, () => this.close(true))); this.destroyFns.push(addTouchCloseListener(this.destroyFns, menu, () => this.close(true))); } close(mousedown) { this.destroyFns.forEach((d) => d()); this.destroyFns.length = 0; this.closeCallback(); this.finishClosing(mousedown); } finishClosing(mousedown) { this.destroyFns.forEach((d) => d()); this.destroyFns.length = 0; setAttribute(this.lastFocus, "aria-expanded", false); if (!mousedown) { this.lastFocus?.focus({ preventScroll: true }); } this.lastFocus = void 0; } }; } }); // packages/ag-charts-community/src/util/pixelRatioObserver.ts var PixelRatioObserver; var init_pixelRatioObserver = __esm({ "packages/ag-charts-community/src/util/pixelRatioObserver.ts"() { "use strict"; init_core(); PixelRatioObserver = class { constructor(callback2) { this.callback = callback2; this.devicePixelRatio = getWindow("devicePixelRatio") ?? 1; this.devicePixelRatioMediaQuery = void 0; this.devicePixelRatioListener = (e) => { if (e.matches) return; this.devicePixelRatio = getWindow("devicePixelRatio") ?? 1; this.unregisterDevicePixelRatioListener(); this.registerDevicePixelRatioListener(); this.callback(this.pixelRatio); }; } get pixelRatio() { return this.devicePixelRatio; } observe() { this.registerDevicePixelRatioListener(); } disconnect() { this.unregisterDevicePixelRatioListener(); } unregisterDevicePixelRatioListener() { this.devicePixelRatioMediaQuery?.removeEventListener("change", this.devicePixelRatioListener); this.devicePixelRatioMediaQuery = void 0; } registerDevicePixelRatioListener() { const devicePixelRatioMediaQuery = getWindow("matchMedia")?.(`(resolution: ${this.pixelRatio}dppx)`); devicePixelRatioMediaQuery?.addEventListener("change", this.devicePixelRatioListener); this.devicePixelRatioMediaQuery = devicePixelRatioMediaQuery; } }; } }); // packages/ag-charts-community/src/util/sizeMonitor.ts var SizeMonitor; var init_sizeMonitor = __esm({ "packages/ag-charts-community/src/util/sizeMonitor.ts"() { "use strict"; init_core(); init_pixelRatioObserver(); SizeMonitor = class { constructor() { this.elements = /* @__PURE__ */ new Map(); this.documentReady = false; this.queuedObserveRequests = []; this.onLoad = () => { this.documentReady = true; this.queuedObserveRequests.forEach(([el, cb]) => this.observe(el, cb)); this.queuedObserveRequests = []; this.observeWindow(); }; if (typeof ResizeObserver !== "undefined") { this.resizeObserver = new ResizeObserver((entries) => { for (const { target, contentRect: { width: width2, height: height2 } } of entries) { const entry = this.elements.get(target); this.checkSize(entry, target, width2, height2); } }); } let animationFrame; this.pixelRatioObserver = new PixelRatioObserver(() => { clearTimeout(animationFrame); animationFrame = setTimeout(() => this.checkPixelRatio(), 0); }); this.documentReady = getDocument("readyState") === "complete"; if (this.documentReady) { this.observeWindow(); } else { getWindow()?.addEventListener("load", this.onLoad); } } destroy() { getWindow()?.removeEventListener("load", this.onLoad); this.resizeObserver?.disconnect(); this.resizeObserver = void 0; this.pixelRatioObserver?.disconnect(); this.pixelRatioObserver = void 0; } observeWindow() { this.pixelRatioObserver?.observe(); } checkPixelRatio() { const pixelRatio = this.pixelRatioObserver?.pixelRatio ?? 1; for (const [element2, entry] of this.elements) { if (entry.size != null && entry.size.pixelRatio !== pixelRatio) { const { width: width2, height: height2 } = entry.size; entry.size = { width: width2, height: height2, pixelRatio }; entry.cb(entry.size, element2); } } } checkSize(entry, element2, width2, height2) { if (!entry) return; if (width2 !== entry.size?.width || height2 !== entry.size?.height) { const pixelRatio = this.pixelRatioObserver?.pixelRatio ?? 1; entry.size = { width: width2, height: height2, pixelRatio }; entry.cb(entry.size, element2); } } // Only a single callback is supported. observe(element2, cb) { if (!this.documentReady) { this.queuedObserveRequests.push([element2, cb]); return; } if (this.elements.has(element2)) { this.removeFromQueue(element2); } else { this.resizeObserver?.observe(element2); } const entry = { cb }; this.elements.set(element2, entry); } unobserve(element2) { this.resizeObserver?.unobserve(element2); this.elements.delete(element2); this.removeFromQueue(element2); if (!this.elements.size) { this.destroy(); } } removeFromQueue(element2) { this.queuedObserveRequests = this.queuedObserveRequests.filter(([el]) => el !== element2); } }; } }); // packages/ag-charts-community/src/util/stateTracker.ts var StateTracker; var init_stateTracker = __esm({ "packages/ag-charts-community/src/util/stateTracker.ts"() { "use strict"; StateTracker = class extends Map { constructor(defaultValue, defaultState) { super(); this.defaultValue = defaultValue; this.defaultState = defaultState; } set(key, value) { this.delete(key); if (typeof value !== "undefined") { super.set(key, value); } return this; } stateId() { return Array.from(this.keys()).pop() ?? this.defaultState; } stateValue() { return Array.from(this.values()).pop() ?? this.defaultValue; } }; } }); // packages/ag-charts-community/src/dom/domLayout.html var domLayout_default; var init_domLayout = __esm({ "packages/ag-charts-community/src/dom/domLayout.html"() { domLayout_default = ''; } }); // packages/ag-charts-community/src/dom/domManager.ts function setupObserver(element2, cb) { if (typeof IntersectionObserver === "undefined") return; const observer = new IntersectionObserver( (entries) => { for (const entry of entries) { if (entry.target === element2) { cb(entry.intersectionRatio); } } }, { root: element2 } ); observer.observe(element2); return observer; } function createTabGuardElement(guardedElem, where) { const div = createElement("div"); div.className = "ag-charts-tab-guard"; guardedElem.insertAdjacentElement(where, div); return div; } var DOM_ELEMENT_CLASSES, CONTAINER_MODIFIERS, domElementConfig, NULL_DOMRECT, DOMManager; var init_domManager = __esm({ "packages/ag-charts-community/src/dom/domManager.ts"() { "use strict"; init_core(); init_bbox(); init_styles(); init_attributeUtil(); init_baseManager(); init_guardedElement(); init_keynavUtil(); init_sizeMonitor(); init_stateTracker(); init_domLayout(); DOM_ELEMENT_CLASSES = [ "styles", "canvas", "canvas-center", "canvas-container", "canvas-overlay", "canvas-proxy", "series-area" ]; CONTAINER_MODIFIERS = { safeHorizontal: "ag-charts-wrapper--safe-horizontal", safeVertical: "ag-charts-wrapper--safe-vertical" }; domElementConfig = /* @__PURE__ */ new Map([ ["styles", { childElementType: "style" }], ["canvas", { childElementType: "canvas" }], ["canvas-proxy", { childElementType: "div" }], ["canvas-overlay", { childElementType: "div" }], ["canvas-center", { childElementType: "div" }], ["series-area", { childElementType: "div" }] ]); NULL_DOMRECT = { x: 0, y: 0, width: 0, height: 0, top: 0, bottom: 0, left: 0, right: 0, toJSON() { return NULL_DOMRECT; } }; DOMManager = class extends BaseManager { constructor(container, styleContainer) { super(); this.styles = /* @__PURE__ */ new Map(); this.container = void 0; this.containerSize = void 0; this.sizeMonitor = new SizeMonitor(); this.cursorState = new StateTracker("default"); this.minWidth = 0; this.minHeight = 0; const templateEl = createElement("div"); templateEl.innerHTML = domLayout_default; this.element = templateEl.children.item(0); this.styleRootElement = styleContainer; this.rootElements = DOM_ELEMENT_CLASSES.reduce( (r, c) => { const cssClass = `ag-charts-${c}`; const el = this.element.classList.contains(cssClass) ? this.element : this.element.querySelector(`.${cssClass}`); if (!el) throw new Error(`AG Charts - unable to find DOM element ${cssClass}`); r[c] = { element: el, children: /* @__PURE__ */ new Map(), listeners: [] }; return r; }, {} ); let hidden = false; this.observer = setupObserver(this.element, (intersectionRatio) => { if (intersectionRatio === 0 && !hidden) { this.listeners.dispatch("hidden", { type: "hidden" }); } hidden = intersectionRatio === 0; }); this.setSizeOptions(); this.updateContainerSize(); this.addStyles("ag-charts-community", styles_default); if (container) { this.setContainer(container); } this.destroyFns.push(stopPageScrolling(this.element)); const guardedElement = this.element.querySelector(".ag-charts-canvas-center"); if (guardedElement == null) throw new Error("Error initializing tab guards"); const topGuard = createTabGuardElement(guardedElement, "beforebegin"); const botGuard = createTabGuardElement(guardedElement, "afterend"); this.tabGuards = new GuardedElement(guardedElement, topGuard, botGuard); } destroy() { super.destroy(); this.observer?.unobserve(this.element); if (this.container) { this.sizeMonitor.unobserve(this.container); } Object.values(this.rootElements).forEach((el) => { el.children.forEach((c) => c.remove()); el.element.remove(); }); this.element.remove(); } setSizeOptions(minWidth = 300, minHeight = 300, optionsWidth, optionsHeight) { const { style } = this.element; style.width = `${optionsWidth ?? minWidth}px`; style.height = `${optionsHeight ?? minHeight}px`; this.minWidth = optionsWidth ?? minWidth; this.minHeight = optionsHeight ?? minHeight; this.updateContainerClassName(); } updateContainerSize() { const { style: centerStyle } = this.rootElements["canvas-center"].element; centerStyle.visibility = this.containerSize == null ? "hidden" : ""; if (this.containerSize) { centerStyle.width = `${this.containerSize.width ?? 0}px`; centerStyle.height = `${this.containerSize.height ?? 0}px`; } else { centerStyle.width = ""; centerStyle.height = ""; } this.updateContainerClassName(); } setTabGuardIndex(tabIndex) { this.tabGuards.tabIndex = tabIndex; } setContainer(newContainer) { if (newContainer === this.container) return; if (this.container) { this.container.removeChild(this.element); this.sizeMonitor.unobserve(this.container); } const isShadowDom = this.getShadowDocumentRoot(newContainer) != null; if (!isShadowDom) { for (const id of this.rootElements["styles"].children.keys()) { this.removeChild("styles", id); } } this.container = newContainer; for (const [id, styles] of this.styles) { this.addStyles(id, styles); } newContainer.appendChild(this.element); this.sizeMonitor.observe(newContainer, (size) => { this.containerSize = size; this.updateContainerSize(); this.listeners.dispatch("resize", { type: "resize" }); }); this.listeners.dispatch("container-changed", { type: "container-changed" }); } setThemeClass(themeClassName) { const themeClassNamePrefix = "ag-charts-theme-"; this.element.classList.forEach((className) => { if (className.startsWith(themeClassNamePrefix) && className !== themeClassName) { this.element.classList.remove(className); } }); this.element.classList.add(themeClassName); } setThemeParameters(params) { const keysMap = { accentColor: "accent-color", axisColor: "axis-color", backgroundColor: "background-color", borderColor: "border-color", foregroundColor: "foreground-color", fontFamily: "font-family", fontSize: "font-size", fontWeight: "font-weight", gridLineColor: "grid-line-color", padding: "padding", subtleTextColor: "subtle-text-color", textColor: "text-color", chromeBackgroundColor: "chrome-background-color", chromeFontFamily: "chrome-font-family", chromeFontSize: "chrome-font-size", chromeFontWeight: "chrome-font-weight", chromeSubtleTextColor: "chrome-subtle-text-color", chromeTextColor: "chrome-text-color", inputBackgroundColor: "input-background-color", inputTextColor: "input-text-color", crosshairLabelBackgroundColor: "crosshair-label-background-color", crosshairLabelTextColor: "crosshair-label-text-color" }; const lengthKeys = ["fontSize", "chromeFontSize"]; for (const [key, value] of Object.entries(params)) { let formattedValue = `${value}`; if (lengthKeys.includes(key)) { formattedValue = `${value}px`; } this.element.style.setProperty(`--ag-charts-${keysMap[key]}`, formattedValue); } } updateCanvasLabel(ariaLabel) { setAttribute(this.rootElements["canvas-proxy"].element, "aria-label", ariaLabel); } getEventElement(defaultElem, eventType) { const events = ["focus", "blur", "keydown", "keyup"]; return events.includes(eventType) ? this.rootElements["series-area"].element : defaultElem; } addEventListener(type, listener, options) { this.getEventElement(this.element, type).addEventListener(type, listener, options); } removeEventListener(type, listener, options) { this.getEventElement(this.element, type).removeEventListener(type, listener, options); } /** Get the main chart area client bound rect. */ getBoundingClientRect() { return this.rootElements["canvas"].element.getBoundingClientRect(); } /** * Get the client bounding rect for overlay elements that might float outside the bounds of the * main chart area. */ getOverlayClientRect() { const window2 = getWindow(); const windowBBox = new BBox(0, 0, window2.innerWidth, window2.innerHeight); const containerBBox = this.getRawOverlayClientRect(); return windowBBox.intersection(containerBBox)?.toDOMRect() ?? NULL_DOMRECT; } getRawOverlayClientRect() { let element2 = this.element; while (element2 != null) { const styleMap = element2.computedStyleMap?.(); const overflowY = styleMap?.get("overflow-y")?.toString(); if (overflowY === "auto" || overflowY === "scroll") { return BBox.fromDOMRect(element2.getBoundingClientRect()); } element2 = element2.parentElement; } const docRoot = this.getShadowDocumentRoot(); if (docRoot != null) return BBox.fromDOMRect(docRoot.getBoundingClientRect()); const { innerWidth, innerHeight } = getWindow(); return new BBox(0, 0, innerWidth, innerHeight); } getShadowDocumentRoot(current = this.container) { const docRoot = current?.ownerDocument?.body ?? getDocument("body"); while (current != null) { if (current === docRoot) { return void 0; } if (current.parentNode instanceof DocumentFragment) { return current; } current = current.parentNode; } return this.container; } getParent(domElementClass) { return this.rootElements[domElementClass].element; } getChildBoundingClientRect(type) { const { children } = this.rootElements[type]; const childRects = []; for (const child of children.values()) { childRects.push(BBox.fromDOMRect(child.getBoundingClientRect())); } return BBox.merge(childRects); } isManagedChildDOMElement(el, domElementClass, id) { const { children } = this.rootElements[domElementClass]; const search = children?.get(id); return search != null && el.contains(search); } contains(element2, domElementClass) { if (domElementClass == null) return this.element.contains(element2); return this.rootElements[domElementClass].element.contains(element2); } addStyles(id, styles) { const dataAttribute = "data-ag-charts"; this.styles.set(id, styles); if (this.container == null) return; const checkId = (el) => { return el.getAttribute(dataAttribute) === id; }; const addStyleElement = (el) => { const metaElements = /* @__PURE__ */ new Set(["TITLE", "META"]); let skippingMetaElements = true; let insertAfterEl; for (const child of el.children) { if (skippingMetaElements && metaElements.has(child.tagName)) { insertAfterEl = child; continue; } skippingMetaElements = false; if (checkId(child)) return; if (child.hasAttribute(dataAttribute)) { insertAfterEl = child; } } const styleEl = createElement("style"); if (insertAfterEl != null) { el.insertBefore(styleEl, insertAfterEl.nextSibling); } else { el.prepend(styleEl); } return styleEl; }; let styleElement; if (this.styleRootElement) { styleElement = addStyleElement(this.styleRootElement); } else { const documentRoot = this.getShadowDocumentRoot(this.container); if (documentRoot != null) { styleElement = this.addChild("styles", id); } else { styleElement = addStyleElement(getDocument("head")); } } if (styleElement == null || checkId(styleElement)) return; styleElement.setAttribute(dataAttribute, id); styleElement.innerHTML = styles; } removeStyles(id) { this.removeChild("styles", id); } updateCursor(callerId, style) { this.cursorState.set(callerId, style); this.element.style.cursor = this.cursorState.stateValue(); } getCursor() { return this.element.style.cursor; } addChild(domElementClass, id, child, insert) { const { element: element2, children, listeners } = this.rootElements[domElementClass]; if (!children) { throw new Error("AG Charts - unable to create DOM elements after destroy()"); } if (children.has(id)) { return children.get(id); } const { childElementType = "div" } = domElementConfig.get(domElementClass) ?? {}; if (child && child.tagName.toLowerCase() !== childElementType.toLowerCase()) { throw new Error("AG Charts - mismatching DOM element type"); } const newChild = child ?? createElement(childElementType); for (const [type, fn, opts] of listeners) { newChild.addEventListener(type, fn, opts); } children.set(id, newChild); if (insert) { const queryResult = element2.querySelector(insert.query); if (queryResult == null) { throw new Error(`AG Charts - addChild query failed ${insert.query}`); } queryResult.insertAdjacentElement(insert.where, newChild); } else { element2?.appendChild(newChild); } return newChild; } removeChild(domElementClass, id) { const { children } = this.rootElements[domElementClass]; if (!children) return; children.get(id)?.remove(); children.delete(id); } incrementDataCounter(name) { const { dataset } = this.element; dataset[name] ?? (dataset[name] = "0"); dataset[name] = String(Number(dataset[name]) + 1); } setDataBoolean(name, value) { this.element.dataset[name] = String(value); } updateContainerClassName() { const { element: element2, containerSize, minWidth, minHeight } = this; element2.classList.toggle(CONTAINER_MODIFIERS.safeHorizontal, minWidth >= (containerSize?.width ?? Infinity)); element2.classList.toggle(CONTAINER_MODIFIERS.safeVertical, minHeight >= (containerSize?.height ?? Infinity)); } }; } }); // packages/ag-charts-community/src/widget/boundedTextWidget.ts var BoundedTextWidget; var init_boundedTextWidget = __esm({ "packages/ag-charts-community/src/widget/boundedTextWidget.ts"() { "use strict"; init_core(); init_widget(); BoundedTextWidget = class extends Widget { constructor() { super(createElement("div")); this.textElement = createSvgElement("text"); this.textElement.role = "presentation"; this.svgElement = createSvgElement("svg"); this.svgElement.appendChild(this.textElement); this.svgElement.style.width = "100%"; this.svgElement.style.opacity = "0"; this.svgElement.role = "presentation"; this.elem.appendChild(this.svgElement); this.elem.role = "presentation"; } set textContent(text3) { this.textElement.textContent = text3; const bboxCalculator = this.textElement; const bbox = bboxCalculator.getBBox?.(); if (bbox) { this.svgElement.setAttribute("viewBox", `${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`); } } get textContent() { return this.textElement.textContent; } destructor() { } }; } }); // packages/ag-charts-community/src/widget/buttonWidget.ts var ButtonWidget; var init_buttonWidget = __esm({ "packages/ag-charts-community/src/widget/buttonWidget.ts"() { "use strict"; init_core(); init_attributeUtil(); init_widget(); ButtonWidget = class extends Widget { constructor() { super(createElement("button")); this.setEnabled(true); } destructor() { } setEnabled(enabled) { setAttribute(this.elem, "aria-disabled", !enabled); setElementStyle(this.elem, "pointer-events", enabled ? void 0 : "none"); } addListener(type, listener) { return super.addListener(type, (ev, current) => { if ((type === "click" || type === "dblclick") && this.isDisabled()) return; listener(ev, current); }); } }; } }); // packages/ag-charts-community/src/widget/groupWidget.ts var GroupWidget; var init_groupWidget = __esm({ "packages/ag-charts-community/src/widget/groupWidget.ts"() { "use strict"; init_core(); init_attributeUtil(); init_widget(); GroupWidget = class extends Widget { constructor() { super(createElement("div")); setAttribute(this.elem, "role", "group"); } destructor() { } }; } }); // packages/ag-charts-community/src/widget/rovingTabContainerWidget.ts var RovingTabContainerWidget; var init_rovingTabContainerWidget = __esm({ "packages/ag-charts-community/src/widget/rovingTabContainerWidget.ts"() { "use strict"; init_core(); init_attributeUtil(); init_keynavUtil(); init_widget(); RovingTabContainerWidget = class extends Widget { constructor(initialOrientation, role) { super(createElement("div")); this.focusedChildIndex = 0; this.onChildFocus = (_event, child) => { const oldFocus = this.children[this.focusedChildIndex]; this.focusedChildIndex = child.index; oldFocus?.setTabIndex(-1); child.setTabIndex(0); }; this.onChildKeyDown = (event, child) => { const rovingOrientation = this.orientation; const [primaryKeys, secondaryKeys] = rovingOrientation === "both" ? [PREV_NEXT_KEYS["horizontal"], PREV_NEXT_KEYS["vertical"]] : [PREV_NEXT_KEYS[rovingOrientation], void 0]; let targetIndex = -1; if (hasNoModifiers(event.sourceEvent)) { const key = event.sourceEvent.key; if (key === primaryKeys.nextKey || key === secondaryKeys?.nextKey) { targetIndex = child.index + 1; } else if (key === primaryKeys.prevKey || key === secondaryKeys?.prevKey) { targetIndex = child.index - 1; } } this.children[targetIndex]?.focus(); }; this.orientation = initialOrientation; setAttribute(this.elem, "role", role); } get orientation() { return getAttribute(this.elem, "aria-orientation") ?? "both"; } set orientation(orientation) { setAttribute(this.elem, "aria-orientation", orientation !== "both" ? orientation : void 0); } focus() { this.children[this.focusedChildIndex]?.focus(); } onChildAdded(child) { child.addListener("focus", this.onChildFocus); child.addListener("keydown", this.onChildKeyDown); child.setTabIndex(this.children.length === 1 ? 0 : -1); } onChildRemoved(child) { child.removeListener("focus", this.onChildFocus); child.removeListener("keydown", this.onChildKeyDown); } }; } }); // packages/ag-charts-community/src/widget/listWidget.ts var ListWidget; var init_listWidget = __esm({ "packages/ag-charts-community/src/widget/listWidget.ts"() { "use strict"; init_core(); init_attributeUtil(); init_rovingTabContainerWidget(); init_widget(); ListWidget = class extends RovingTabContainerWidget { constructor() { super("both", "list"); this.setHidden(true); } destructor() { this.children.forEach((c) => c.getElement().parentElement.remove()); } addChildToDOM(child, before) { const listItem = createElement("div"); setAttribute(listItem, "role", "listitem"); setElementStyle(listItem, "position", "absolute"); Widget.setElementContainer(child, listItem); this.appendOrInsert(listItem, before); this.setHidden(false); } removeChildFromDOM(child) { child.getElement().parentElement.remove(); this.setHidden(this.children.length === 0); } setHidden(hidden) { if (this.children.length === 0) { hidden = true; } super.setHidden(hidden); } }; } }); // packages/ag-charts-community/src/widget/nativeWidget.ts var NativeWidget; var init_nativeWidget = __esm({ "packages/ag-charts-community/src/widget/nativeWidget.ts"() { "use strict"; init_widget(); NativeWidget = class extends Widget { constructor(elem) { super(elem); } destructor() { } }; } }); // packages/ag-charts-community/src/widget/sliderWidget.ts var _SliderWidget, SliderWidget; var init_sliderWidget = __esm({ "packages/ag-charts-community/src/widget/sliderWidget.ts"() { "use strict"; init_core(); init_attributeUtil(); init_format_util(); init_number(); init_widget(); _SliderWidget = class _SliderWidget extends Widget { constructor() { super(createElement("input")); this._step = _SliderWidget.STEP_ONE; this.orientation = "both"; } get step() { return this._step; } set step(step) { this._step = step; this.getElement().step = step.attributeValue; } get keyboardStep() { return this._keyboardStep?.step ?? this._step; } set keyboardStep(step) { if (step === this._keyboardStep?.step) return; if (this._keyboardStep !== void 0) { this.removeListener("keydown", this._keyboardStep.onKeyDown); this.removeListener("keyup", this._keyboardStep.onKeyUp); this.removeListener("blur", this._keyboardStep.onBlur); this._keyboardStep = void 0; } if (step !== void 0) { const onKeyDown = () => this.getElement().step = step.attributeValue; const resetStep = () => this.getElement().step = this._step.attributeValue; this._keyboardStep = { step, onKeyDown, onKeyUp: resetStep, onBlur: resetStep }; this.addListener("keydown", this._keyboardStep.onKeyDown); this.addListener("keyup", this._keyboardStep.onKeyUp); this.addListener("blur", this._keyboardStep.onBlur); } } get orientation() { return getAttribute(this.elem, "aria-orientation") ?? "both"; } set orientation(orientation) { setAttribute(this.elem, "aria-orientation", orientation !== "both" ? orientation : void 0); _SliderWidget.registerDefaultPreventers(this, orientation); } destructor() { } clampValueRatio(clampMin, clampMax) { const ratio2 = this.getValueRatio(); const clampedRatio = clamp(clampMin, ratio2, clampMax); if (clampedRatio !== ratio2) { this.setValueRatio(clampedRatio); } return clampedRatio; } setValueRatio(ratio2, opts) { const { divider } = this.step; const value = Math.round(ratio2 * 1e4) / divider; const { ariaValueText = formatPercent(value / divider) } = opts ?? {}; const elem = this.getElement(); elem.value = `${value}`; elem.ariaValueText = ariaValueText; } getValueRatio() { return parseFloat(this.getElement().value) / this.step.divider; } static registerDefaultPreventers(target, orientation) { if (orientation === "both") { target.removeListener("keydown", _SliderWidget.onKeyDown); } else { target.addListener("keydown", _SliderWidget.onKeyDown); } } static onKeyDown(ev, current) { let ignoredKeys = []; const { orientation } = current; if (orientation === "horizontal") { ignoredKeys = ["ArrowUp", "ArrowDown"]; } else if (orientation === "vertical") { ignoredKeys = ["ArrowLeft", "ArrowRight"]; } if (ignoredKeys.includes(ev.sourceEvent.code)) { ev.sourceEvent.preventDefault(); } } }; _SliderWidget.STEP_ONE = { attributeValue: "1", divider: 1 }; _SliderWidget.STEP_HUNDRETH = { attributeValue: "0.01", divider: 100 }; SliderWidget = _SliderWidget; } }); // packages/ag-charts-community/src/widget/switchWidget.ts var SwitchWidget; var init_switchWidget = __esm({ "packages/ag-charts-community/src/widget/switchWidget.ts"() { "use strict"; init_attributeUtil(); init_buttonWidget(); SwitchWidget = class extends ButtonWidget { constructor() { super(); setAttribute(this.elem, "role", "switch"); this.setChecked(false); } setChecked(checked) { setAttribute(this.elem, "aria-checked", checked); } }; } }); // packages/ag-charts-community/src/widget/toolbarWidget.ts var ToolbarWidget; var init_toolbarWidget = __esm({ "packages/ag-charts-community/src/widget/toolbarWidget.ts"() { "use strict"; init_rovingTabContainerWidget(); ToolbarWidget = class extends RovingTabContainerWidget { constructor(orientation = "horizontal") { super(orientation, "toolbar"); } destructor() { } }; } }); // packages/ag-charts-community/src/dom/proxyInteractionService.ts function checkType(type, meta) { return meta.params?.type === type; } function allocateResult(type) { if ("button" === type) { return new ButtonWidget(); } else if ("slider" === type) { return new SliderWidget(); } else if ("toolbar" === type) { return new ToolbarWidget(); } else if ("group" === type) { return new GroupWidget(); } else if ("list" === type) { return new ListWidget(); } else if ("region" === type) { return new NativeWidget(createElement("div")); } else if ("text" === type) { return new BoundedTextWidget(); } else if ("listswitch" === type) { return new SwitchWidget(); } else { throw Error("AG Charts - error allocating meta"); } } function allocateMeta(params) { const meta = { params, result: void 0 }; meta.result = allocateResult(meta.params.type); return meta; } var ProxyInteractionService; var init_proxyInteractionService = __esm({ "packages/ag-charts-community/src/dom/proxyInteractionService.ts"() { "use strict"; init_core(); init_attributeUtil(); init_boundedTextWidget(); init_buttonWidget(); init_groupWidget(); init_listWidget(); init_nativeWidget(); init_sliderWidget(); init_switchWidget(); init_toolbarWidget(); ProxyInteractionService = class { constructor(localeManager, domManager) { this.localeManager = localeManager; this.domManager = domManager; this.destroyFns = []; } destroy() { this.destroyFns.forEach((fn) => fn()); } addLocalisation(fn) { fn(); this.destroyFns.push(this.localeManager.addListener("locale-changed", fn)); } createProxyContainer(args) { const meta = allocateMeta(args); const { params, result } = meta; const div = result.getElement(); this.domManager.addChild("canvas-proxy", params.domManagerId, div); div.classList.add(...params.classList, "ag-charts-proxy-container"); div.role = params.type; if ("ariaOrientation" in params) { div.ariaOrientation = params.ariaOrientation; } if (checkType("toolbar", meta)) { meta.result.orientation = meta.params.orientation; } this.addLocalisation(() => { div.ariaLabel = this.localeManager.t(params.ariaLabel.id, params.ariaLabel.params); }); return result; } createProxyElement(args) { const meta = allocateMeta(args); if (checkType("button", meta)) { const { params, result } = meta; const button = result.getElement(); this.initInteract(params, result); if (typeof params.textContent === "string") { button.textContent = params.textContent; } else { const { textContent } = params; this.addLocalisation(() => { button.textContent = this.localeManager.t(textContent.id, textContent.params); }); } this.setParent(meta.params, meta.result); } if (checkType("slider", meta)) { const { params, result } = meta; const slider = result.getElement(); this.initInteract(params, result); slider.type = "range"; slider.role = "presentation"; slider.style.margin = "0px"; this.addLocalisation(() => { slider.ariaLabel = this.localeManager.t(params.ariaLabel.id, params.ariaLabel.params); }); this.setParent(meta.params, meta.result); } if (checkType("text", meta)) { const { params, result } = meta; this.initElement(params, result); this.setParent(meta.params, meta.result); } if (checkType("listswitch", meta)) { const { params, result: button } = meta; this.initInteract(params, button); button.setTextContent(params.textContent); button.setChecked(params.ariaChecked); button.setAriaDescribedBy(params.ariaDescribedBy); this.setParent(meta.params, meta.result); } if (checkType("region", meta)) { const { params, result } = meta; const region = result.getElement(); this.initInteract(params, result); region.role = "region"; this.setParent(meta.params, meta.result); } return meta.result; } initElement(params, widget) { const element2 = widget.getElement(); setAttribute(element2, "id", params.id); setElementStyle(element2, "cursor", params.cursor); element2.classList.toggle("ag-charts-proxy-elem", true); return element2; } initInteract(params, widget) { const { tabIndex, domIndex } = params; const element2 = this.initElement(params, widget); if (tabIndex !== void 0) { element2.tabIndex = tabIndex; } if (domIndex !== void 0) { widget.domIndex = domIndex; } } setParent(params, element2) { if ("parent" in params) { params.parent?.addChild(element2); } else { const insert = { where: params.where, query: ".ag-charts-series-area" }; this.domManager.addChild("canvas-proxy", params.domManagerId, element2.getElement(), insert); } } }; } }); // packages/ag-charts-locale/src/ar-EG.ts var init_ar_EG = __esm({ "packages/ag-charts-locale/src/ar-EG.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/bg-BG.ts var init_bg_BG = __esm({ "packages/ag-charts-locale/src/bg-BG.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/cs-CZ.ts var init_cs_CZ = __esm({ "packages/ag-charts-locale/src/cs-CZ.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/da-DK.ts var init_da_DK = __esm({ "packages/ag-charts-locale/src/da-DK.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/de-DE.ts var init_de_DE = __esm({ "packages/ag-charts-locale/src/de-DE.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/el-GR.ts var init_el_GR = __esm({ "packages/ag-charts-locale/src/el-GR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/en-US.ts var AG_CHARTS_LOCALE_EN_US; var init_en_US = __esm({ "packages/ag-charts-locale/src/en-US.ts"() { "use strict"; AG_CHARTS_LOCALE_EN_US = { // Screen reader announcement when focusing an item in the chart ariaAnnounceHoverDatum: "${datum}", // Screen reader announcement when focusing a chart ariaAnnounceChart: "chart, ${seriesCount}[number] series", // Screen reader announcement when focusing a hierarchy chart ariaAnnounceHierarchyChart: "hierarchy chart, ${caption}", // Screen reader announcement when focusing a gauge chart ariaAnnounceGaugeChart: "gauge chart, ${caption}", // Screen reader announcement when focusing an item in a treemap or sunburst chart ariaAnnounceHierarchyDatum: "level ${level}[number], ${count}[number] children, ${description}", // Screen reader announcement when focusing a link in a Sankey or chord chart ariaAnnounceFlowProportionLink: "link ${index} of ${count}, from ${from} to ${to}, ${sizeName} ${size}", // Screen reader announcement when focusing a node in a Sankey or chord chart ariaAnnounceFlowProportionNode: "node ${index} of ${count}, ${description}", // Screen reader description for legend items ariaDescriptionLegendItem: "Press Space or Enter to toggle visibility", // Screen reader for the '+' horizontal line button on the Y-axis ariaLabelAddHorizontalLine: "Add Horizontal Line", // Screen reader text for annotation-options toolbar ariaLabelAnnotationOptionsToolbar: "Annotation Options", // Screen reader text for annotation-settings dialog ariaLabelAnnotationSettingsDialog: "Annotation Settings", // Screen reader text for the color picker dialog ariaLabelColorPicker: "Color picker", // Screen reader text for the financial charts toolbar ariaLabelFinancialCharts: "Financial Charts", // Screen reader text for the legend toolbar ariaLabelLegend: "Legend", // Screen reader text for the legend pagination button ariaLabelLegendPagination: "Legend Pagination", // Screen reader text for the previous legend page button ariaLabelLegendPagePrevious: "Previous Legend Page", // Screen reader text for the next legend page button ariaLabelLegendPageNext: "Next Legend Page", // Screen reader text for the an item in the legend ariaLabelLegendItem: "${label}, Legend item ${index}[number] of ${count}[number]", // Screen reader text for the an unknown item in the legend ariaLabelLegendItemUnknown: "Unknown legend item", // Screen reader text for the navigator element ariaLabelNavigator: "Navigator", // Screen reader text for an accessibility control that changes the position of the navigator's range ariaLabelNavigatorRange: "Range", // Screen reader text for an accessibility control that changes the start of the navigator's range ariaLabelNavigatorMinimum: "Minimum", // Screen reader text for an accessibility control that changes the end of the navigator's range ariaLabelNavigatorMaximum: "Maximum", // Screen reader text for ranges toolbar ariaLabelRangesToolbar: "Ranges", // Screen reader text for the settings dialog tab-bar ariaLabelSettingsTabBar: "Settings", // Screen reader text for zoom toolbar ariaLabelZoomToolbar: "Zoom", // Screen reader text for the value of the navigator's range ariaValuePanRange: "${min}[percent] to ${max}[percent]", // Alt-text for the solid line dash style menu item icon iconAltTextLineStyleSolid: "Solid", // Alt-text for the long-dashed line dash style menu item icon iconAltTextLineStyleDashed: "Long-dashed", // Alt-text for the short-dashed line dash style menu item icon iconAltTextLineStyleDotted: "Short-dashed", // Alt-text for the 'position-top' icon iconAltTextPositionTop: "Top", // Alt-text for the 'position-center' icon iconAltTextPositionCenter: "Center", // Alt-text for the 'position-bottom' icon iconAltTextPositionBottom: "Bottom", // Alt-text for the 'position-left' icon iconAltTextAlignLeft: "Left", // Alt-text for the 'align-center' icon iconAltTextAlignCenter: "Center", // Alt-text for the 'position-right' icon iconAltTextAlignRight: "Right", // Alt-text for the 'close' icon iconAltTextClose: "Close", // Default text for the 'loading data' overlay overlayLoadingData: "Loading data...", // Default text for the 'no data' overlay overlayNoData: "No data to display", // Default text for the 'no visible series' overlay overlayNoVisibleSeries: "No visible series", // Default text for the 'unsupported browser' overlay overlayUnsupportedBrowser: "Incompatible browser version. Please upgrade your browser.", // Text for frequency label in Histogram Series tooltip seriesHistogramTooltipFrequency: "Frequency", // Text for sum label in Histogram Series tooltip seriesHistogramTooltipSum: "${yName} (sum)", // Text for sum label in Histogram Series tooltip seriesHistogramTooltipCount: "${yName} (count)", // Text for sum label in Histogram Series tooltip seriesHistogramTooltipMean: "${yName} (mean)", // Text for the series type toolbar's chart type button toolbarSeriesTypeDropdown: "Chart Type", // Text for the series type toolbar's OHLC chart type button toolbarSeriesTypeOHLC: "OHLC", // Text for the series type toolbar's HLC chart type button toolbarSeriesTypeHLC: "HLC", // Text for the series type toolbar's high low chart type button toolbarSeriesTypeHighLow: "High Low", // Text for the series type toolbar's candles chart type button toolbarSeriesTypeCandles: "Candles", // Text for the series type toolbar's hollow candles chart type button toolbarSeriesTypeHollowCandles: "Hollow Candles", // Text for the series type toolbar's line chart type button toolbarSeriesTypeLine: "Line", // Text for the series type toolbar's line with markers chart type button toolbarSeriesTypeLineWithMarkers: "Line with Markers", // Text for the series type toolbar's line with step line chart type button toolbarSeriesTypeStepLine: "Step Line", // Text for the annotation toolbar's trend line button toolbarAnnotationsTrendLine: "Trend Line", // Text for the annotation toolbar's Fibonacci Retracement button toolbarAnnotationsFibonacciRetracement: "Fib Retracement", // Text for the annotation toolbar's Fibonacci Retracement Trend Based button toolbarAnnotationsFibonacciRetracementTrendBased: "Fib Trend Based", // Text for the annotation toolbar's horizontal line button toolbarAnnotationsHorizontalLine: "Horizontal Line", // Text for the annotation toolbar's vertical line button toolbarAnnotationsVerticalLine: "Vertical Line", // Text for the annotation toolbar's parallel channel button toolbarAnnotationsParallelChannel: "Parallel Channel", // Text for the annotation toolbar's disjoint channel button toolbarAnnotationsDisjointChannel: "Disjoint Channel", // Text for the annotation toolbar's clear all button toolbarAnnotationsClearAll: "Clear All", // Text for the annotation toolbar's fill color picker annotation button toolbarAnnotationsFillColor: "Fill Color", // Text for the annotation toolbar's line color picker annotation button toolbarAnnotationsLineColor: "Line Color", // Text for the annotation toolbar's line style type button toolbarAnnotationsLineStyle: "Line Style", // Text for the annotation toolbar's line stroke width button toolbarAnnotationsLineStrokeWidth: "Line Stroke Width", // Text for the annotation toolbar's settings annotation button toolbarAnnotationsSettings: "Settings", // Text for the annotation toolbar's text color picker annotation button toolbarAnnotationsTextColor: "Text Color", // Text for the annotation toolbar's text size picker annotation button toolbarAnnotationsTextSize: "Text Size", // Text for the annotation toolbar's lock annotation button toolbarAnnotationsLock: "Lock", // Text for the annotation toolbar's unlock annotation button toolbarAnnotationsUnlock: "Unlock", // Text for the annotation toolbar's delete annotation button toolbarAnnotationsDelete: "Delete", // Text for the annotation toolbar's drag handle toolbarAnnotationsDragHandle: "Drag Toolbar", // Text for the annotation toolbar's line drawings menu button toolbarAnnotationsLineAnnotations: "Trend Lines", // Text for the annotation toolbar's Fibonacci drawings menu button toolbarAnnotationsFibonacciAnnotations: "Fibonacci", // Text for the annotation toolbar's text annotations menu button toolbarAnnotationsTextAnnotations: "Text Annotations", // Text for the annotation toolbar's shapes menu button toolbarAnnotationsShapeAnnotations: "Arrows", // Text for the annotation toolbar's measurers menu button toolbarAnnotationsMeasurerAnnotations: "Measurers", // Text for the annotation toolbar's callout button toolbarAnnotationsCallout: "Callout", // Text for the annotation toolbar's comment button toolbarAnnotationsComment: "Comment", // Text for the annotation toolbar's note button toolbarAnnotationsNote: "Note", // Text for the annotation toolbar's text button toolbarAnnotationsText: "Text", // Text for the annotation toolbar's arrow button toolbarAnnotationsArrow: "Arrow", // Text for the annotation toolbar's arrow up button toolbarAnnotationsArrowUp: "Arrow Up", // Text for the annotation toolbar's arrow down button toolbarAnnotationsArrowDown: "Arrow Down", // Text for the annotation toolbar's date range button toolbarAnnotationsDateRange: "Date Range", // Text for the annotation toolbar's price range button toolbarAnnotationsPriceRange: "Price Range", // Text for the annotation toolbar's date and price range button toolbarAnnotationsDatePriceRange: "Date and Price", // Text for the annotation toolbar's quick date and price range button toolbarAnnotationsQuickDatePriceRange: "Measure", // Text for the range toolbar's 1 month button toolbarRange1Month: "1M", // Aria label for the range toolbar's 1 month button toolbarRange1MonthAria: "1 month", // Text for the range toolbar's 3 month button toolbarRange3Months: "3M", // Aria label for the range toolbar's 3 month button toolbarRange3MonthsAria: "3 months", // Text for the range toolbar's 6 month button toolbarRange6Months: "6M", // Aria label for the range toolbar's 6 month button toolbarRange6MonthsAria: "6 months", // Text for the range toolbar's year to date button toolbarRangeYearToDate: "YTD", // Aria label for the range toolbar's year to date month button toolbarRangeYearToDateAria: "Year to date", // Text for the range toolbar's 1 year button toolbarRange1Year: "1Y", // Aria label for the range toolbar's 1 year button toolbarRange1YearAria: "1 year", // Text for the range toolbar's full range button toolbarRangeAll: "All", // Aria label for the range toolbar's full range button toolbarRangeAllAria: "All", // Text for the zoom toolbar's zoom out button toolbarZoomZoomOut: "Zoom out", // Text for the zoom toolbar's zoom in button toolbarZoomZoomIn: "Zoom in", // Text for the zoom toolbar's pan left button toolbarZoomPanLeft: "Pan left", // Text for the zoom toolbar's pan right button toolbarZoomPanRight: "Pan right", // Text for the zoom toolbar's pan to the start button toolbarZoomPanStart: "Pan to the start", // Text for the zoom toolbar's pan to the end button toolbarZoomPanEnd: "Pan to the end", // Text for the zoom toolbar's pan reset button toolbarZoomReset: "Reset the zoom", // Text for the context menu's download button contextMenuDownload: "Download", // Text for the context menu's toggle series visibility button contextMenuToggleSeriesVisibility: "Toggle Visibility", // Text for the context menu's toggle other series visibility button contextMenuToggleOtherSeries: "Toggle Other Series", // Text for the context menu's zoom to point button contextMenuZoomToCursor: "Zoom to here", // Text for the context menu's pan to point button contextMenuPanToCursor: "Pan to here", // Text for the annotation dialog's header channel tab label dialogHeaderChannel: "Channel", // Text for the annotation dialog's header line tab label dialogHeaderLine: "Line", // Text for the annotation dialog's header fibonacci retracement line tab label dialogHeaderFibonacciRange: "Fib Retracement", // Text for the annotation dialog's header date range tab label dialogHeaderDateRange: "Date Range", // Text for the annotation dialog's header price range tab label dialogHeaderPriceRange: "Price Range", // Text for the annotation dialog's header date and price range tab label dialogHeaderDatePriceRange: "Date and Price", // Text for the annotation dialog's header text tab label dialogHeaderText: "Text", // Text for the annotation dialog's text alignment radio label dialogInputAlign: "Align", // Text for the annotation dialog's color picker label dialogInputColorPicker: "Color", // Text for the annotation dialog's color picker alt text dialogInputColorPickerAltText: "Text Color", // Text for the annotation dialog's fill color picker label dialogInputFillColorPicker: "Fill", // Text for the annotation dialog's fill color picker alt text dialogInputFillColorPickerAltText: "Fill Color", // Text for the annotation dialog's extend channel start checkbox dialogInputExtendChannelStart: "Extend channel start", // Text for the annotation dialog's extend channel end checkbox dialogInputExtendChannelEnd: "Extend channel end", // Text for the annotation dialog's extend line start checkbox dialogInputExtendLineStart: "Extend line start", // Text for the annotation dialog's extend line end checkbox dialogInputExtendLineEnd: "Extend line end", // Text for the annotation dialog's extend above checkbox dialogInputExtendAbove: "Extend above", // Text for the annotation dialog's extend below checkbox dialogInputExtendBelow: "Extend below", // Text for the annotation dialog's extend left checkbox dialogInputExtendLeft: "Extend left", // Text for the annotation dialog's extend right checkbox dialogInputExtendRight: "Extend right", // Text for the annotation dialog's reverse checkbox dialogInputReverse: "Reverse", // Text for the annotation dialog's show fill checkbox dialogInputShowFill: "Show Fill", // Text for the annotation dialog's font size select box label dialogInputFontSize: "Size", // Text for the annotation dialog's font size select box alt text dialogInputFontSizeAltText: "Font Size", // Text for the annotation dialog's line style radio label dialogInputLineStyle: "Dash", // Text for the annotation dialog's text position radio label dialogInputPosition: "Position", // Text for the annotation dialog's stroke width label dialogInputStrokeWidth: "Weight", // Text for the annotation dialog's stroke width label dialogInputStrokeWidthAltText: "Line Weight", // Text for the annotation dialog's Fibonacci bands label dialogInputFibonacciBands: "Bands", // Text for the annotation dialog's Fibonacci bands label dialogInputFibonacciBandsAltText: "Fibonacci Bands", // Text for text area input placeholders inputTextareaPlaceholder: "Add Text", // Text for the measurer statistics date range bars value measurerDateRangeBars: "${value}[number] bars", // Text for the measurer statistics price range value measurerPriceRangeValue: "${value}[number]", // Text for the measurer statistics price range percentage measurerPriceRangePercent: "${value}[percent]", // Text for the measurer statistics volume value measurerVolume: "Vol ${value}" }; } }); // packages/ag-charts-locale/src/es-ES.ts var init_es_ES = __esm({ "packages/ag-charts-locale/src/es-ES.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/fa-IR.ts var init_fa_IR = __esm({ "packages/ag-charts-locale/src/fa-IR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/fi-FI.ts var init_fi_FI = __esm({ "packages/ag-charts-locale/src/fi-FI.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/fr-FR.ts var init_fr_FR = __esm({ "packages/ag-charts-locale/src/fr-FR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/he-IL.ts var init_he_IL = __esm({ "packages/ag-charts-locale/src/he-IL.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/hr-HR.ts var init_hr_HR = __esm({ "packages/ag-charts-locale/src/hr-HR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/hu-HU.ts var init_hu_HU = __esm({ "packages/ag-charts-locale/src/hu-HU.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/it-IT.ts var init_it_IT = __esm({ "packages/ag-charts-locale/src/it-IT.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/ja-JP.ts var init_ja_JP = __esm({ "packages/ag-charts-locale/src/ja-JP.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/ko-KR.ts var init_ko_KR = __esm({ "packages/ag-charts-locale/src/ko-KR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/nb-NO.ts var init_nb_NO = __esm({ "packages/ag-charts-locale/src/nb-NO.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/nl-NL.ts var init_nl_NL = __esm({ "packages/ag-charts-locale/src/nl-NL.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/pl-PL.ts var init_pl_PL = __esm({ "packages/ag-charts-locale/src/pl-PL.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/pt-BR.ts var init_pt_BR = __esm({ "packages/ag-charts-locale/src/pt-BR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/pt-PT.ts var init_pt_PT = __esm({ "packages/ag-charts-locale/src/pt-PT.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/ro-RO.ts var init_ro_RO = __esm({ "packages/ag-charts-locale/src/ro-RO.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/sk-SK.ts var init_sk_SK = __esm({ "packages/ag-charts-locale/src/sk-SK.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/sv-SE.ts var init_sv_SE = __esm({ "packages/ag-charts-locale/src/sv-SE.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/tr-TR.ts var init_tr_TR = __esm({ "packages/ag-charts-locale/src/tr-TR.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/uk-UA.ts var init_uk_UA = __esm({ "packages/ag-charts-locale/src/uk-UA.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/ur-PK.ts var init_ur_PK = __esm({ "packages/ag-charts-locale/src/ur-PK.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/vi-VN.ts var init_vi_VN = __esm({ "packages/ag-charts-locale/src/vi-VN.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/zh-CN.ts var init_zh_CN = __esm({ "packages/ag-charts-locale/src/zh-CN.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/zh-HK.ts var init_zh_HK = __esm({ "packages/ag-charts-locale/src/zh-HK.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/zh-TW.ts var init_zh_TW = __esm({ "packages/ag-charts-locale/src/zh-TW.ts"() { "use strict"; } }); // packages/ag-charts-locale/src/main.ts var init_main2 = __esm({ "packages/ag-charts-locale/src/main.ts"() { "use strict"; init_ar_EG(); init_bg_BG(); init_cs_CZ(); init_da_DK(); init_de_DE(); init_el_GR(); init_en_US(); init_es_ES(); init_fa_IR(); init_fi_FI(); init_fr_FR(); init_he_IL(); init_hr_HR(); init_hu_HU(); init_it_IT(); init_ja_JP(); init_ko_KR(); init_nb_NO(); init_nl_NL(); init_pl_PL(); init_pt_BR(); init_pt_PT(); init_ro_RO(); init_sk_SK(); init_sv_SE(); init_tr_TR(); init_uk_UA(); init_ur_PK(); init_vi_VN(); init_zh_CN(); init_zh_HK(); init_zh_TW(); } }); // packages/ag-charts-community/src/locale/defaultMessageFormatter.ts var messageRegExp, formatters, defaultMessageFormatter; var init_defaultMessageFormatter = __esm({ "packages/ag-charts-community/src/locale/defaultMessageFormatter.ts"() { "use strict"; init_main(); messageRegExp = /\$\{(\w+)}(?:\[(\w+)])?/gi; formatters = { number: new Intl.NumberFormat("en-US"), percent: new Intl.NumberFormat("en-US", { style: "percent", minimumFractionDigits: 2, maximumFractionDigits: 2 }), date: new Intl.DateTimeFormat("en-US", { dateStyle: "full" }), time: new Intl.DateTimeFormat("en-US", { timeStyle: "full" }), datetime: new Intl.DateTimeFormat("en-US", { dateStyle: "full", timeStyle: "full" }) }; defaultMessageFormatter = ({ defaultValue, variables }) => { return defaultValue?.replaceAll(messageRegExp, (_, match, format) => { const value = variables[match]; const formatter = format != null ? formatters[format] : null; if (format != null && formatter == null) { logger_exports.warnOnce(`Format style [${format}] is not supported`); } if (formatter != null) { return formatter.format(value); } else if (typeof value === "number") { return formatters.number.format(value); } else if (value instanceof Date) { return formatters.datetime.format(value); } return String(value); }); }; } }); // packages/ag-charts-community/src/locale/localeManager.ts var LocaleManager; var init_localeManager = __esm({ "packages/ag-charts-community/src/locale/localeManager.ts"() { "use strict"; init_main2(); init_listeners(); init_defaultMessageFormatter(); LocaleManager = class extends Listeners { constructor() { super(...arguments); this.localeText = void 0; this.getLocaleText = void 0; } setLocaleText(localeText) { if (this.localeText !== localeText) { this.localeText = localeText; this.dispatch("locale-changed"); } } setLocaleTextFormatter(getLocaleText) { this.getLocaleText = getLocaleText; if (this.getLocaleText !== getLocaleText) { this.getLocaleText = getLocaleText; this.dispatch("locale-changed"); } } t(key, variables = {}) { const { localeText = AG_CHARTS_LOCALE_EN_US, getLocaleText } = this; const defaultValue = localeText[key]; return getLocaleText?.({ key, defaultValue, variables }) ?? defaultMessageFormatter({ key, defaultValue, variables }) ?? key; } }; } }); // packages/ag-charts-community/src/scene/canvas/hdpiCanvas.ts var HdpiCanvas; var init_hdpiCanvas = __esm({ "packages/ag-charts-community/src/scene/canvas/hdpiCanvas.ts"() { "use strict"; init_core(); init_proxy(); init_canvasUtil(); HdpiCanvas = class { constructor(options) { this.enabled = true; this.width = 600; this.height = 300; const { width: width2, height: height2, canvasElement, willReadFrequently = false } = options; this.pixelRatio = options.pixelRatio ?? getWindow("devicePixelRatio") ?? 1; this.element = canvasElement ?? createElement("canvas"); this.element.style.display = "block"; this.element.style.width = (width2 ?? this.width) + "px"; this.element.style.height = (height2 ?? this.height) + "px"; this.element.width = Math.round((width2 ?? this.width) * this.pixelRatio); this.element.height = Math.round((height2 ?? this.height) * this.pixelRatio); this.context = this.element.getContext("2d", { willReadFrequently }); this.onEnabledChange(); this.resize(width2 ?? 0, height2 ?? 0, this.pixelRatio); debugContext(this.context); } drawImage(context, dx2 = 0, dy2 = 0) { return context.drawImage(this.context.canvas, dx2, dy2); } toDataURL(type) { return this.element.toDataURL(type); } resize(width2, height2, pixelRatio) { if (!(width2 > 0 && height2 > 0)) return; const { element: element2, context } = this; element2.width = Math.round(width2 * pixelRatio); element2.height = Math.round(height2 * pixelRatio); context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); element2.style.width = width2 + "px"; element2.style.height = height2 + "px"; this.width = width2; this.height = height2; this.pixelRatio = pixelRatio; } clear() { clearContext(this); } destroy() { this.element.remove(); this.element.width = 0; this.element.height = 0; this.context.clearRect(0, 0, 0, 0); Object.freeze(this); } onEnabledChange() { if (this.element) { this.element.style.display = this.enabled ? "" : "none"; } } }; __decorateClass([ ObserveChanges((target) => target.onEnabledChange()) ], HdpiCanvas.prototype, "enabled", 2); } }); // packages/ag-charts-community/src/scene/layersManager.ts var LayersManager; var init_layersManager = __esm({ "packages/ag-charts-community/src/scene/layersManager.ts"() { "use strict"; init_debug(); init_hdpiOffscreenCanvas(); LayersManager = class { constructor(canvas) { this.canvas = canvas; this.debug = Debug.create(true, "scene"); this.layersMap = /* @__PURE__ */ new Map(); this.nextLayerId = 0; } get size() { return this.layersMap.size; } resize(width2, height2, pixelRatio) { this.canvas.resize(width2, height2, pixelRatio); this.layersMap.forEach(({ canvas }) => canvas.resize(width2, height2, pixelRatio)); } addLayer(opts) { const { width: width2, height: height2, pixelRatio } = this.canvas; const { name } = opts; const canvas = new HdpiOffscreenCanvas({ width: width2, height: height2, pixelRatio }); this.layersMap.set(canvas, { id: this.nextLayerId++, name, canvas }); this.debug("Scene.addLayer() - layers", this.layersMap); return canvas; } removeLayer(canvas) { if (this.layersMap.has(canvas)) { this.layersMap.delete(canvas); canvas.destroy(); this.debug("Scene.removeLayer() - layers", this.layersMap); } } clear() { for (const layer of this.layersMap.values()) { layer.canvas.destroy(); } this.layersMap.clear(); } }; } }); // packages/ag-charts-community/src/scene/sceneDebug.ts function formatBytes(value) { for (const unit of ["B", "KB", "MB", "GB"]) { if (value < 1536) { return `${value.toFixed(1)}${unit}`; } value /= 1024; } return `${value.toFixed(1)}TB}`; } function memoryUsage() { if (!("memory" in performance)) return; const { totalJSHeapSize, usedJSHeapSize, jsHeapSizeLimit } = performance.memory; const result = []; for (const amount of [usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit]) { if (typeof amount !== "number") continue; result.push(formatBytes(amount)); } return `Heap ${result.join(" / ")}`; } function debugStats(layersManager, debugSplitTimes, ctx, renderCtxStats, extraDebugStats = {}, seriesRect = BBox.zero) { if (!Debug.check("scene:stats" /* SCENE_STATS */, "scene:stats:verbose" /* SCENE_STATS_VERBOSE */)) return; const { layersRendered = 0, layersSkipped = 0, nodesRendered = 0, nodesSkipped = 0, opsPerformed = 0, opsSkipped = 0 } = renderCtxStats ?? {}; const end2 = performance.now(); const { start: start2, ...durations } = debugSplitTimes; const splits = Object.entries(durations).map(([n, t]) => { return time(n, t); }).filter((v) => v != null).join(" + "); const extras = Object.entries(extraDebugStats).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(" ; "); const detailedStats = Debug.check("scene:stats:verbose" /* SCENE_STATS_VERBOSE */); const memUsage = memoryUsage(); const stats = [ `${time("\u23F1\uFE0F", start2, end2)} (${splits})`, `${extras}`, `Layers: ${detailedStats ? pct(layersRendered, layersSkipped) : layersManager.size}`, detailedStats ? `Nodes: ${pct(nodesRendered, nodesSkipped)}` : null, detailedStats ? `Ops: ${pct(opsPerformed, opsSkipped)}` : null, detailedStats && memUsage ? memUsage : null ].filter(isString); const measurer3 = new SimpleTextMeasurer((t) => ctx.measureText(t)); const statsSize = new Map(stats.map((t) => [t, measurer3.measureLines(t)])); const width2 = Math.max(...Array.from(statsSize.values(), (s) => s.width)); const height2 = accumulate(statsSize.values(), (s) => s.height); const x = 2 + seriesRect.x; ctx.save(); ctx.fillStyle = "white"; ctx.fillRect(x, 0, width2, height2); ctx.fillStyle = "black"; let y = 0; for (const [stat, size] of statsSize.entries()) { y += size.height; ctx.fillText(stat, x, y); } ctx.restore(); } function prepareSceneNodeHighlight(ctx) { const config = toArray(getWindow("agChartsSceneDebug")); const result = []; for (const name of config) { if (name === "layout") { result.push("seriesRoot", "legend", "root", /.*Axis-\d+-axis.*/); } else { result.push(name); } } ctx.debugNodeSearch = result; } function debugSceneNodeHighlight(ctx, debugNodes) { ctx.save(); for (const [name, node] of Object.entries(debugNodes)) { const bbox = Transformable.toCanvas(node); if (!bbox) { logger_exports.log(`Scene.render() - no bbox for debugged node [${name}].`); continue; } ctx.globalAlpha = 0.8; ctx.strokeStyle = "red"; ctx.lineWidth = 1; ctx.strokeRect(bbox.x, bbox.y, bbox.width, bbox.height); ctx.fillStyle = "red"; ctx.strokeStyle = "white"; ctx.font = "16px sans-serif"; ctx.textBaseline = "top"; ctx.textAlign = "left"; ctx.lineWidth = 2; ctx.strokeText(name, bbox.x, bbox.y, bbox.width); ctx.fillText(name, bbox.x, bbox.y, bbox.width); } ctx.restore(); } function nodeProps(node) { const { ...allProps } = node; for (const prop of Object.keys(allProps)) { if (allowedProperties.has(prop)) continue; if (typeof allProps[prop] === "number") continue; if (typeof allProps[prop] === "string") continue; if (typeof allProps[prop] === "boolean") continue; skippedProperties.add(prop); delete allProps[prop]; } return allProps; } function buildTree(node, mode) { if (!Debug.check(true, "scene" /* SCENE */)) { return {}; } let order = 0; return { node: mode === "json" ? nodeProps(node) : node, name: node.name ?? node.id, dirty: node.dirty, ...Array.from(node.children(), (c) => buildTree(c, mode)).reduce( (result, childTree) => { let { name: treeNodeName } = childTree; const { node: { visible, opacity, zIndex, translationX, translationY, rotation, scalingX, scalingY }, node: childNode } = childTree; if (!visible || opacity <= 0) { treeNodeName = `(${treeNodeName})`; } if (Group.is(childNode) && childNode.renderToOffscreenCanvas) { treeNodeName = `*${treeNodeName}*`; } const zIndexString = Array.isArray(zIndex) ? `(${zIndex.join(", ")})` : zIndex; const key = [ `${(order++).toString().padStart(3, "0")}|`, `${treeNodeName ?? ""}`, `z: ${zIndexString}`, translationX && `x: ${translationX}`, translationY && `y: ${translationY}`, rotation && `r: ${rotation}`, scalingX != null && scalingX !== 1 && `sx: ${scalingX}`, scalingY != null && scalingY !== 1 && `sy: ${scalingY}` ].filter((v) => !!v).join(" "); let selectedKey = key; let index = 1; while (result[selectedKey] != null && index < 100) { selectedKey = `${key} (${index++})`; } result[selectedKey] = childTree; return result; }, {} ) }; } function buildDirtyTree(node) { if (!node.dirty) { return { dirtyTree: {}, paths: [] }; } const childrenDirtyTree = Array.from(node.children(), (c) => buildDirtyTree(c)).filter((c) => c.paths.length > 0); const name = Group.is(node) ? node.name ?? node.id : node.id; const paths = childrenDirtyTree.length ? childrenDirtyTree.flatMap((c) => c.paths).map((p) => `${name}.${p}`) : [name]; return { dirtyTree: { name, node, dirty: node.dirty, ...childrenDirtyTree.map((c) => c.dirtyTree).filter((t) => t.dirty != null).reduce((result, childTree) => { result[childTree.name ?? ""] = childTree; return result; }, {}) }, paths }; } function pct(rendered, skipped) { const total = rendered + skipped; return `${rendered} / ${total} (${Math.round(100 * rendered / total)}%)`; } function time(name, start2, end2) { const duration = end2 != null ? end2 - start2 : start2; return `${name}: ${Math.round(duration * 100) / 100}ms`; } function accumulate(iterator, mapper) { let sum2 = 0; for (const item of iterator) { sum2 += mapper(item); } return sum2; } var skippedProperties, allowedProperties; var init_sceneDebug = __esm({ "packages/ag-charts-community/src/scene/sceneDebug.ts"() { "use strict"; init_main(); init_core(); init_debug(); init_textMeasurer(); init_bbox(); init_group(); init_transformable(); skippedProperties = /* @__PURE__ */ new Set(); allowedProperties = /* @__PURE__ */ new Set([ "gradient", // '_datum', "zIndex", "clipRect", "cachedBBox", "childNodeCounts", "path", "__zIndex", "name", "__scalingCenterX", "__scalingCenterY", "__rotationCenterX", "__rotationCenterY", "_previousDatum", "__fill", "__lineDash", "borderPath", "borderClipPath", "_clipPath" ]); } }); // packages/ag-charts-community/src/scene/scene.ts var Scene; var init_scene = __esm({ "packages/ag-charts-community/src/scene/scene.ts"() { "use strict"; init_core(); init_debug(); init_id(); init_hdpiCanvas(); init_layersManager(); init_node(); init_sceneDebug(); Scene = class { constructor(canvasOptions) { this.debug = Debug.create(true, "scene" /* SCENE */); this.id = createId(this); this.root = null; this.pendingSize = null; this.isDirty = false; this.canvas = new HdpiCanvas(canvasOptions); this.layersManager = new LayersManager(this.canvas); } get width() { return this.pendingSize?.[0] ?? this.canvas.width; } get height() { return this.pendingSize?.[1] ?? this.canvas.height; } get pixelRatio() { return this.pendingSize?.[2] ?? this.canvas.pixelRatio; } /** @deprecated v10.2.0 Only used by AG Grid Sparklines */ setContainer(value) { const { element: element2 } = this.canvas; element2.parentElement?.removeChild(element2); value.appendChild(element2); return this; } setRoot(node) { if (this.root === node) { return this; } this.isDirty = true; this.root?._setLayerManager(); this.root = node; if (node) { node.visible = true; node._setLayerManager(this.layersManager); } return this; } clear() { this.canvas.clear(); } attachNode(node) { this.appendChild(node); return () => this.removeChild(node); } appendChild(node) { this.root?.appendChild(node); return this; } removeChild(node) { this.root?.removeChild(node); return this; } download(fileName, fileFormat) { downloadUrl(this.canvas.toDataURL(fileFormat), fileName?.trim() ?? "image"); } /** NOTE: Integrated Charts undocumented image download method. */ getDataURL(fileFormat) { return this.canvas.toDataURL(fileFormat); } resize(width2, height2, pixelRatio) { width2 = Math.round(width2); height2 = Math.round(height2); pixelRatio ?? (pixelRatio = this.pixelRatio); if (width2 > 0 && height2 > 0 && (width2 !== this.width || height2 !== this.height || pixelRatio !== this.pixelRatio)) { this.pendingSize = [width2, height2, pixelRatio]; this.isDirty = true; return true; } return false; } render(opts) { const { debugSplitTimes = { start: performance.now() }, extraDebugStats, seriesRect } = opts ?? {}; const { canvas, canvas: { context: ctx } = {}, root, pendingSize, width: width2, height: height2, pixelRatio: devicePixelRatio } = this; if (!ctx) { return; } const renderStartTime = performance.now(); if (pendingSize) { this.layersManager.resize(...pendingSize); this.pendingSize = null; } if (root && !root.visible) { this.isDirty = false; return; } if (root?.dirty === false && !this.isDirty) { if (this.debug.check()) { this.debug("Scene.render() - no-op", { tree: buildTree(root, "console") }); } debugStats(this.layersManager, debugSplitTimes, ctx, void 0, extraDebugStats, seriesRect); return; } const renderCtx = { ctx, width: width2, height: height2, devicePixelRatio, debugNodes: {} }; if (Debug.check("scene:stats:verbose" /* SCENE_STATS_VERBOSE */)) { renderCtx.stats = { layersRendered: 0, layersSkipped: 0, nodesRendered: 0, nodesSkipped: 0, opsPerformed: 0, opsSkipped: 0 }; } prepareSceneNodeHighlight(renderCtx); let canvasCleared = false; if (root?.dirty !== false) { canvasCleared = true; canvas.clear(); } if (root && Debug.check("scene:dirtyTree" /* SCENE_DIRTY_TREE */)) { const { dirtyTree, paths } = buildDirtyTree(root); Debug.create("scene:dirtyTree" /* SCENE_DIRTY_TREE */)("Scene.render() - dirtyTree", { dirtyTree, paths }); } if (root && canvasCleared) { if (root.visible) { root.preRender(renderCtx); } if (this.debug.check()) { const tree = buildTree(root, "console"); this.debug("Scene.render() - before", { canvasCleared, tree }); } if (root.visible) { ctx.save(); root.render(renderCtx); ctx.restore(); } } debugSplitTimes["\u270D\uFE0F"] = performance.now() - renderStartTime; ctx.verifyDepthZero?.(); this.isDirty = false; debugStats(this.layersManager, debugSplitTimes, ctx, renderCtx.stats, extraDebugStats, seriesRect); debugSceneNodeHighlight(ctx, renderCtx.debugNodes); if (root && this.debug.check()) { this.debug("Scene.render() - after", { tree: buildTree(root, "console"), canvasCleared }); } } toSVG() { const { root, width: width2, height: height2 } = this; if (root == null) return; return Node.toSVG(root, width2, height2); } /** Alternative to destroy() that preserves re-usable resources. */ strip() { const { context, pixelRatio } = this.canvas; context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); this.layersManager.clear(); this.setRoot(null); this.isDirty = false; } destroy() { this.strip(); this.canvas.destroy(); Object.assign(this, { canvas: void 0 }); } }; Scene.className = "Scene"; } }); // packages/ag-charts-community/src/util/callbackCache.ts var CallbackCache; var init_callbackCache = __esm({ "packages/ag-charts-community/src/util/callbackCache.ts"() { "use strict"; init_main(); CallbackCache = class { constructor() { this.cache = /* @__PURE__ */ new WeakMap(); } call(fn, ...params) { let serialisedParams; let paramCache = this.cache.get(fn); try { serialisedParams = JSON.stringify(params); } catch { return this.invoke(fn, params, paramCache); } if (paramCache == null) { paramCache = /* @__PURE__ */ new Map(); this.cache.set(fn, paramCache); } if (!paramCache.has(serialisedParams)) { return this.invoke(fn, params, paramCache, serialisedParams); } return paramCache.get(serialisedParams); } invoke(fn, params, paramCache, serialisedParams) { try { const result = fn(...params); if (paramCache && serialisedParams != null) { paramCache.set(serialisedParams, result); } return result; } catch (e) { logger_exports.warnOnce(`User callback errored, ignoring`, e); return; } } invalidateCache() { this.cache = /* @__PURE__ */ new WeakMap(); } }; } }); // packages/ag-charts-community/src/chart/annotation/annotationManager.ts var AnnotationManager; var init_annotationManager = __esm({ "packages/ag-charts-community/src/chart/annotation/annotationManager.ts"() { "use strict"; init_main(); init_baseManager(); init_object(); AnnotationManager = class extends BaseManager { constructor(annotationRoot) { super(); this.annotationRoot = annotationRoot; this.mementoOriginatorKey = "annotations"; this.annotations = []; } createMemento() { return this.annotations; } guardMemento(blob) { return blob == null || isArray(blob); } restoreMemento(_version, _mementoVersion, memento) { this.annotations = this.cleanData(memento ?? []).map((annotation) => { const annotationTheme = this.getAnnotationTypeStyles(annotation.type); return mergeDefaults(annotation, annotationTheme); }); this.listeners.dispatch("restore-annotations", { type: "restore-annotations", annotations: this.annotations }); } updateData(annotations) { this.annotations = this.cleanData(annotations ?? []); } attachNode(node) { this.annotationRoot.append(node); return () => { this.annotationRoot?.removeChild(node); return this; }; } setAnnotationStyles(styles) { this.styles = styles; } getAnnotationTypeStyles(type) { return this.styles?.[type]; } cleanData(annotations) { for (const annotation of annotations) { if ("textAlign" in annotation) delete annotation.textAlign; } return annotations; } }; } }); // packages/ag-charts-community/src/chart/axis/axisManager.ts var AxisManager; var init_axisManager = __esm({ "packages/ag-charts-community/src/chart/axis/axisManager.ts"() { "use strict"; init_group(); AxisManager = class { constructor(sceneRoot) { this.sceneRoot = sceneRoot; this.axes = /* @__PURE__ */ new Map(); this.axisGridGroup = new Group({ name: "Axes-Grids", zIndex: 1 /* AXIS_GRID */ }); this.axisGroup = new Group({ name: "Axes", zIndex: 2 /* AXIS */ }); this.axisLabelGroup = new Group({ name: "Axes-Labels", zIndex: 13 /* SERIES_LABEL */ }); this.axisCrosslineRangeGroup = new Group({ name: "Axes-Crosslines-Range", zIndex: 4 /* SERIES_CROSSLINE_RANGE */ }); this.axisCrosslineLineGroup = new Group({ name: "Axes-Crosslines-Line", zIndex: 8 /* SERIES_CROSSLINE_LINE */ }); this.axisCrosslineLabelGroup = new Group({ name: "Axes-Crosslines-Label", zIndex: 13 /* SERIES_LABEL */ }); this.sceneRoot.appendChild(this.axisGroup); this.sceneRoot.appendChild(this.axisGridGroup); this.sceneRoot.appendChild(this.axisLabelGroup); this.sceneRoot.appendChild(this.axisCrosslineRangeGroup); this.sceneRoot.appendChild(this.axisCrosslineLineGroup); this.sceneRoot.appendChild(this.axisCrosslineLabelGroup); } updateAxes(oldAxes, newAxes) { const axisNodes = { axisNode: this.axisGroup, gridNode: this.axisGridGroup, labelNode: this.axisLabelGroup, crossLineRangeNode: this.axisCrosslineRangeGroup, crossLineLineNode: this.axisCrosslineLineGroup, crossLineLabelNode: this.axisCrosslineLabelGroup }; for (const axis of oldAxes) { if (newAxes.includes(axis)) continue; axis.detachAxis(axisNodes); axis.destroy(); } for (const axis of newAxes) { if (oldAxes?.includes(axis)) continue; axis.attachAxis(axisNodes); } this.axes.clear(); for (const axis of newAxes) { const ctx = axis.createAxisContext(); if (this.axes.has(ctx.direction)) { this.axes.get(ctx.direction)?.push(ctx); } else { this.axes.set(ctx.direction, [ctx]); } } } getAxisContext(direction) { return this.axes.get(direction) ?? []; } destroy() { this.axes.clear(); this.sceneRoot.removeChild(this.axisGroup); this.sceneRoot.removeChild(this.axisGridGroup); } }; } }); // packages/ag-charts-community/src/chart/data/dataService.ts var DataService; var init_dataService = __esm({ "packages/ag-charts-community/src/chart/data/dataService.ts"() { "use strict"; init_main(); init_debug(); init_listeners(); init_proxy(); DataService = class extends Listeners { constructor(animationManager) { super(); this.animationManager = animationManager; this.dispatchOnlyLatest = true; this.dispatchThrottle = 0; this.requestThrottle = 300; this.isLoadingInitialData = false; this.isLoadingData = false; this.freshRequests = []; this.requestCounter = 0; this.debug = Debug.create(true, "data-model", "data-source"); this.throttledFetch = this.createThrottledFetch(this.requestThrottle); this.throttledDispatch = this.createThrottledDispatch(this.dispatchThrottle); } updateCallback(dataSourceCallback) { if (typeof dataSourceCallback !== "function") return; this.debug("DataService - updated data source callback"); this.dataSourceCallback = dataSourceCallback; this.isLoadingInitialData = true; this.animationManager.skip(); this.dispatch("data-source-change"); } clearCallback() { this.dataSourceCallback = void 0; } load(params) { this.isLoadingData = true; this.throttledFetch(params); } isLazy() { return this.dataSourceCallback != null; } isLoading() { return this.isLazy() && (this.isLoadingInitialData || this.isLoadingData); } createThrottledFetch(requestThrottle) { return throttle( (params) => this.fetch(params).catch((e) => logger_exports.error("callback failed", e)), requestThrottle, { leading: false, trailing: true } ); } createThrottledDispatch(dispatchThrottle) { return throttle( (id, data) => { this.debug(`DataService - dispatching 'data-load' | ${id}`); this.dispatch("data-load", { type: "data-load", data }); }, dispatchThrottle, { leading: true, trailing: true } ); } async fetch(params) { if (!this.dataSourceCallback) { throw new Error("DataService - [dataSource.getData] callback not initialised"); } const start2 = performance.now(); const id = this.requestCounter++; this.debug(`DataService - requesting | ${id}`); this.freshRequests.push(id); let response; try { response = await this.dataSourceCallback(params); this.debug(`DataService - response | ${performance.now() - start2}ms | ${id}`); } catch (error3) { this.debug(`DataService - request failed | ${id}`); logger_exports.errorOnce(`DataService - request failed | [${error3}]`); } this.isLoadingInitialData = false; const requestIndex = this.freshRequests.findIndex((rid) => rid === id); if (requestIndex === -1 || this.dispatchOnlyLatest && requestIndex !== this.freshRequests.length - 1) { this.debug(`DataService - discarding stale request | ${id}`); return; } this.freshRequests = this.freshRequests.slice(requestIndex + 1); if (this.freshRequests.length === 0) { this.isLoadingData = false; } if (Array.isArray(response)) { this.throttledDispatch(id, response); } else { this.dispatch("data-error"); } } }; __decorateClass([ ActionOnSet({ newValue(dispatchThrottle) { this.throttledDispatch = this.createThrottledDispatch(dispatchThrottle); } }) ], DataService.prototype, "dispatchThrottle", 2); __decorateClass([ ActionOnSet({ newValue(requestThrottle) { this.throttledFetch = this.createThrottledFetch(requestThrottle); } }) ], DataService.prototype, "requestThrottle", 2); } }); // packages/ag-charts-community/src/chart/interaction/animationBatch.ts var AnimationBatch; var init_animationBatch = __esm({ "packages/ag-charts-community/src/chart/interaction/animationBatch.ts"() { "use strict"; init_main(); init_animation(); init_debug(); AnimationBatch = class { constructor(maxAnimationTime) { this.maxAnimationTime = maxAnimationTime; this.debug = Debug.create(true, "animation"); this.controllers = /* @__PURE__ */ new Map(); this.stoppedCbs = /* @__PURE__ */ new Set(); this.currentPhase = 0; this.phases = new Map(PHASE_ORDER.map((p) => [p, []])); this.skipAnimations = false; this.animationTimeConsumed = 0; /** Guard against premature animation execution. */ this.isReady = false; } get size() { return this.controllers.size; } get consumedTimeMs() { return this.animationTimeConsumed; } isActive() { return this.controllers.size > 0; } getActiveControllers() { return this.phases.get(PHASE_ORDER[this.currentPhase]) ?? []; } checkOverlappingId(id) { if (id != null && this.controllers.has(id)) { this.controllers.get(id).stop(); this.debug(`Skipping animation batch due to update of existing animation: ${id}`); this.skip(); } } addAnimation(animation) { if (animation.isComplete) return; const animationPhaseIdx = PHASE_ORDER.indexOf(animation.phase); if (animationPhaseIdx < this.currentPhase) { this.debug(`Skipping animation due to being for an earlier phase`, animation.id); animation.stop(); return; } this.controllers.set(animation.id, animation); this.phases.get(animation.phase)?.push(animation); } removeAnimation(animation) { this.controllers.delete(animation.id); const phase = this.phases.get(animation.phase); const index = phase?.indexOf(animation); if (index != null && index >= 0) { phase?.splice(index, 1); } } progress(deltaTime) { if (!this.isReady) return; let unusedTime = deltaTime === 0 ? 0.01 : deltaTime; const refresh = () => { const phase2 = PHASE_ORDER[this.currentPhase]; return { phaseControllers: [...this.getActiveControllers()], phase: phase2, phaseMeta: PHASE_METADATA[phase2] }; }; let { phase, phaseControllers, phaseMeta } = refresh(); const arePhasesComplete = () => PHASE_ORDER[this.currentPhase] == null; const progressPhase = () => { ({ phase, phaseControllers, phaseMeta } = refresh()); while (!arePhasesComplete() && phaseControllers.length === 0) { this.currentPhase++; ({ phase, phaseControllers, phaseMeta } = refresh()); this.debug(`AnimationBatch - phase changing to ${phase}`, { unusedTime }, phaseControllers); } }; const total = this.controllers.size; this.debug(`AnimationBatch - ${deltaTime}ms; phase ${phase} with ${phaseControllers?.length} of ${total}`); do { const phaseDeltaTime = unusedTime; const skipPhase = phaseMeta.skipIfNoEarlierAnimations && this.animationTimeConsumed === 0; let completeCount = 0; for (const controller of phaseControllers) { if (skipPhase) { controller.stop(); } else { unusedTime = Math.min(controller.update(phaseDeltaTime), unusedTime); } if (controller.isComplete) { completeCount++; this.removeAnimation(controller); } } this.animationTimeConsumed += phaseDeltaTime - unusedTime; this.debug(`AnimationBatch - updated ${phaseControllers.length} controllers; ${completeCount} completed`); this.debug(`AnimationBatch - animationTimeConsumed: ${this.animationTimeConsumed}`); progressPhase(); } while (unusedTime > 0 && !arePhasesComplete()); if (this.animationTimeConsumed > this.maxAnimationTime) { this.debug(`Animation batch exceeded max animation time, skipping`, [...this.controllers]); this.stop(); } } ready() { if (this.isReady) return; this.isReady = true; this.debug(`AnimationBatch - ready; skipped: ${this.skipAnimations}`, [...this.controllers]); let skipAll = true; for (const [, controller] of this.controllers) { if (controller.duration > 0 && PHASE_METADATA[controller.phase].skipIfNoEarlierAnimations !== true) { skipAll = false; break; } } if (!skipAll) { for (const [, controller] of this.controllers) { if (controller.autoplay) { controller.play(true); } } } } skip(skip = true) { if (this.skipAnimations === false && skip === true) { for (const controller of this.controllers.values()) { controller.stop(); } this.controllers.clear(); } this.skipAnimations = skip; } play() { for (const controller of this.controllers.values()) { controller.play(); } } stop() { for (const controller of this.controllers.values()) { try { controller.stop(); this.removeAnimation(controller); } catch (error3) { logger_exports.error("Error during animation stop", error3); } } this.dispatchStopped(); } stopByAnimationId(id) { if (id != null && this.controllers.has(id)) { const controller = this.controllers.get(id); if (controller) { controller.stop(); this.removeAnimation(controller); } } } stopByAnimationGroupId(id) { for (const controller of this.controllers.values()) { if (controller.groupId === id) { this.stopByAnimationId(controller.id); } } } dispatchStopped() { this.stoppedCbs.forEach((cb) => cb()); this.stoppedCbs.clear(); } isSkipped() { return this.skipAnimations; } destroy() { this.stop(); this.controllers.clear(); } }; } }); // packages/ag-charts-community/src/chart/interaction/interactionManager.ts var InteractionState, InteractionManager; var init_interactionManager = __esm({ "packages/ag-charts-community/src/chart/interaction/interactionManager.ts"() { "use strict"; InteractionState = /* @__PURE__ */ ((InteractionState5) => { InteractionState5[InteractionState5["Default"] = 32] = "Default"; InteractionState5[InteractionState5["ZoomDrag"] = 16] = "ZoomDrag"; InteractionState5[InteractionState5["Annotations"] = 8] = "Annotations"; InteractionState5[InteractionState5["ContextMenu"] = 4] = "ContextMenu"; InteractionState5[InteractionState5["Animation"] = 2] = "Animation"; InteractionState5[InteractionState5["AnnotationsSelected"] = 1] = "AnnotationsSelected"; InteractionState5[InteractionState5["Clickable"] = 41] = "Clickable"; InteractionState5[InteractionState5["Focusable"] = 34] = "Focusable"; InteractionState5[InteractionState5["Keyable"] = 43] = "Keyable"; InteractionState5[InteractionState5["ContextMenuable"] = 36] = "ContextMenuable"; InteractionState5[InteractionState5["AnnotationsMoveable"] = 9] = "AnnotationsMoveable"; InteractionState5[InteractionState5["AnnotationsDraggable"] = 57] = "AnnotationsDraggable"; InteractionState5[InteractionState5["ZoomDraggable"] = 50] = "ZoomDraggable"; InteractionState5[InteractionState5["ZoomClickable"] = 34] = "ZoomClickable"; InteractionState5[InteractionState5["ZoomWheelable"] = 59] = "ZoomWheelable"; InteractionState5[InteractionState5["All"] = 63] = "All"; return InteractionState5; })(InteractionState || {}); InteractionManager = class { constructor() { this.stateQueue = 32 /* Default */ | 2 /* Animation */; } pushState(state) { this.stateQueue |= state; } popState(state) { this.stateQueue &= ~state; } isState(allowedStates) { return !!(this.stateQueue & -this.stateQueue & allowedStates); } }; } }); // packages/ag-charts-community/src/chart/interaction/animationManager.ts function validAnimationDuration(testee) { if (testee == null) return true; return !isNaN(testee) && testee >= 0 && testee <= 2; } var AnimationManager; var init_animationManager = __esm({ "packages/ag-charts-community/src/chart/interaction/animationManager.ts"() { "use strict"; init_main(); init_core(); init_animation(); init_debug(); init_animationBatch(); AnimationManager = class { constructor(interactionManager, chartUpdateMutex) { this.interactionManager = interactionManager; this.chartUpdateMutex = chartUpdateMutex; this.defaultDuration = 1e3; this.batch = new AnimationBatch(this.defaultDuration * 1.5); this.debug = Debug.create(true, "animation"); this.events = new EventEmitter(); this.rafAvailable = typeof requestAnimationFrame !== "undefined"; this.isPlaying = true; this.requestId = null; this.skipAnimations = true; this.currentAnonymousAnimationId = 0; } addListener(eventName, listener) { return this.events.on(eventName, listener); } /** * Create an animation to tween a value between the `from` and `to` properties. If an animation already exists * with the same `id`, immediately stop it. */ animate(opts) { const batch = this.batch; try { batch.checkOverlappingId(opts.id); } catch (error3) { this.failsafeOnError(error3); return; } let { id } = opts; if (id == null) { id = `__${this.currentAnonymousAnimationId}`; this.currentAnonymousAnimationId += 1; } const skip = this.isSkipped() || opts.phase === "none"; if (skip) { this.debug("AnimationManager - skipping animation"); } const { delay, duration } = opts; if (!validAnimationDuration(delay)) { throw new Error(`Animation delay of ${delay} is unsupported (${id})`); } if (!validAnimationDuration(duration)) { throw new Error(`Animation duration of ${duration} is unsupported (${id})`); } const animation = new Animation({ ...opts, id, skip, autoplay: this.isPlaying ? opts.autoplay : false, phase: opts.phase, defaultDuration: this.defaultDuration }); if (this.forceTimeJump(animation, this.defaultDuration)) { return; } this.batch.addAnimation(animation); return animation; } play() { if (this.isPlaying) { return; } this.isPlaying = true; this.debug("AnimationManager.play()"); try { this.batch.play(); } catch (error3) { this.failsafeOnError(error3); } this.requestAnimation(); } stop() { this.isPlaying = false; this.cancelAnimation(); this.debug("AnimationManager.stop()"); this.batch.stop(); } stopByAnimationId(id) { try { this.batch.stopByAnimationId(id); } catch (error3) { this.failsafeOnError(error3); } } stopByAnimationGroupId(id) { try { this.batch.stopByAnimationGroupId(id); } catch (error3) { this.failsafeOnError(error3); } } reset() { if (this.isPlaying) { this.stop(); this.play(); } else { this.stop(); } } skip(skip = true) { this.skipAnimations = skip; } isSkipped() { return !this.rafAvailable || this.skipAnimations || this.batch.isSkipped(); } isActive() { return this.isPlaying && this.batch.isActive(); } skipCurrentBatch() { if (this.debug.check()) { this.debug(`AnimationManager - skipCurrentBatch()`, { stack: new Error().stack }); } this.batch.skip(); } /** Mocking point for tests to guarantee that animation updates happen. */ isSkippingFrames() { return true; } /** Mocking point for tests to capture requestAnimationFrame callbacks. */ scheduleAnimationFrame(cb) { this.requestId = getWindow().requestAnimationFrame((t) => { cb(t).catch((e) => logger_exports.error(e)); }); } /** Mocking point for tests to skip animations to a specific point in time. */ forceTimeJump(_animation, _defaultDuration) { return false; } requestAnimation() { if (!this.rafAvailable) return; if (!this.batch.isActive() || this.requestId !== null) return; let prevTime; const onAnimationFrame = async (time2) => { const executeAnimationFrame = () => { const deltaTime = time2 - (prevTime ?? time2); prevTime = time2; this.debug("AnimationManager - onAnimationFrame()", { controllersCount: this.batch.size, deltaTime }); this.interactionManager.pushState(2 /* Animation */); try { this.batch.progress(deltaTime); } catch (error3) { this.failsafeOnError(error3); } this.events.emit("animation-frame", { type: "animation-frame", deltaMs: deltaTime }); }; if (this.isSkippingFrames()) { await this.chartUpdateMutex.acquireImmediately(executeAnimationFrame); } else { await this.chartUpdateMutex.acquire(executeAnimationFrame); } if (this.batch.isActive()) { this.scheduleAnimationFrame(onAnimationFrame); } else { this.batch.stop(); this.events.emit("animation-stop", { type: "animation-stop", deltaMs: this.batch.consumedTimeMs }); } }; this.events.emit("animation-start", { type: "animation-start", deltaMs: 0 }); this.scheduleAnimationFrame(onAnimationFrame); } cancelAnimation() { if (this.requestId === null) return; cancelAnimationFrame(this.requestId); this.requestId = null; this.startBatch(); } failsafeOnError(error3, cancelAnimation = true) { logger_exports.error("Error during animation, skipping animations", error3); if (cancelAnimation) { this.cancelAnimation(); } } startBatch(skipAnimations) { this.debug(`AnimationManager - startBatch() with skipAnimations=${skipAnimations}.`); this.reset(); this.batch.destroy(); this.batch = new AnimationBatch(this.defaultDuration * 1.5); if (skipAnimations === true) { this.batch.skip(); } } endBatch() { if (this.batch.isActive()) { this.batch.ready(); this.requestAnimation(); } else { this.interactionManager.popState(2 /* Animation */); if (this.batch.isSkipped()) { this.batch.skip(false); } } } onBatchStop(cb) { this.batch.stoppedCbs.add(cb); } destroy() { this.stop(); this.events.clear(); } }; } }); // packages/ag-charts-community/src/chart/interaction/chartEventManager.ts var ChartEventManager; var init_chartEventManager = __esm({ "packages/ag-charts-community/src/chart/interaction/chartEventManager.ts"() { "use strict"; init_baseManager(); ChartEventManager = class extends BaseManager { seriesEvent(type) { this.listeners.dispatch(type, { type }); } seriesKeyNavZoom(delta4, widgetEvent) { const event = { type: "series-keynav-zoom", delta: delta4, widgetEvent }; this.listeners.dispatch("series-keynav-zoom", event); } legendItemClick(legendType, series, itemId, enabled, legendItemName) { const event = { type: "legend-item-click", legendType, series, itemId, enabled, legendItemName }; this.listeners.dispatch("legend-item-click", event); } legendItemDoubleClick(legendType, series, itemId, enabled, numVisibleItems, legendItemName) { const event = { type: "legend-item-double-click", legendType, series, itemId, enabled, legendItemName, numVisibleItems }; this.listeners.dispatch("legend-item-double-click", event); } }; } }); // packages/ag-charts-community/src/chart/interaction/contextMenuRegistry.ts var ContextMenuRegistry; var init_contextMenuRegistry = __esm({ "packages/ag-charts-community/src/chart/interaction/contextMenuRegistry.ts"() { "use strict"; init_listeners(); ContextMenuRegistry = class { constructor() { this.defaultActions = []; this.disabledActions = /* @__PURE__ */ new Set(); this.hiddenActions = /* @__PURE__ */ new Set(); this.listeners = new Listeners(); } static check(type, event) { return event.type === type; } static checkCallback(desiredType, type, _callback) { return desiredType === type; } dispatchContext(type, pointerEvent, context, position) { const { sourceEvent } = pointerEvent; const x = position?.x ?? pointerEvent.canvasX; const y = position?.y ?? pointerEvent.canvasY; sourceEvent.stopPropagation(); const event = { type, x, y, context, sourceEvent }; this.listeners.dispatch("", event); } addListener(handler) { return this.listeners.addListener("", handler); } filterActions(type) { return this.defaultActions.filter((action) => { return action.id != null && !this.hiddenActions.has(action.id) && ["all", type].includes(action.type); }); } registerDefaultAction(action) { const didAdd = action.id != null && !this.defaultActions.some(({ id }) => id === action.id); if (didAdd) { this.defaultActions.push(action); } return () => { const index = didAdd ? this.defaultActions.findIndex(({ id }) => id === action.id) : -1; if (index !== -1) { this.defaultActions.splice(index, 1); } }; } enableAction(actionId) { this.disabledActions.delete(actionId); } disableAction(actionId) { this.disabledActions.add(actionId); } showAction(actionId) { this.hiddenActions.add(actionId); } hideAction(actionId) { this.hiddenActions.delete(actionId); } isDisabled(actionId) { return this.disabledActions.has(actionId); } }; } }); // packages/ag-charts-community/src/chart/interaction/highlightManager.ts var HighlightManager; var init_highlightManager = __esm({ "packages/ag-charts-community/src/chart/interaction/highlightManager.ts"() { "use strict"; init_baseManager(); init_stateTracker(); HighlightManager = class extends BaseManager { constructor() { super(...arguments); this.highlightStates = new StateTracker(); } updateHighlight(callerId, highlightedDatum) { const { activeHighlight: previousHighlight } = this; this.highlightStates.set(callerId, highlightedDatum); this.activeHighlight = this.highlightStates.stateValue(); if (!this.isEqual(this.activeHighlight, previousHighlight)) { this.listeners.dispatch("highlight-change", { type: "highlight-change", currentHighlight: this.activeHighlight, previousHighlight, callerId }); } } getActiveHighlight() { return this.activeHighlight; } isEqual(a, b) { return a === b || a != null && b != null && a?.series === b?.series && a?.itemId === b?.itemId && a?.datum === b?.datum; } }; } }); // packages/ag-charts-community/src/chart/series/util.ts function datumBoundaryPoints(datum, domain) { if (datum == null || domain.length === 0) { return [false, false]; } const datumValue = datum.valueOf(); const d0 = domain[0]; const d1 = domain[domain.length - 1]; if (typeof d0 === "string") { return [datumValue === d0, datumValue === d1]; } let min = d0.valueOf(); let max = d1.valueOf(); if (min > max) { [min, max] = [max, min]; } return [datumValue === min, datumValue === max]; } function datumStylerProperties(datum, xKey, yKey, xDomain, yDomain) { const { xValue, yValue } = datum; const [min, max] = datumBoundaryPoints(yValue, yDomain); const [first2, last] = datumBoundaryPoints(xValue, xDomain); return { datum, xKey, yKey, xValue, yValue, first: first2, last, min, max }; } function visibleRangeIndices(length2, [range0, range1], xRange) { const xMinIndex = findMinIndex(0, length2 - 1, (index) => { const x1 = xRange(index)?.[1] ?? NaN; return !Number.isFinite(x1) || x1 > range0; }) ?? 0; let xMaxIndex = findMaxIndex(0, length2 - 1, (index) => { const x0 = xRange(index)?.[0] ?? NaN; return !Number.isFinite(x0) || x0 < range1; }) ?? length2 - 1; xMaxIndex = Math.min(xMaxIndex + 1, length2); return [xMinIndex, xMaxIndex]; } function getDatumRefPoint(series, datum) { const refPoint = datum.yBar?.upperPoint ?? datum.midPoint ?? series.datumMidPoint?.(datum); if (refPoint) { const { x, y } = Transformable.toCanvasPoint(series.contentGroup, refPoint.x, refPoint.y); return { canvasX: Math.round(x), canvasY: Math.round(y) }; } } function countExpandingSearch(min, max, start2, countUntil, iteratee) { let i = -1; let count = 0; let shift = 0; let reachedAnEnd = false; while (count < countUntil && i <= max - min) { i += 1; const index = start2 + shift; if (!reachedAnEnd) shift *= -1; if (shift >= 0) shift += 1; if (reachedAnEnd && shift < 0) shift -= 1; if (index < min || index > max) { reachedAnEnd = true; continue; } if (iteratee(index)) count += 1; } return count; } var init_util = __esm({ "packages/ag-charts-community/src/chart/series/util.ts"() { "use strict"; init_main(); init_transformable(); } }); // packages/ag-charts-community/src/chart/interaction/tooltipManager.ts var TooltipManager; var init_tooltipManager = __esm({ "packages/ag-charts-community/src/chart/interaction/tooltipManager.ts"() { "use strict"; init_stateTracker(); init_util(); TooltipManager = class { constructor(domManager, tooltip) { this.domManager = domManager; this.tooltip = tooltip; this.stateTracker = new StateTracker(); this.suppressState = new StateTracker(false); this.appliedState = null; tooltip.setup(domManager); domManager.addListener("hidden", () => this.tooltip.hide()); } updateTooltip(callerId, meta, content) { if (!this.tooltip.enabled) return; content ?? (content = this.stateTracker.get(callerId)?.content); this.stateTracker.set(callerId, { content, meta }); this.applyStates(); } removeTooltip(callerId) { if (!this.tooltip.enabled) return; this.stateTracker.delete(callerId); this.applyStates(); } suppressTooltip(callerId) { this.suppressState.set(callerId, true); } unsuppressTooltip(callerId) { this.suppressState.delete(callerId); } destroy() { this.domManager.removeStyles("tooltip"); } applyStates() { const id = this.stateTracker.stateId(); const state = id ? this.stateTracker.get(id) : null; if (this.suppressState.stateValue() || state?.meta == null || state?.content == null) { this.appliedState = null; this.tooltip.hide(); return; } const canvasRect = this.domManager.getBoundingClientRect(); const boundingRect = this.tooltip.bounds === "extended" ? this.domManager.getOverlayClientRect() : canvasRect; if (this.appliedState?.content === state?.content) { const renderInstantly = this.tooltip.isVisible(); this.tooltip.show(boundingRect, canvasRect, state?.meta, null, renderInstantly); } else { this.tooltip.show(boundingRect, canvasRect, state?.meta, state?.content); } this.appliedState = state; } static makeTooltipMeta(event, series, datum) { const { canvasX, canvasY } = event; const tooltip = series.properties.tooltip; const meta = { canvasX, canvasY, enableInteraction: tooltip.interaction?.enabled ?? false, lastPointerEvent: { type: event.type, canvasX, canvasY }, showArrow: tooltip.showArrow, position: { type: tooltip.position.type, xOffset: tooltip.position.xOffset, yOffset: tooltip.position.yOffset } }; const refPoint = getDatumRefPoint(series, datum); if ((tooltip.position.type === "node" || tooltip.position.type === "sparkline") && refPoint) { return { ...meta, canvasX: refPoint.canvasX, canvasY: refPoint.canvasY }; } return meta; } isEnteringInteractiveTooltip(event) { const { tooltip } = this; const relatedTarget = event.sourceEvent.relatedTarget; return tooltip.interactive && tooltip.enabled && tooltip.isVisible() && tooltip.contains(relatedTarget); } }; } }); // packages/ag-charts-community/src/chart/interaction/dragInterpreter.ts function makeSynthetic(device, type, event) { const { offsetX, offsetY, clientX, clientY, currentX, currentY, sourceEvent } = event; return { type, device, offsetX, offsetY, clientX, clientY, currentX, currentY, sourceEvent }; } function checkDistanceSquared(dx2, dy2) { const distanceSquared2 = dx2 * dx2 + dy2 * dy2; const thresholdSquared = DRAG_THRESHOLD_PX * DRAG_THRESHOLD_PX; return distanceSquared2 >= thresholdSquared; } var DRAG_THRESHOLD_PX, DOUBLE_TAP_TIMER_MS, DragInterpreter; var init_dragInterpreter = __esm({ "packages/ag-charts-community/src/chart/interaction/dragInterpreter.ts"() { "use strict"; init_listeners(); DRAG_THRESHOLD_PX = 3; DOUBLE_TAP_TIMER_MS = 505; DragInterpreter = class { constructor(widget) { this.destroyFns = []; this.listeners = new Listeners(); this.isDragging = false; this.touch = { distanceTravelledX: 0, distanceTravelledY: 0, clientX: 0, clientY: 0 }; this.destroyFns.push( widget.addListener("touchstart", this.onTouchStart.bind(this)), widget.addListener("touchmove", this.onTouchMove.bind(this)), widget.addListener("touchend", this.onTouchEnd.bind(this)), widget.addListener("mousemove", this.onMouseMove.bind(this)), widget.addListener("dblclick", this.onDblClick.bind(this)), widget.addListener("drag-start", this.onDragStart.bind(this)), widget.addListener("drag-move", this.onDragMove.bind(this)), widget.addListener("drag-end", this.onDragEnd.bind(this)) ); } destroy() { this.destroyFns.forEach((fn) => fn()); this.listeners.destroy(); } addListener(type, handler) { return this.listeners.addListener(type, handler); } dispatch(event) { this.listeners.dispatch(event.type, event); } onTouchStart(e) { const { clientX, clientY } = e.sourceEvent.targetTouches.item(0) ?? { clientX: Infinity, clientY: Infinity }; this.touch.distanceTravelledX = 0; this.touch.distanceTravelledY = 0; this.touch.clientX = clientX; this.touch.clientY = clientY; } onTouchMove(e) { const { clientX, clientY } = e.sourceEvent.targetTouches.item(0) ?? { clientX: Infinity, clientY: Infinity }; this.touch.distanceTravelledX += Math.abs(this.touch.clientX - clientX); this.touch.distanceTravelledY += Math.abs(this.touch.clientY - clientY); this.touch.clientX = clientX; this.touch.clientY = clientY; } onTouchEnd(event) { event.sourceEvent.preventDefault(); } onMouseMove(event) { this.dispatch(event); } onDblClick(event) { this.dispatch({ device: "mouse", ...event }); } onDragStart(event) { this.dragStartEvent = event; } onDragMove(event) { if (this.dragStartEvent != null) { if (checkDistanceSquared(event.originDeltaX, event.originDeltaY)) { this.dispatch(this.dragStartEvent); this.dispatch({ ...this.dragStartEvent, type: "drag-move" }); this.dragStartEvent = void 0; this.isDragging = true; } } if (this.isDragging) { this.dispatch(event); } } onDragEnd(event) { if (this.isDragging) { this.dispatch(event); this.isDragging = false; return; } if (event.device === "mouse") { const click = makeSynthetic("mouse", "click", event); this.dispatch(click); } else if (event.sourceEvent.type === "touchend") { if (checkDistanceSquared(this.touch.distanceTravelledX, this.touch.distanceTravelledY)) { return; } const click = makeSynthetic("touch", "click", event); this.dispatch(click); const now = Date.now(); if (this.lastClickTime !== void 0 && now - this.lastClickTime <= DOUBLE_TAP_TIMER_MS) { const dblClick = makeSynthetic(event.device, "dblclick", event); this.dispatch(dblClick); this.lastClickTime = void 0; } else { this.lastClickTime = now; } } } }; } }); // packages/ag-charts-community/src/chart/interaction/widgetSet.ts var DOMManagerWidget, WidgetSet; var init_widgetSet = __esm({ "packages/ag-charts-community/src/chart/interaction/widgetSet.ts"() { "use strict"; init_nativeWidget(); init_dragInterpreter(); DOMManagerWidget = class extends NativeWidget { constructor(elem) { super(elem); } addChildToDOM() { } removeChildFromDOM() { } }; WidgetSet = class { constructor(domManager) { this.seriesWidget = new DOMManagerWidget(domManager.getParent("series-area")); this.chartWidget = new DOMManagerWidget(domManager.getParent("canvas-proxy")); this.containerWidget = new DOMManagerWidget(domManager.getParent("canvas-container")); this.containerWidget.addChild(this.chartWidget); this.chartWidget.addChild(this.seriesWidget); this.seriesDragInterpreter = new DragInterpreter(this.seriesWidget); } destroy() { this.seriesDragInterpreter.destroy(); this.seriesWidget.destroy(); this.chartWidget.destroy(); this.containerWidget.destroy(); } }; } }); // packages/ag-charts-community/src/util/vector4.ts function start(a) { return { x: a.x1, y: a.y1 }; } function end(a) { return { x: a.x2, y: a.y2 }; } function topCenter(a) { return { x: (a.x1 + a.x2) / 2, y: Math.min(a.y1, a.y2) }; } function center(a) { return { x: (a.x1 + a.x2) / 2, y: (a.y1 + a.y2) / 2 }; } function bottomCenter(a) { return { x: (a.x1 + a.x2) / 2, y: Math.max(a.y1, a.y2) }; } function width(a) { return Math.abs(a.x2 - a.x1); } function height(a) { return Math.abs(a.y2 - a.y1); } function round2(a) { return { x1: Math.round(a.x1), y1: Math.round(a.y1), x2: Math.round(a.x2), y2: Math.round(a.y2) }; } function clone(a) { return { x1: a.x1, y1: a.y1, x2: a.x2, y2: a.y2 }; } function collides(a, b) { const an = normalise(a); const bn = normalise(b); return an.x1 <= bn.x2 && an.x2 >= bn.x1 && an.y1 <= bn.y2 && an.y2 >= bn.y1; } function normalise(a) { return { x1: Math.min(a.x1, a.x2), x2: Math.max(a.x1, a.x2), y1: Math.min(a.y1, a.y2), y2: Math.max(a.y1, a.y2) }; } function from(a, b, c, d) { if (typeof a === "number") { return { x1: a, y1: b, x2: c, y2: d }; } if ("width" in a) { return { x1: a.x, y1: a.y, x2: a.x + a.width, y2: a.y + a.height }; } throw new Error(`Values can not be converted into a vector4: [${JSON.stringify(a)}] [${b}] [${c}] [${d}]`); } function origin() { return { x1: 0, y1: 0, x2: 0, y2: 0 }; } var Vec4; var init_vector4 = __esm({ "packages/ag-charts-community/src/util/vector4.ts"() { "use strict"; Vec4 = { bottomCenter, center, clone, collides, end, from, height, round: round2, start, topCenter, origin, width }; } }); // packages/ag-charts-community/src/util/panToBBox.ts function normalize2(screenMin, min, screenMax, max, target) { return min + (max - min) * ((target - screenMin) / (screenMax - screenMin)); } function unnormalize(screenMin, min, screenMax, max, ratio2) { return screenMin + (ratio2 - min) * ((screenMax - screenMin) / (max - min)); } function calcWorldAxis(viewportMin, viewportMax, ratio2) { return [ unnormalize(viewportMin, ratio2.min, viewportMax, ratio2.max, 0), unnormalize(viewportMin, ratio2.min, viewportMax, ratio2.max, 1) ]; } function calcWorldVec4(viewport, ratioX, ratioY) { const [x1, x2] = calcWorldAxis(viewport.x1, viewport.x2, ratioX); const [y1, y2] = calcWorldAxis(viewport.y1, viewport.y2, ratioY); return { x1, x2, y1, y2 }; } function panAxesUnnormalized(worldMin, worldMax, viewportMin, viewportMax, targetMin, targetMax) { if (viewportMin <= targetMin && targetMax <= viewportMax) return viewportMin; const minDiff = targetMin - viewportMin; const maxDiff = targetMax - viewportMax; const diff8 = Math.abs(minDiff) < Math.abs(maxDiff) ? minDiff : maxDiff; return clamp(worldMin, viewportMin + diff8, worldMax); } function calcPanToBBoxRatios(viewportBBox, ratios, targetBBox) { const { x: ratioX = { min: 0, max: 1 }, y: ratioY = { min: 0, max: 1 } } = ratios; const target = Vec4.from(targetBBox); const viewport = Vec4.from(viewportBBox); const world = calcWorldVec4(viewport, ratioX, ratioY); const x = panAxesUnnormalized(world.x1, world.x2, viewport.x1, viewport.x2, target.x1, target.x2); const y = panAxesUnnormalized(world.y1, world.y2, viewport.y1, viewport.y2, target.y1, target.y2); return { x: { min: normalize2(viewport.x1, ratioX.min, viewport.x2, ratioX.max, x), max: normalize2(viewport.x1, ratioX.min, viewport.x2, ratioX.max, x + viewportBBox.width) }, y: { min: normalize2(viewport.y1, ratioY.min, viewport.y2, ratioY.max, y), max: normalize2(viewport.y1, ratioY.min, viewport.y2, ratioY.max, y + viewportBBox.height) } }; } var init_panToBBox = __esm({ "packages/ag-charts-community/src/util/panToBBox.ts"() { "use strict"; init_number(); init_vector4(); } }); // packages/ag-charts-community/src/chart/interaction/zoomManager.ts var expectedMementoKeys, ZoomManagerAutoScaleAxis, rangeValidator, ZoomManager, AxisZoomManager; var init_zoomManager = __esm({ "packages/ag-charts-community/src/chart/interaction/zoomManager.ts"() { "use strict"; init_main(); init_continuousScale(); init_ordinalTimeScale(); init_baseManager(); init_json(); init_panToBBox(); init_stateTracker(); expectedMementoKeys = ["rangeX", "rangeY", "ratioX", "ratioY", "autoScaledAxes"]; ZoomManagerAutoScaleAxis = class { constructor() { this.enabled = false; this.padding = 0; this.manuallyAdjusted = false; } }; rangeValidator = (axis) => attachDescription((value, context) => { if (!ContinuousScale.is(axis?.scale) && !OrdinalTimeScale.is(axis?.scale)) return true; if (value == null || context.end == null) return true; return value <= context.end; }, `to be less than end`); ZoomManager = class extends BaseManager { constructor(fireChartEvent, layoutManager) { super(); this.fireChartEvent = fireChartEvent; this.mementoOriginatorKey = "zoom"; this.axisZoomManagers = /* @__PURE__ */ new Map(); this.state = new StateTracker(void 0, "initial"); this.axes = []; this.didLayoutAxes = false; this.autoScaleYAxis = new ZoomManagerAutoScaleAxis(); this.lastRestoredState = void 0; this.independentAxes = false; this.navigatorModule = false; this.zoomModule = false; // The initial state memento can not be restored until the chart has performed its first layout. Instead save it as // pending and restore then delete it on the first layout. this.pendingMemento = void 0; this.destroyFns.push( layoutManager.addListener("layout:complete", () => { const { pendingMemento } = this; const shouldPerformInitialLayout = !this.didLayoutAxes; this.didLayoutAxes = true; if (pendingMemento) { this.restoreMemento(pendingMemento.version, pendingMemento.mementoVersion, pendingMemento.memento); } else if (shouldPerformInitialLayout) { this.autoScaleYZoom("zoom-manager"); } }) ); } createMemento() { return this.getMementoRanges(); } guardMemento(blob, messages) { if (blob == null) return true; if (!isObject(blob)) return false; for (const key of Object.keys(blob)) { if (!expectedMementoKeys.includes(key)) { return false; } } const primaryX = this.getPrimaryAxis("x" /* X */); const primaryY = this.getPrimaryAxis("y" /* Y */); const zoomMementoDefs = { rangeX: { start: and(or(number, date), rangeValidator(primaryX)), end: or(number, date) }, rangeY: { start: and(or(number, date), rangeValidator(primaryY)), end: or(number, date) }, ratioX: { start: and(ratio, lessThan("end")), end: ratio }, ratioY: { start: and(ratio, lessThan("end")), end: ratio }, autoScaledAxes: arrayOf(union("y")) }; const result = validate(blob, zoomMementoDefs); if (result.errors.length > 0) { messages.push(...result.errors.map((e) => e.message)); return false; } return true; } restoreMemento(version, mementoVersion, memento) { const { independentAxes } = this; if (!this.axes || !this.didLayoutAxes) { this.pendingMemento = { version, mementoVersion, memento }; return; } this.pendingMemento = void 0; const zoom = this.getDefinedZoom(); if (memento?.rangeX) { zoom.x = this.rangeToRatio(memento.rangeX, "x" /* X */) ?? { min: 0, max: 1 }; } else if (memento?.ratioX) { zoom.x = { min: memento.ratioX.start ?? 0, max: memento.ratioX.end ?? 1 }; } else { zoom.x = { min: 0, max: 1 }; } if (!this.navigatorModule || this.zoomModule) { let yAutoScale = memento?.autoScaledAxes?.includes("y"); if (memento?.rangeY) { zoom.y = this.rangeToRatio(memento.rangeY, "y" /* Y */) ?? { min: 0, max: 1 }; yAutoScale ?? (yAutoScale = false); } else if (memento?.ratioY) { zoom.y = { min: memento.ratioY.start ?? 0, max: memento.ratioY.end ?? 1 }; yAutoScale ?? (yAutoScale = false); } else { zoom.y = { min: 0, max: 1 }; yAutoScale ?? (yAutoScale = true); } zoom.autoScaleYAxis = yAutoScale; } this.lastRestoredState = zoom; if (independentAxes !== true) { this.updateZoom("zoom-manager", zoom); return; } const primaryX = this.getPrimaryAxis("x" /* X */); const primaryY = this.getPrimaryAxis("y" /* Y */); for (const axis of [primaryX, primaryY]) { if (!axis) continue; this.updateAxisZoom("zoom-manager", axis.id, zoom[axis.direction]); } } updateAxes(axes) { this.axes = axes; const zoomManagers = new Map(axes.map((axis) => [axis.id, this.axisZoomManagers.get(axis.id)])); this.axisZoomManagers.clear(); for (const axis of axes) { this.axisZoomManagers.set(axis.id, zoomManagers.get(axis.id) ?? new AxisZoomManager(axis)); } if (this.state.size > 0 && axes.length > 0) { this.updateZoom(this.state.stateId(), this.state.stateValue()); } } setIndependentAxes(independent = true) { this.independentAxes = independent; } setAutoScaleYAxis(enabled, padding) { this.autoScaleYAxis.enabled = enabled; this.autoScaleYAxis.padding = padding; } setNavigatorEnabled(enabled = true) { this.navigatorModule = enabled; } setZoomModuleEnabled(enabled = true) { this.zoomModule = enabled; } isZoomEnabled() { return this.zoomModule; } updateZoom(callerId, newZoom) { if (newZoom?.x && (newZoom.x.min < 0 || newZoom.x.max > 1)) { logger_exports.warnOnce( `Attempted to update x-axis zoom to an invalid ratio of [{ min: ${newZoom.x.min}, max: ${newZoom.x.max} }], expecting a ratio of 0 to 1, ignoring.` ); newZoom.x = void 0; } if (newZoom?.y && (newZoom.y.min < 0 || newZoom.y.max > 1)) { logger_exports.warnOnce( `Attempted to update y-axis zoom to an invalid ratio of [{ min: ${newZoom.y.min}, max: ${newZoom.y.max} }], expecting a ratio of 0 to 1, ignoring.` ); newZoom.y = void 0; } if (this.axisZoomManagers.size === 0) { const stateId = this.state.stateId(); if (stateId === "initial" || stateId === callerId) { this.state.set(callerId, newZoom); } return; } this.state.set(callerId, newZoom); const autoScaleYAxis = newZoom?.autoScaleYAxis; if (autoScaleYAxis != null) { this.autoScaleYAxis.manuallyAdjusted = !autoScaleYAxis; } this.axisZoomManagers.forEach((axis) => { axis.updateZoom(callerId, newZoom?.[axis.getDirection()]); }); this.applyChanges(callerId); } updateAxisZoom(callerId, axisId, newZoom) { this.axisZoomManagers.get(axisId)?.updateZoom(callerId, newZoom); this.applyChanges(callerId); } resetZoom(callerId) { this.autoScaleYAxis.manuallyAdjusted = false; const zoom = this.getRestoredZoom(); this.updateZoom(callerId, { x: { min: zoom?.x?.min ?? 0, max: zoom?.x?.max ?? 1 }, y: { min: zoom?.y?.min ?? 0, max: zoom?.y?.max ?? 1 }, autoScaleYAxis: zoom?.autoScaleYAxis ?? true }); } resetAxisZoom(callerId, axisId) { const axisZoomManager = this.axisZoomManagers.get(axisId); const direction = axisZoomManager?.getDirection(); if (direction == null) return; const restoredZoom = this.getRestoredZoom(); if (direction === "y" /* Y */) { const autoScaleYAxis = restoredZoom?.autoScaleYAxis ?? true; this.autoScaleYAxis.manuallyAdjusted = !autoScaleYAxis; } this.updateAxisZoom(callerId, axisId, restoredZoom?.[direction] ?? { min: 0, max: 1 }); } setAxisManuallyAdjusted(_callerId, axisId) { const direction = this.axisZoomManagers.get(axisId)?.getDirection(); if (direction !== "y" /* Y */) return; this.autoScaleYAxis.manuallyAdjusted = true; } updatePrimaryAxisZoom(callerId, direction, newZoom) { const primaryAxis = this.getPrimaryAxis(direction); if (!primaryAxis) return; this.updateAxisZoom(callerId, primaryAxis.id, newZoom); } panToBBox(callerId, seriesRect, target) { if (!this.isZoomEnabled()) return false; const zoom = this.getZoom(); if (zoom === void 0 || !zoom.x && !zoom.y) return false; const panIsPossible = seriesRect.width > 0 && seriesRect.height > 0 && Math.abs(target.width) <= Math.abs(seriesRect.width) && Math.abs(target.height) <= Math.abs(seriesRect.height); if (!panIsPossible) { logger_exports.warnOnce(`cannot pan to target BBox - chart too small?`); return false; } const newZoom = calcPanToBBoxRatios(seriesRect, zoom, target); if (this.independentAxes) { this.updatePrimaryAxisZoom(callerId, "x" /* X */, newZoom.x); this.updatePrimaryAxisZoom(callerId, "y" /* Y */, newZoom.y); } else { this.updateZoom(callerId, newZoom); } return true; } // Fire this event to signal to listeners that the view is changing through a zoom and/or pan change. fireZoomPanStartEvent(callerId) { this.listeners.dispatch("zoom-pan-start", { type: "zoom-pan-start", callerId }); } extendToEnd(callerId, direction, extent3) { return this.extendWith(callerId, direction, (end2) => Number(end2) - extent3); } extendWith(callerId, direction, fn) { const axis = this.getPrimaryAxis(direction); if (!axis) return; const extents = this.getDomainExtents(axis); if (!extents) return; const [, end2] = extents; const start2 = fn(end2); const ratio2 = this.rangeToRatio({ start: start2, end: end2 }, direction); if (!ratio2) return; this.updateZoom(callerId, { [direction]: ratio2 }); } updateWith(callerId, direction, fn) { const axis = this.getPrimaryAxis(direction); if (!axis) return; const extents = this.getDomainExtents(axis); if (!extents) return; let [start2, end2] = extents; [start2, end2] = fn(start2, end2); const ratio2 = this.rangeToRatio({ start: start2, end: end2 }, direction); if (!ratio2) return; this.updateZoom(callerId, { [direction]: ratio2 }); } getZoom() { let x; let y; this.axisZoomManagers.forEach((axis) => { if (axis.getDirection() === "x" /* X */) { x ?? (x = axis.getZoom()); } else if (axis.getDirection() === "y" /* Y */) { y ?? (y = axis.getZoom()); } }); if (x || y) { return { x, y }; } } getAxisZoom(axisId) { return this.axisZoomManagers.get(axisId)?.getZoom() ?? { min: 0, max: 1 }; } getAxisZooms() { const axes = {}; for (const [axisId, axis] of this.axisZoomManagers.entries()) { axes[axisId] = { direction: axis.getDirection(), zoom: axis.getZoom() }; } return axes; } getRestoredZoom() { return this.lastRestoredState; } getPrimaryAxisId(direction) { return this.getPrimaryAxis(direction)?.id; } isVisibleItemsCountAtLeast(zoom, minVisibleItems) { const xAxis = this.getPrimaryAxis("x" /* X */); const yAxis = this.getPrimaryAxis("y" /* Y */); const processedSeriesIds = /* @__PURE__ */ new Set(); let visibleItemsCount = 0; const xVisibleRange = [zoom.x.min, zoom.x.max]; const yVisibleRange = [zoom.y.min, zoom.y.max]; for (const series of xAxis?.boundSeries ?? []) { processedSeriesIds.add(series.id); const remainingItems = minVisibleItems - (visibleItemsCount ?? 0); const seriesVisibleItems = series.getVisibleItems(xVisibleRange, yVisibleRange, remainingItems); visibleItemsCount += seriesVisibleItems; if (visibleItemsCount >= minVisibleItems) return true; } for (const series of yAxis?.boundSeries ?? []) { if (processedSeriesIds.has(series.id)) continue; const remainingItems = minVisibleItems - (visibleItemsCount ?? 0); const seriesVisibleItems = series.getVisibleItems(xVisibleRange, yVisibleRange, remainingItems); visibleItemsCount += seriesVisibleItems; if (visibleItemsCount >= minVisibleItems) return true; } return processedSeriesIds.size === 0; } getMementoRanges() { const zoom = this.getDefinedZoom(); let autoScaledAxes; if (this.autoScaleYAxis.enabled) { autoScaledAxes = this.autoScaleYAxis.manuallyAdjusted ? [] : ["y"]; } const memento = { rangeX: this.getRangeDirection(zoom.x, "x" /* X */), rangeY: this.getRangeDirection(zoom.y, "y" /* Y */), ratioX: { start: zoom.x.min, end: zoom.x.max }, ratioY: { start: zoom.y.min, end: zoom.y.max }, autoScaledAxes }; return memento; } autoScaleYZoom(callerId, applyChanges = true) { if (!this.isZoomEnabled()) return; const { independentAxes, autoScaleYAxis } = this; const zoom = this.getZoom(); if (zoom?.x == null || !autoScaleYAxis.enabled || autoScaleYAxis.manuallyAdjusted) return; const { padding } = autoScaleYAxis; let zoomY; if (zoom.x?.min === 0 && zoom.x?.max === 1) { zoomY = { min: 0, max: 1 }; } else if (independentAxes) { zoomY = this.primaryAxisZoom("y" /* Y */, zoom.x, { padding }); } else { zoomY = this.combinedAxisZoom("y" /* Y */, zoom.x, { padding }); } if (zoomY == null) return; if (independentAxes) { const primaryAxis = this.getPrimaryAxis("y" /* Y */); const primaryAxisManager = primaryAxis == null ? void 0 : this.axisZoomManagers.get(primaryAxis.id); primaryAxisManager?.updateZoom("zoom-manager", zoomY); } else { for (const axisZoomManager of this.axisZoomManagers.values()) { if (axisZoomManager.getDirection() === "y" /* Y */) { axisZoomManager.updateZoom("zoom-manager", zoomY); } } } if (applyChanges) { this.applyChanges(callerId); } } applyChanges(callerId) { this.autoScaleYZoom(callerId, false); const changed = Array.from(this.axisZoomManagers.values(), (axis) => axis.applyChanges()).includes(true); if (!changed) { return; } const axes = {}; for (const [axisId, axis] of this.axisZoomManagers.entries()) { axes[axisId] = axis.getZoom(); } this.listeners.dispatch("zoom-change", { type: "zoom-change", ...this.getZoom(), axes, callerId }); this.fireChartEvent({ type: "zoom", ...this.getMementoRanges() }); } getRangeDirection(ratio2, direction) { const axis = this.getPrimaryAxis(direction); if (!axis || !ContinuousScale.is(axis.scale) && !OrdinalTimeScale.is(axis.scale)) return; const extents = this.getDomainPixelExtents(axis); if (!extents) return; const [d0, d1] = extents; let start2; let end2; if (d0 <= d1) { start2 = axis.scale.invert(0); end2 = axis.scale.invert(d0 + (d1 - d0) * ratio2.max); } else { start2 = axis.scale.invert(d0 - (d0 - d1) * ratio2.min); end2 = axis.scale.invert(0); } return { start: start2, end: end2 }; } rangeToRatio(range4, direction) { const axis = this.getPrimaryAxis(direction); if (!axis) return; const extents = this.getDomainPixelExtents(axis); if (!extents) return; const [d0, d1] = extents; let r0 = range4.start == null ? d0 : axis.scale.convert?.(range4.start); let r1 = range4.end == null ? d1 : axis.scale.convert?.(range4.end); if (!isFiniteNumber(r0) || !isFiniteNumber(r1)) return; const [dMin, dMax] = [Math.min(d0, d1), Math.max(d0, d1)]; if (r0 < dMin || r0 > dMax) { logger_exports.warnOnce( `Invalid range start [${range4.start}], expecting a value between [${axis.scale.invert?.(d0)}] and [${axis.scale.invert?.(d1)}], ignoring.` ); return; } if (r1 < dMin || r1 > dMax) { logger_exports.warnOnce( `Invalid range end [${range4.end}], expecting a value between [${axis.scale.invert?.(d0)}] and [${axis.scale.invert?.(d1)}], ignoring.` ); return; } r0 = Math.min(dMax, Math.max(dMin, r0)); r1 = Math.min(dMax, Math.max(dMin, r1)); const diff8 = d1 - d0; const min = Math.abs((r0 - d0) / diff8); const max = Math.abs((r1 - d0) / diff8); return { min, max }; } getPrimaryAxis(direction) { return this.axes?.find((a) => a.direction === direction); } getDomainExtents(axis) { const { domain } = axis.scale; const d0 = domain.at(0); const d1 = domain.at(-1); if (d0 == null || d1 == null) return; return [d0, d1]; } getDomainPixelExtents(axis) { const { domain } = axis.scale; const d0 = axis.scale.convert?.(domain.at(0)); const d1 = axis.scale.convert?.(domain.at(-1)); if (!isFiniteNumber(d0) || !isFiniteNumber(d1)) return; return [d0, d1]; } getDefinedZoom() { const zoom = this.getZoom(); return { x: { min: zoom?.x?.min ?? 0, max: zoom?.x?.max ?? 1 }, y: { min: zoom?.y?.min ?? 0, max: zoom?.y?.max ?? 1 } }; } zoomBounds(xAxis, yAxis, zoom, padding) { const xScale = xAxis.scale; const xScaleRange = xScale.range; xScale.range = [0, 1]; const yScale = yAxis.scale; const yScaleRange = yScale.range; yScale.range = [0, 1]; let min = 1; let minPadding = false; let max = 0; let maxPadding = false; for (const series of yAxis.boundSeries) { const { connectsToYAxis } = series; const yValues = series.getRange("y" /* Y */, [zoom.min, zoom.max]); for (const yValue of yValues) { const y = yScale.convert(yValue); if (!Number.isFinite(y)) continue; if (y < min) { min = y; minPadding = !connectsToYAxis || yValue < 0; } if (y > max) { max = y; maxPadding = !connectsToYAxis || yValue > 0; } } } if (isFiniteNumber(yAxis.min)) { min = 0; } if (isFiniteNumber(yAxis.max)) { max = 1; } xScale.range = xScaleRange; yScale.range = yScaleRange; if (min >= max) return; const totalPadding = (minPadding ? padding : 0) + (maxPadding ? padding : 0); const paddedDelta = Math.min((max - min) * (1 + totalPadding), 1); if (paddedDelta <= 0) return; if (minPadding && maxPadding) { const mid = (max + min) / 2; min = mid - paddedDelta / 2; max = mid + paddedDelta / 2; } else if (!minPadding && maxPadding) { max = min + paddedDelta; } else if (minPadding && !maxPadding) { min = max - paddedDelta; } if (min < 0) { max += -min; min = 0; } else if (max > 1) { min -= max - 1; max = 1; } return { min, max }; } primaryAxisZoom(direction, zoom, { padding = 0 } = {}) { const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */; const xAxis = this.getPrimaryAxis(crossDirection); const yAxis = this.getPrimaryAxis(direction); if (xAxis == null || yAxis == null) return; return this.zoomBounds(xAxis, yAxis, zoom, padding); } combinedAxisZoom(direction, zoom, { padding = 0 } = {}) { const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */; const seriesXAxes = /* @__PURE__ */ new Map(); for (const xAxis of this.axes) { if (xAxis.direction !== crossDirection) continue; for (const series of xAxis.boundSeries) { seriesXAxes.set(series, xAxis); } } let min = 1; let max = 0; for (const yAxis of this.axes) { if (yAxis.direction !== direction) continue; for (const series of yAxis.boundSeries) { const xAxis = seriesXAxes.get(series); if (xAxis == null) continue; const bounds = this.zoomBounds(xAxis, yAxis, zoom, padding); if (bounds == null) return; min = Math.min(min, bounds.min); max = Math.max(max, bounds.max); } } const delta4 = 1e-6; if (min < delta4) min = 0; if (max > 1 - delta4) max = 1; if (min > max) return; return { min, max }; } }; AxisZoomManager = class { constructor(axis) { this.axis = axis; const [min = 0, max = 1] = axis.visibleRange; this.state = new StateTracker({ min, max }); this.currentZoom = this.state.stateValue(); } getDirection() { return this.axis.direction; } updateZoom(callerId, newZoom) { this.state.set(callerId, newZoom); } getZoom() { return deepClone(this.state.stateValue()); } hasChanges() { const currentZoom = this.currentZoom; const pendingZoom = this.state.stateValue(); return currentZoom.min !== pendingZoom.min || currentZoom.max !== pendingZoom.max; } applyChanges() { const hasChanges = this.hasChanges(); this.currentZoom = this.state.stateValue(); return hasChanges; } }; } }); // packages/ag-charts-community/src/chart/layout/seriesLabelLayoutManager.ts var SeriesLabelLayoutManager; var init_seriesLabelLayoutManager = __esm({ "packages/ag-charts-community/src/chart/layout/seriesLabelLayoutManager.ts"() { "use strict"; init_bbox(); init_labelPlacement(); SeriesLabelLayoutManager = class { constructor() { this.labelData = /* @__PURE__ */ new Map(); } updateLabels(placedLabelSeries, padding, seriesRect = BBox.zero) { const bounds = { x: -padding.left, y: -padding.top, width: seriesRect.width + padding.left + padding.right, height: seriesRect.height + padding.top + padding.bottom }; const expectedSeriesId = new Set(placedLabelSeries.map((s) => s.id)); for (const seriesId of this.labelData.keys()) { if (!expectedSeriesId.has(seriesId)) { this.labelData.delete(seriesId); } } for (const series of placedLabelSeries) { const labelData = series.getLabelData(); if (labelData.every(isPointLabelDatum)) { this.labelData.set(series.id, labelData); } } const placedLabels = placeLabels(this.labelData, bounds, 5); for (const series of placedLabelSeries) { series.updatePlacedLabelData?.(placedLabels.get(series.id) ?? []); } } }; } }); // packages/ag-charts-community/src/chart/legend/legendManager.ts var LegendManager; var init_legendManager = __esm({ "packages/ag-charts-community/src/chart/legend/legendManager.ts"() { "use strict"; init_main(); init_baseManager(); LegendManager = class extends BaseManager { constructor() { super(...arguments); this.mementoOriginatorKey = "legend"; this.legendDataMap = /* @__PURE__ */ new Map(); } createMemento() { return this.getData().filter(({ hideInLegend, isFixed }) => !hideInLegend && !isFixed).map(({ enabled, seriesId, itemId, legendItemName }) => ({ visible: enabled, seriesId, itemId, legendItemName })); } guardMemento(blob) { return blob == null || isArray(blob); } restoreMemento(_version, _mementoVersion, memento) { memento?.forEach((datum) => { const { seriesId, data } = this.getRestoredData(datum) ?? {}; if (!seriesId || !data) { return; } this.updateData(seriesId, data); }); this.update(); } getRestoredData(datum) { const { seriesId, itemId, legendItemName, visible } = datum; if (seriesId) { const legendData = this.legendDataMap.get(seriesId) ?? []; const data = legendData.map((d) => { const match = d.seriesId === seriesId && (!itemId || d.itemId === itemId); if (match && d.isFixed) { this.warnFixed(d.seriesId, d.itemId); } return !d.isFixed && match ? { ...d, enabled: visible } : d; }); return { seriesId, data }; } if (itemId == null && legendItemName == null) { return; } for (const legendDatum of this.getData()) { if (itemId != null && legendDatum.itemId !== itemId || legendItemName != null && legendDatum.legendItemName !== legendItemName) { continue; } if (legendDatum.isFixed) { this.warnFixed(legendDatum.seriesId, itemId); return; } const seriesLegendData = (this.legendDataMap.get(legendDatum.seriesId) ?? []).map( (d) => d.itemId === itemId || d.legendItemName === legendItemName ? { ...d, enabled: visible } : d ); return { seriesId: legendDatum.seriesId, data: seriesLegendData }; } } warnFixed(seriesId, itemId) { logger_exports.warnOnce( `The legend item with seriesId [${seriesId}] and itemId [${itemId}] is not configurable, this series item cannot be toggled through the legend.` ); } update(data) { this.listeners.dispatch("legend-change", { type: "legend-change", legendData: data ?? this.getData() }); } updateData(seriesId, data = []) { this.legendDataMap.set(seriesId, data); } clearData() { this.legendDataMap.clear(); } toggleItem({ enabled, seriesId, itemId, legendItemName }) { if (legendItemName) { this.getData().forEach((datum) => { const newData = (this.legendDataMap.get(datum.seriesId) ?? []).map( (d) => d.legendItemName === legendItemName ? { ...d, enabled } : d ); this.updateData(datum.seriesId, newData); }); return; } const seriesLegendData = this.getData(seriesId); const singleLegendItem = seriesLegendData.length === 1; const data = seriesLegendData.map( (datum) => itemId == null && singleLegendItem || datum.itemId === itemId ? { ...datum, enabled } : datum ); this.updateData(seriesId, data); } getData(seriesId) { if (seriesId) { return this.legendDataMap.get(seriesId) ?? []; } return [...this.legendDataMap].reduce( (data, [_, legendData]) => data.concat(legendData), [] ); } getDatum({ seriesId, itemId } = {}) { return this.getData(seriesId).find((datum) => datum.itemId === itemId); } getSeriesEnabled(seriesId) { const data = this.getData(seriesId); if (data.length > 0) { return data.some((d) => d.enabled); } } getItemEnabled({ seriesId, itemId } = {}) { return this.getDatum({ seriesId, itemId })?.enabled ?? true; } }; } }); // packages/ag-charts-community/src/chart/series/seriesStateManager.ts var SeriesStateManager; var init_seriesStateManager = __esm({ "packages/ag-charts-community/src/chart/series/seriesStateManager.ts"() { "use strict"; SeriesStateManager = class { constructor() { this.groups = {}; } registerSeries({ internalId, seriesGrouping, visible, type }) { var _a; if (!seriesGrouping) return; (_a = this.groups)[type] ?? (_a[type] = {}); this.groups[type][internalId] = { grouping: seriesGrouping, visible }; } updateSeries({ internalId, seriesGrouping, visible, type }) { if (!seriesGrouping) return; const entry = this.groups[type]?.[internalId]; if (entry) { entry.grouping = seriesGrouping; entry.visible = visible; } } deregisterSeries({ internalId, type }) { if (this.groups[type]) { delete this.groups[type][internalId]; } if (this.groups[type] && Object.keys(this.groups[type]).length === 0) { delete this.groups[type]; } } getVisiblePeerGroupIndex({ type, seriesGrouping, visible }) { if (!seriesGrouping) { return { visibleGroupCount: visible ? 1 : 0, visibleSameStackCount: visible ? 1 : 0, index: 0 }; } const visibleGroupsSet = /* @__PURE__ */ new Set(); const visibleSameStackSet = /* @__PURE__ */ new Set(); for (const entry of Object.values(this.groups[type] ?? {})) { if (!entry.visible) continue; visibleGroupsSet.add(entry.grouping.groupIndex); if (entry.grouping.groupIndex === seriesGrouping.groupIndex) { visibleSameStackSet.add(entry.grouping.stackIndex); } } const visibleGroups = Array.from(visibleGroupsSet); visibleGroups.sort((a, b) => a - b); return { visibleGroupCount: visibleGroups.length, visibleSameStackCount: visibleSameStackSet.size, index: visibleGroups.indexOf(seriesGrouping.groupIndex) }; } }; } }); // packages/ag-charts-community/src/chart/chartUpdateType.ts var ChartUpdateType; var init_chartUpdateType = __esm({ "packages/ag-charts-community/src/chart/chartUpdateType.ts"() { "use strict"; ChartUpdateType = /* @__PURE__ */ ((ChartUpdateType4) => { ChartUpdateType4[ChartUpdateType4["FULL"] = 0] = "FULL"; ChartUpdateType4[ChartUpdateType4["UPDATE_DATA"] = 1] = "UPDATE_DATA"; ChartUpdateType4[ChartUpdateType4["PROCESS_DATA"] = 2] = "PROCESS_DATA"; ChartUpdateType4[ChartUpdateType4["PERFORM_LAYOUT"] = 3] = "PERFORM_LAYOUT"; ChartUpdateType4[ChartUpdateType4["SERIES_UPDATE"] = 4] = "SERIES_UPDATE"; ChartUpdateType4[ChartUpdateType4["PRE_SCENE_RENDER"] = 5] = "PRE_SCENE_RENDER"; ChartUpdateType4[ChartUpdateType4["SCENE_RENDER"] = 6] = "SCENE_RENDER"; ChartUpdateType4[ChartUpdateType4["NONE"] = 7] = "NONE"; return ChartUpdateType4; })(ChartUpdateType || {}); } }); // packages/ag-charts-community/src/chart/updateService.ts var UpdateService; var init_updateService = __esm({ "packages/ag-charts-community/src/chart/updateService.ts"() { "use strict"; init_main(); UpdateService = class { constructor(updateCallback) { this.updateCallback = updateCallback; this.events = new EventEmitter(); } addListener(eventName, listener) { return this.events.on(eventName, listener); } removeListener(eventName, listener) { return this.events.on(eventName, listener); } destroy() { this.events.clear(); } update(type = 0 /* FULL */, options) { this.updateCallback(type, options); } dispatchUpdateComplete() { this.events.emit("update-complete", { type: "update-complete" }); } dispatchPreDomUpdate() { this.events.emit("pre-dom-update", { type: "pre-dom-update" }); } dispatchPreSceneRender() { this.events.emit("pre-scene-render", { type: "pre-scene-render" }); } dispatchProcessData({ series }) { this.events.emit("process-data", { type: "process-data", series }); } }; } }); // packages/ag-charts-community/src/chart/chartContext.ts var ChartContext; var init_chartContext = __esm({ "packages/ag-charts-community/src/chart/chartContext.ts"() { "use strict"; init_chartTypeOriginator(); init_historyManager(); init_stateManager(); init_domManager(); init_proxyInteractionService(); init_localeManager(); init_module(); init_scene(); init_callbackCache(); init_annotationManager(); init_axisManager(); init_dataService(); init_animationManager(); init_chartEventManager(); init_contextMenuRegistry(); init_highlightManager(); init_interactionManager(); init_tooltipManager(); init_widgetSet(); init_zoomManager(); init_layoutManager(); init_seriesLabelLayoutManager(); init_legendManager(); init_seriesStateManager(); init_updateService(); ChartContext = class { constructor(chart, vars) { this.callbackCache = new CallbackCache(); this.chartEventManager = new ChartEventManager(); this.highlightManager = new HighlightManager(); this.layoutManager = new LayoutManager(); this.localeManager = new LocaleManager(); this.seriesStateManager = new SeriesStateManager(); this.stateManager = new StateManager(); this.seriesLabelLayoutManager = new SeriesLabelLayoutManager(); this.contextModules = []; const { scene, root, syncManager, container, fireEvent, updateCallback, updateMutex, styleContainer, chartType } = vars; this.chartService = chart; this.syncManager = syncManager; this.domManager = new DOMManager(container, styleContainer); this.widgets = new WidgetSet(this.domManager); const canvasElement = this.domManager.addChild( "canvas", "scene-canvas", scene?.canvas.element ); this.scene = scene ?? new Scene({ canvasElement }); this.scene.setRoot(root); this.axisManager = new AxisManager(root); this.legendManager = new LegendManager(); this.annotationManager = new AnnotationManager(chart.annotationRoot); this.chartTypeOriginator = new ChartTypeOriginator(chart); this.interactionManager = new InteractionManager(); this.contextMenuRegistry = new ContextMenuRegistry(); this.updateService = new UpdateService(updateCallback); this.proxyInteractionService = new ProxyInteractionService(this.localeManager, this.domManager); this.historyManager = new HistoryManager(this.chartEventManager); this.animationManager = new AnimationManager(this.interactionManager, updateMutex); this.dataService = new DataService(this.animationManager); this.tooltipManager = new TooltipManager(this.domManager, chart.tooltip); this.zoomManager = new ZoomManager(fireEvent, this.layoutManager); for (const module2 of moduleRegistry.byType("context")) { if (!module2.chartTypes.includes(chartType)) continue; const moduleInstance = module2.moduleFactory(this); this.contextModules.push(moduleInstance); this[module2.contextKey] = moduleInstance; } } destroy() { this.animationManager.destroy(); this.highlightManager.destroy(); this.axisManager.destroy(); this.callbackCache.invalidateCache(); this.chartEventManager.destroy(); this.domManager.destroy(); this.highlightManager.destroy(); this.proxyInteractionService.destroy(); this.syncManager.destroy(); this.tooltipManager.destroy(); this.zoomManager.destroy(); this.widgets.destroy(); this.contextModules.forEach((m) => m.destroy()); } }; } }); // packages/ag-charts-community/src/chart/chartHighlight.ts var ChartHighlight; var init_chartHighlight = __esm({ "packages/ag-charts-community/src/chart/chartHighlight.ts"() { "use strict"; init_properties(); init_validation2(); ChartHighlight = class extends BaseProperties { constructor() { super(...arguments); this.range = "tooltip"; } }; __decorateClass([ Validate(UNION(["tooltip", "node"], "a range")) ], ChartHighlight.prototype, "range", 2); } }); // packages/ag-charts-community/src/chart/data/caching.ts function setsEqual(a, b) { if (a.size !== b.size) return false; for (const value of a) { if (!b.has(value)) return false; } return true; } function idsMapEqual(a, b) { if (a == null || b == null) return a === b; if (a.size !== b.size) return false; for (const [key, aValue] of a) { const bValue = b.get(key); if (bValue == null) return false; if (!setsEqual(aValue, bValue)) return false; } return true; } function propsEqual(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i += 1) { const { type: typeA, idsMap: idsMapA, scopes: scopesA, data: dataA, ...propA } = a[i]; const { type: typeB, idsMap: idsMapB, scopes: scopesB, data: dataB, ...propB } = b[i]; if (typeA !== typeB) return false; if (scopesA && scopesB && !arraysEqual(scopesA, scopesB)) return false; if (dataA && dataB && dataA !== dataB) return false; if (!objectsEqual(propA, propB) || !idsMapEqual(idsMapA, idsMapB)) return false; } return true; } function optsEqual(a, b) { const { props: propsA, ...restA } = a; const { props: propsB, ...restB } = b; return objectsEqual(restA, restB) && propsEqual(propsA, propsB); } function canReuseCachedData(cachedDataItem, data, ids, opts) { return data === cachedDataItem.data && arraysEqual(ids, cachedDataItem.ids) && optsEqual(opts, cachedDataItem.opts); } var init_caching = __esm({ "packages/ag-charts-community/src/chart/data/caching.ts"() { "use strict"; init_main(); init_object(); } }); // packages/ag-charts-community/src/chart/data/dataDomain.ts var DiscreteDomain, ContinuousDomain; var init_dataDomain = __esm({ "packages/ag-charts-community/src/chart/data/dataDomain.ts"() { "use strict"; DiscreteDomain = class _DiscreteDomain { constructor() { this.domain = /* @__PURE__ */ new Set(); } static is(value) { return value instanceof _DiscreteDomain; } extend(val) { this.domain.add(val); } getDomain() { return Array.from(this.domain); } }; ContinuousDomain = class _ContinuousDomain { constructor() { this.domain = [Infinity, -Infinity]; } static is(value) { return value instanceof _ContinuousDomain; } static extendDomain(values, domain = [Infinity, -Infinity]) { for (const value of values) { if (typeof value !== "number") { continue; } if (domain[0] > value) { domain[0] = value; } if (domain[1] < value) { domain[1] = value; } } return domain; } extend(value) { if (this.domain[0] > value) { this.domain[0] = value; } if (this.domain[1] < value) { this.domain[1] = value; } } getDomain() { return [...this.domain]; } }; } }); // packages/ag-charts-community/src/chart/data/rangeLookup.ts var MIN, MAX, SPAN, RangeLookup; var init_rangeLookup = __esm({ "packages/ag-charts-community/src/chart/data/rangeLookup.ts"() { "use strict"; MIN = 0; MAX = 1; SPAN = 2; RangeLookup = class { constructor(allValues) { const dataLength = allValues.reduce((acc, v) => Math.max(acc, v.length), 0); const sizePower = 32 - Math.clz32(dataLength); let maxLevelSize = 1 << sizePower; if (dataLength === maxLevelSize / 2) { maxLevelSize = maxLevelSize >>> 1; } this.maxLevelSize = maxLevelSize; const buffer = new Float64Array((maxLevelSize * 2 - 1) * 2).fill(NaN); for (const values of allValues) { for (let i = 0; i < values.length; i += 1) { const value = Number(values[i]); const bufferIndex = maxLevelSize + i - 1; const bufferMinIndex = (bufferIndex * SPAN | 0) + MIN; const bufferMaxIndex = (bufferIndex * SPAN | 0) + MAX; const prevMinValue = buffer[bufferMinIndex]; const prevMaxValue = buffer[bufferMaxIndex]; if (!Number.isFinite(prevMinValue) || value < prevMinValue) { buffer[bufferMinIndex] = value; } if (!Number.isFinite(prevMaxValue) || value > prevMaxValue) { buffer[bufferMaxIndex] = value; } } } for (let size = maxLevelSize / 2 | 0; size >= 1; size = size / 2 | 0) { const start2 = size - 1 | 0; const end2 = start2 + size | 0; for (let i = 0; i < size; i += 1) { const nodeIndex = start2 + i; const leftIndex = end2 + i * 2; const rightIndex = leftIndex + 1; const aMin = buffer[(leftIndex * SPAN | 0) + MIN]; const bMin = buffer[(rightIndex * SPAN | 0) + MIN]; buffer[(nodeIndex * SPAN | 0) + MIN] = !Number.isFinite(bMin) || aMin < bMin ? aMin : bMin; const aMax = buffer[(leftIndex * SPAN | 0) + MAX]; const bMax = buffer[(rightIndex * SPAN | 0) + MAX]; buffer[(nodeIndex * SPAN | 0) + MAX] = !Number.isFinite(bMax) || aMax > bMax ? aMax : bMax; } } this.buffer = buffer; } computeRangeInto(buffer, start2, end2, bufferIndex, currentStart, step, into) { const currentEnd = currentStart + step - 1; if (currentEnd < start2 || currentStart >= end2) return into; if (currentStart >= start2 && currentEnd < end2) { const min = buffer[(bufferIndex * SPAN | 0) + MIN]; const max = buffer[(bufferIndex * SPAN | 0) + MAX]; if (Number.isFinite(min)) into[0] = Math.min(into[0], min); if (Number.isFinite(max)) into[1] = Math.max(into[1], max); } else if (step > 1) { bufferIndex = bufferIndex * 2 | 0; step = step / 2 | 0; this.computeRangeInto(buffer, start2, end2, bufferIndex + 1 | 0, currentStart, step, into); this.computeRangeInto(buffer, start2, end2, bufferIndex + 2 | 0, currentStart + step, step, into); } return into; } rangeBetween(start2, end2) { if (start2 > end2) return [NaN, NaN]; const { maxLevelSize, buffer } = this; const range4 = [Infinity, -Infinity]; this.computeRangeInto(buffer, start2, end2, 0, 0, maxLevelSize, range4); return range4; } get range() { const { buffer } = this; return [buffer[MIN], buffer[MAX]]; } }; } }); // packages/ag-charts-community/src/chart/data/dataModel.ts function toKeyString(keys) { return keys.map((key) => isObject(key) ? JSON.stringify(key) : key).join("-"); } function round3(val) { const accuracy = 1e4; if (Number.isInteger(val)) { return val; } else if (Math.abs(val) > accuracy) { return Math.trunc(val); } return Math.round(val * accuracy) / accuracy; } function fixNumericExtent(extent3) { const numberExtent = extent3?.map(Number); return numberExtent?.every(Number.isFinite) ? numberExtent : []; } function getMissCount(scopeProvider, missMap) { return missMap?.get(scopeProvider.id) ?? 0; } function isScoped(obj) { return "scopes" in obj && Array.isArray(obj.scopes); } function createArray(length2, value) { const out = []; for (let i = 0; i < length2; i += 1) { out[i] = value; } return out; } function datumKeys(keys, columnScope, datumIndex) { const out = []; for (const k of keys) { const key = k.get(columnScope)?.[datumIndex]; if (key == null) return; out.push(key); } return out; } function getPathComponents(path) { const components = []; let matchIndex = 0; let matchGroup; const regExp = /((?:(?:^|\.)\s*\w+|\[\s*(?:'(?:[^']|(? { let current = datum; for (const component of components) { current = current[component]; } return current; }; } function logProcessedData(processedData) { const logValues = (name, data) => { if (data.length > 0) { logger_exports.log(`DataModel.processData() - ${name}`); logger_exports.table(data); } }; logger_exports.log("DataModel.processData() - processedData", processedData); logValues("Key Domains", processedData.domain.keys); logValues("Group Domains", processedData.domain.groups ?? []); logValues("Value Domains", processedData.domain.values); logValues("Aggregate Domains", processedData.domain.aggValues ?? []); } var DOMAIN_RANGES, INVALID_VALUE, DataModel; var init_dataModel = __esm({ "packages/ag-charts-community/src/chart/data/dataModel.ts"() { "use strict"; init_main(); init_debug(); init_number(); init_dataDomain(); init_rangeLookup(); DOMAIN_RANGES = Symbol("domain-ranges"); INVALID_VALUE = Symbol("invalid"); DataModel = class { constructor(opts, mode = "standalone", suppressFieldDotNotation = false) { this.opts = opts; this.mode = mode; this.suppressFieldDotNotation = suppressFieldDotNotation; this.debug = Debug.create(true, "data-model"); this.scopeCache = /* @__PURE__ */ new Map(); this.keys = []; this.values = []; this.aggregates = []; this.groupProcessors = []; this.propertyProcessors = []; this.reducers = []; this.processors = []; this.markScopeDatumInvalid = function(scopes, data, datumIndex, invalidData) { for (const scope of scopes) { if (!invalidData.has(scope)) { invalidData.set(scope, createArray(data.length, false)); } invalidData.get(scope)[datumIndex] = true; } }; let keys = true; for (const next of opts.props) { if (next.type === "key" && !keys) { throw new Error("AG Charts - internal config error: keys must come before values."); } if (next.type === "value" && keys) { keys = false; } } const verifyMatchGroupId = ({ matchGroupIds = [] }) => { for (const matchGroupId of matchGroupIds) { if (this.values.every((def) => def.groupId !== matchGroupId)) { throw new Error( `AG Charts - internal config error: matchGroupIds properties must match defined groups (${matchGroupId}).` ); } } }; const keyScopes = /* @__PURE__ */ new Set(); const valueScopes = /* @__PURE__ */ new Set(); for (const def of opts.props) { const scopes = def.type === "key" ? keyScopes : valueScopes; if (isScoped(def)) { def.scopes?.forEach((s) => scopes.add(s)); } switch (def.type) { case "key": this.keys.push({ ...def, index: this.keys.length, missing: /* @__PURE__ */ new Map() }); break; case "value": if (def.property == null) { throw new Error( `AG Charts - internal config error: no properties specified for value definitions: ${JSON.stringify( def )}` ); } this.values.push({ ...def, index: this.values.length, missing: /* @__PURE__ */ new Map() }); break; case "aggregate": verifyMatchGroupId(def); this.aggregates.push({ ...def, index: this.aggregates.length }); break; case "group-value-processor": verifyMatchGroupId(def); this.groupProcessors.push({ ...def, index: this.groupProcessors.length }); break; case "property-value-processor": this.propertyProcessors.push({ ...def, index: this.propertyProcessors.length }); break; case "reducer": this.reducers.push({ ...def, index: this.reducers.length }); break; case "processor": this.processors.push({ ...def, index: this.processors.length }); break; } } if (!!this.opts.groupByKeys || this.opts.groupByFn != null) { const ungroupedScopes = new Set(valueScopes.values()); keyScopes.forEach((s) => ungroupedScopes.delete(s)); if (ungroupedScopes.size > 0) { throw new Error( `AG Charts - scopes missing key for grouping, illegal configuration: ${[...ungroupedScopes.values()]}` ); } } } resolveProcessedDataDefById(scope, searchId) { const def = this.scopeCache.get(scope.id)?.get(searchId); if (!def) { throw new Error(`AG Charts - didn't find property definition for [${searchId}, ${scope.id}]`); } return { index: def.index, def }; } resolveProcessedDataIndexById(scope, searchId) { return this.resolveProcessedDataDefById(scope, searchId).index; } resolveKeysById(scope, searchId, processedData) { const index = this.resolveProcessedDataIndexById(scope, searchId); const keys = processedData.keys[index]; if (keys == null) { throw new Error(`AG Charts - didn't find keys for [${searchId}, ${scope.id}]`); } return keys.get(scope.id); } hasColumnById(scope, searchId) { return this.scopeCache.get(scope.id)?.get(searchId) != null; } resolveColumnById(scope, searchId, processedData) { const index = this.resolveProcessedDataIndexById(scope, searchId); const column = processedData.columns?.[index]; if (column == null) { throw new Error(`AG Charts - didn't find column for [${searchId}, ${scope.id}]`); } return column; } /** * Provides a convenience iterator to iterate over all of the extract datum values in a * specific DataGroup. * * @param scope to which datums should belong * @param group containing the datums * @param processedData containing the group */ *forEachDatum(scope, processedData, group) { const columnIndex = processedData.columnScopes.findIndex((s) => s.has(scope.id)); for (const datumIndex of group.datumIndices[columnIndex] ?? []) { yield processedData.columns[columnIndex][datumIndex]; } } /** * Provides a convenience iterator to iterate over all of the extracted datum values in a * GroupedData. * * @param scope to which datums should belong * @param processedData to iterate through */ *forEachGroupDatum(scope, processedData) { const columnIndex = processedData.columnScopes.findIndex((s) => s.has(scope.id)); const output = { groupIndex: 0, columnIndex }; const empty = []; for (const group of processedData.groups) { output.group = group; let valueIndex = 0; for (const datumIndex of group.datumIndices[columnIndex] ?? empty) { output.datumIndex = datumIndex; output.valueIndex = valueIndex++; yield output; } output.groupIndex++; } } /** * Provides a window-based convenience iterator to iterate over all of the extracted datum * values in a GroupedData, including the previous and next entries relative to each datum. * * @param scope to which datums should belong * @param processedData to iterate through */ *forEachGroupDatumTuple(scope, processedData) { const columnIndex = processedData.columnScopes.findIndex((s) => s.has(scope.id)); const output = { columnIndex, datumIndexes: [void 0, void 0, void 0] }; for (const next of this.forEachGroupDatum(scope, processedData)) { output.group = output.nextGroup; output.groupIndex = output.nextGroupIndex; output.nextGroup = next.group; output.nextGroupIndex = next.groupIndex; output.datumIndexes[0] = output.datumIndexes[1]; output.datumIndexes[1] = output.datumIndexes[2]; output.datumIndexes[2] = next.datumIndex; if (output.group != null && output.datumIndexes[1] != null) { yield output; } } output.group = output.nextGroup; output.groupIndex = output.nextGroupIndex; output.nextGroup = void 0; output.nextGroupIndex = void 0; output.datumIndexes[0] = output.datumIndexes[1]; output.datumIndexes[1] = output.datumIndexes[2]; output.datumIndexes[2] = void 0; if (output.group != null && output.datumIndexes[1] != null) { yield output; } } getDomain(scope, searchId, type, processedData) { const domains = this.getDomainsByType(type ?? "value", processedData); return domains?.[this.resolveProcessedDataIndexById(scope, searchId)] ?? []; } getDomainBetweenRange(scope, searchIds, [i0, i1], processedData) { const columnIndices = searchIds.map((searchId) => this.resolveProcessedDataIndexById(scope, searchId)); const cacheKey = columnIndices.join(":"); const domainRanges = processedData[DOMAIN_RANGES]; let rangeLookup = domainRanges.get(cacheKey); if (rangeLookup == null) { const values = columnIndices.map((columnIndex) => processedData.columns[columnIndex]); rangeLookup = new RangeLookup(values); domainRanges.set(cacheKey, rangeLookup); } return rangeLookup.rangeBetween(i0, i1); } getDomainsByType(type, processedData) { switch (type) { case "key": return processedData.domain.keys; case "value": return processedData.domain.values; case "aggregate": return processedData.domain.aggValues; case "group-value-processor": return processedData.domain.groups; default: return null; } } processData(sources) { const { opts: { groupByKeys, groupByFn }, aggregates, groupProcessors, reducers, processors, propertyProcessors } = this; const start2 = performance.now(); if (groupByKeys && this.keys.length === 0) { return; } let processedData = this.extractData(sources); if (groupByKeys) { processedData = this.groupData(processedData); } else if (groupByFn) { processedData = this.groupData(processedData, groupByFn(processedData)); } if (groupProcessors.length > 0 && processedData.type === "grouped") { this.postProcessGroups(processedData); } if (aggregates.length > 0 && processedData.type === "ungrouped") { this.aggregateUngroupedData(processedData); } else if (aggregates.length > 0 && processedData.type === "grouped") { this.aggregateGroupedData(processedData); } if (propertyProcessors.length > 0) { this.postProcessProperties(processedData); } if (reducers.length > 0) { this.reduceData(processedData); } if (processors.length > 0) { this.postProcessData(processedData); } this.warnDataMissingProperties(sources); const end2 = performance.now(); processedData.time = end2 - start2; if (this.debug.check()) { logProcessedData(processedData); } this.processScopeCache(); return processedData; } warnDataMissingProperties(sources) { if (sources.size === 0) return; for (const def of iterate(this.keys, this.values)) { for (const [scope, missCount] of def.missing) { if (missCount < (sources.get(scope)?.length ?? Infinity)) continue; const scopeHint = scope == null ? "" : ` for ${scope}`; logger_exports.warnOnce(`the key '${def.property}' was not found in any data element${scopeHint}.`); } } } processScopeCache() { this.scopeCache.clear(); for (const def of iterate(this.keys, this.values, this.aggregates)) { if (!def.idsMap) continue; for (const [scope, ids] of def.idsMap) { for (const id of ids) { if (!this.scopeCache.has(scope)) { this.scopeCache.set(scope, /* @__PURE__ */ new Map([[id, def]])); } else if (this.scopeCache.get(scope)?.has(id)) { throw new Error("duplicate definition ids on the same scope are not allowed."); } else { this.scopeCache.get(scope).set(id, def); } } } } } valueGroupIdxLookup({ matchGroupIds }) { const result = []; for (const [index, def] of this.values.entries()) { if (!matchGroupIds || def.groupId && matchGroupIds.includes(def.groupId)) { result.push(index); } } return result; } valueIdxLookup(scopes, prop) { const noScopesToMatch = scopes == null || scopes.length === 0; const propId = typeof prop === "string" ? prop : prop.id; const hasMatchingScopeId = (def) => { if (def.idsMap) { for (const [scope, ids] of def.idsMap) { if (scopes?.includes(scope) && ids.has(propId)) { return true; } } } return false; }; const result = this.values.reduce((res, def, index) => { const validDefScopes = def.scopes == null || noScopesToMatch && !def.scopes.length || def.scopes.some((s) => scopes?.includes(s)); if (validDefScopes && (def.property === propId || def.id === propId || hasMatchingScopeId(def))) { res.push(index); } return res; }, []); if (result.length === 0) { throw new Error( `AG Charts - configuration error, unknown property ${JSON.stringify(prop)} in scope(s) ${JSON.stringify( scopes )}` ); } return result; } extractData(sources) { const { dataDomain, processValue, allScopesHaveSameDefs } = this.initDataDomainProcessor(); const { keys: keyDefs, values: valueDefs } = this; const { invalidData, invalidKeys, allKeyMappings } = this.extractKeys(keyDefs, sources, processValue); const { columns, columnScopes, partialValidDataCount, maxDataLength } = this.extractValues( invalidData, valueDefs, sources, invalidKeys, processValue ); const propertyDomain = (def) => { const defDomain = dataDomain.get(def); const result = defDomain.getDomain(); if (ContinuousDomain.is(defDomain) && result[0] > result[1]) { return []; } return result; }; return { type: "ungrouped", input: { count: maxDataLength }, scopes: new Set(sources.keys()), dataSources: sources, aggregation: void 0, keys: [...allKeyMappings.values()], columns, columnScopes, invalidKeys, invalidData, domain: { keys: keyDefs.map(propertyDomain), values: valueDefs.map(propertyDomain) }, defs: { allScopesHaveSameDefs, keys: keyDefs, values: valueDefs }, partialValidDataCount, time: 0, [DOMAIN_RANGES]: /* @__PURE__ */ new Map() }; } extractKeys(keyDefs, sources, processValue) { const invalidKeys = /* @__PURE__ */ new Map(); const invalidData = /* @__PURE__ */ new Map(); const allKeys = /* @__PURE__ */ new Map(); let keyDefKeys; let scopeDataProcessed; const cloneScope = (source, target) => { const sourceScope = scopeDataProcessed.get(source); keyDefKeys.set(target, keyDefKeys.get(sourceScope)); if (invalidKeys.has(sourceScope)) { invalidKeys.set(target, invalidKeys.get(sourceScope)); invalidData.set(target, invalidData.get(sourceScope)); } }; for (const keyDef of keyDefs) { const { invalidValue, scopes: keyScopes } = keyDef; keyDefKeys = /* @__PURE__ */ new Map(); scopeDataProcessed = /* @__PURE__ */ new Map(); allKeys.set(keyDef, keyDefKeys); for (const scope of keyScopes ?? []) { const data = sources.get(scope) ?? []; if (scopeDataProcessed.has(data)) { cloneScope(data, scope); continue; } const keys = []; keyDefKeys.set(scope, keys); scopeDataProcessed.set(data, scope); let invalidScopeKeys; let invalidScopeData; for (let datumIndex = 0; datumIndex < data.length; datumIndex++) { const key = processValue(keyDef, data[datumIndex], datumIndex, scope); if (key !== INVALID_VALUE) { keys.push(key); continue; } keys.push(invalidValue); invalidScopeKeys ?? (invalidScopeKeys = createArray(data.length, false)); invalidScopeData ?? (invalidScopeData = createArray(data.length, false)); invalidScopeKeys[datumIndex] = true; invalidScopeData[datumIndex] = true; } if (invalidScopeKeys && invalidScopeData) { invalidKeys.set(scope, invalidScopeKeys); invalidData.set(scope, invalidScopeData); } } } return { invalidData, invalidKeys, allKeyMappings: allKeys }; } extractValues(invalidData, valueDefs, sources, invalidKeys, processValue) { let partialValidDataCount = 0; const columns = []; const allColumnScopes = []; let maxDataLength = 0; for (const def of valueDefs) { const { invalidValue } = def; const valueSources = new Set(def.scopes.map((s) => sources.get(s))); if (valueSources.size > 1) { throw new Error(`AG Charts - more than one data source for: ${JSON.stringify(def)}`); } const columnScopes = new Set(def.scopes); const columnScope = first(def.scopes); const columnSource = sources.get(columnScope); const column = columnSource.map((valueDatum, datumIndex) => { const invalidKey = invalidKeys.get(columnScope)?.[datumIndex]; let value = processValue(def, valueDatum, datumIndex, def.scopes); if (invalidKey || value === INVALID_VALUE) { this.markScopeDatumInvalid(def.scopes, columnSource, datumIndex, invalidData); } if (invalidKey) { value = invalidValue; } else if (value === INVALID_VALUE) { partialValidDataCount += 1; value = invalidValue; } return value; }); columns.push(column); allColumnScopes.push(columnScopes); maxDataLength = Math.max(maxDataLength, column.length); } return { columns, columnScopes: allColumnScopes, partialValidDataCount, maxDataLength }; } groupData(data, groupingFn) { var _a; const groups = /* @__PURE__ */ new Map(); const { keys: dataKeys, columns: allColumns, columnScopes, invalidKeys, invalidData } = data; const allScopes = data.scopes; const processedColumnIndexes = /* @__PURE__ */ new Set(); for (const scope of allScopes) { const scopeColumnIndexes = allColumns.map((_, idx) => idx).filter((idx) => !processedColumnIndexes.has(idx) && columnScopes[idx].has(scope)); if (scopeColumnIndexes.length === 0) continue; for (const idx of scopeColumnIndexes) { processedColumnIndexes.add(idx); } const siblingScopes = /* @__PURE__ */ new Set(); for (const columnIdx of scopeColumnIndexes) { for (const columnScope of columnScopes[columnIdx]) { siblingScopes.add(columnScope); } } const scopeKeys = dataKeys.map((k) => k.get(scope)).filter((k) => k != null); const firstColumn = allColumns[first(scopeColumnIndexes)]; const scopeInvalidData = invalidData?.get(scope); const scopeInvalidKeys = invalidKeys?.get(scope); for (let datumIndex = 0; datumIndex < firstColumn.length; datumIndex++) { if (scopeInvalidKeys?.[datumIndex] === true) continue; const keys = scopeKeys.map((k) => k[datumIndex]); if (keys == null || keys.length === 0) { throw new Error("AG Charts - no keys found for scope: " + scope); } const group = groupingFn?.(keys) ?? keys; const groupStr = toKeyString(group); const outputGroup = groups.get(groupStr) ?? { keys: group, datumIndices: [], validScopes: allScopes }; if (!groups.has(groupStr)) { groups.set(groupStr, outputGroup); } if (scopeInvalidData?.[datumIndex] === true) { if (outputGroup.validScopes === allScopes) { outputGroup.validScopes = new Set(allScopes.values()); } for (const invalidScope of siblingScopes) { outputGroup.validScopes.delete(invalidScope); } } if (outputGroup.validScopes.size === 0) continue; for (const columnIdx of scopeColumnIndexes) { (_a = outputGroup.datumIndices)[columnIdx] ?? (_a[columnIdx] = []); outputGroup.datumIndices[columnIdx].push(datumIndex); } } } const resultGroups = []; const resultData = []; for (const { keys, datumIndices, validScopes } of groups.values()) { if (validScopes?.size === 0) continue; resultGroups.push(keys); resultData.push({ datumIndices, keys, aggregation: [], validScopes }); } return { ...data, type: "grouped", domain: { ...data.domain, groups: resultGroups }, groups: resultData }; } aggregateUngroupedData(processedData) { const domainAggValues = this.aggregates.map(() => [Infinity, -Infinity]); processedData.domain.aggValues = domainAggValues; const { keys, columns, dataSources } = processedData; const onlyScope = first(dataSources.keys()); const rawData = dataSources.get(onlyScope); processedData.aggregation = rawData?.map((_, datumIndex) => { const aggregation = []; for (const [index, def] of this.aggregates.entries()) { const indices = this.valueGroupIdxLookup(def); let groupAggValues = def.groupAggregateFunction?.() ?? [Infinity, -Infinity]; const valuesToAgg = indices.map((columnIndex) => columns[columnIndex][datumIndex]); const k = datumKeys(keys, onlyScope, datumIndex); const valuesAgg = k != null ? def.aggregateFunction(valuesToAgg, k) : void 0; if (valuesAgg) { groupAggValues = def.groupAggregateFunction?.(valuesAgg, groupAggValues) ?? ContinuousDomain.extendDomain(valuesAgg, groupAggValues); } const finalValues = def.finalFunction?.(groupAggValues) ?? groupAggValues; if (def.round === true) { for (const idx in finalValues) { finalValues[idx] = round3(finalValues[idx]); } } aggregation[index] = finalValues; ContinuousDomain.extendDomain(finalValues, domainAggValues[index]); } return aggregation; }); } aggregateGroupedData(processedData) { const domainAggValues = this.aggregates.map(() => [Infinity, -Infinity]); processedData.domain.aggValues = domainAggValues; const { columns } = processedData; for (const [index, def] of this.aggregates.entries()) { const indices = this.valueGroupIdxLookup(def); for (const group of processedData.groups) { group.aggregation ?? (group.aggregation = []); if (group.validScopes?.size === 0) continue; const groupKeys = group.keys; let groupAggValues = def.groupAggregateFunction?.() ?? [Infinity, -Infinity]; const maxDatumIndex = Math.max( ...indices.map((columnIndex) => group.datumIndices[columnIndex]?.length ?? 0) ); for (let datumIndex = 0; datumIndex < maxDatumIndex; datumIndex++) { const valuesToAgg = indices.map( (columnIndex) => columns[columnIndex][group.datumIndices[columnIndex]?.[datumIndex]] ); const valuesAgg = def.aggregateFunction(valuesToAgg, groupKeys); if (valuesAgg) { groupAggValues = def.groupAggregateFunction?.(valuesAgg, groupAggValues) ?? ContinuousDomain.extendDomain(valuesAgg, groupAggValues); } } const finalValues = def.finalFunction?.(groupAggValues) ?? groupAggValues; if (def.round === true) { for (const idx in finalValues) { finalValues[idx] = round3(finalValues[idx]); } } group.aggregation[index] = finalValues; ContinuousDomain.extendDomain(finalValues, domainAggValues[index]); } } } postProcessGroups(processedData) { const { groupProcessors } = this; const { columnScopes, columns, invalidData, scopes } = processedData; for (const processor of groupProcessors) { const valueIndexes = this.valueGroupIdxLookup(processor); const adjustFn = processor.adjust()(); for (const dataGroup of processedData.groups) { if (dataGroup.validScopes !== scopes) continue; adjustFn(columns, valueIndexes, dataGroup); } for (const valueIndex of valueIndexes) { const valueDef = this.values[valueIndex]; const isDiscrete = valueDef.valueType === "category"; const column = columns[valueIndex]; const columnScope = first(columnScopes[valueIndex]); const invalidDatums = invalidData?.get(columnScope); const domain = isDiscrete ? new DiscreteDomain() : new ContinuousDomain(); for (let datumIndex = 0; datumIndex < column.length; datumIndex += 1) { if (invalidDatums?.[datumIndex] === true) continue; domain.extend(column[datumIndex]); } processedData.domain.values[valueIndex] = domain.getDomain(); } } } postProcessProperties(processedData) { for (const { adjust, property, scopes } of this.propertyProcessors) { for (const idx of this.valueIdxLookup(scopes, property)) { adjust()(processedData, idx); } } } reduceData(processedData) { processedData.reduced ?? (processedData.reduced = {}); const { dataSources, keys } = processedData; for (const def of this.reducers) { const reducer = def.reducer(); let accValue = def.initialValue; if (processedData.type === "grouped") { for (const group of processedData.groups) { accValue = reducer(accValue, group.keys); } } else { const onlyScope = first(dataSources.keys()); const keyColumns = keys.map((k) => k.get(onlyScope)).filter((k) => k != null); const keysParam = keyColumns.map(() => void 0); const rawData = dataSources.get(onlyScope); for (let datumIndex = 0; datumIndex < rawData.length; datumIndex += 1) { for (let keyIdx = 0; keyIdx < keysParam.length; keyIdx++) { keysParam[keyIdx] = keyColumns[keyIdx]?.[datumIndex]; } accValue = reducer(accValue, keysParam); } } processedData.reduced[def.property] = accValue; } } postProcessData(processedData) { processedData.reduced ?? (processedData.reduced = {}); for (const def of this.processors) { processedData.reduced[def.property] = def.calculate( processedData, processedData.reduced[def.property] ); } } initDataDomainProcessor() { const { keys: keyDefs, values: valueDefs } = this; const scopes = /* @__PURE__ */ new Set(); for (const valueDef of valueDefs) { if (!valueDef.scopes) continue; for (const scope of valueDef.scopes) { scopes.add(scope); } } const dataDomain = /* @__PURE__ */ new Map(); const processorFns = /* @__PURE__ */ new Map(); let allScopesHaveSameDefs = true; const initDataDomain = () => { for (const def of iterate(keyDefs, valueDefs)) { if (def.valueType === "category") { dataDomain.set(def, new DiscreteDomain()); } else { dataDomain.set(def, new ContinuousDomain()); allScopesHaveSameDefs && (allScopesHaveSameDefs = (def.scopes ?? []).length === scopes.size); } } }; initDataDomain(); const accessors = this.buildAccessors(iterate(keyDefs, valueDefs)); const processValue = (def, datum, idx, valueScopes) => { let valueInDatum; let value; if (accessors.has(def.property)) { try { value = accessors.get(def.property)(datum); } catch { } valueInDatum = value != null; } else { valueInDatum = def.property in datum; value = valueInDatum ? datum[def.property] : def.missingValue; } if (def.forceValue != null) { const valueNegative = valueInDatum && isNegative(value); value = valueNegative ? -1 * def.forceValue : def.forceValue; valueInDatum = true; } const missingValueDef = "missingValue" in def; if (!valueInDatum && !missingValueDef) { if (typeof valueScopes === "string") { const missCount = def.missing.get(valueScopes) ?? 0; def.missing.set(valueScopes, missCount + 1); } else { for (const scope of valueScopes) { const missCount = def.missing.get(scope) ?? 0; def.missing.set(scope, missCount + 1); } } } if (!dataDomain.has(def)) { initDataDomain(); } if (valueInDatum && def.validation?.(value, datum, idx) === false) { if ("invalidValue" in def) { value = def.invalidValue; } else { if (this.mode !== "integrated") { logger_exports.warnOnce( `invalid value of type [${typeof value}] for [${def.scopes} / ${def.id}] ignored:`, `[${value}]` ); } return INVALID_VALUE; } } if (def.processor) { if (!processorFns.has(def)) { processorFns.set(def, def.processor()); } value = processorFns.get(def)?.(value); } dataDomain.get(def)?.extend(value); return value; }; return { dataDomain, processValue, initDataDomain, scopes, allScopesHaveSameDefs }; } buildAccessors(defs) { const result = /* @__PURE__ */ new Map(); if (this.suppressFieldDotNotation) { return result; } for (const def of defs) { const isPath = def.property.includes(".") || def.property.includes("["); if (!isPath) continue; const components = getPathComponents(def.property); if (components == null) { logger_exports.warnOnce("Invalid property path [%s]", def.property); continue; } const accessor = createPathAccessor(components); result.set(def.property, accessor); } return result; } }; } }); // packages/ag-charts-community/src/chart/data/dataController.ts var _DataController, DataController; var init_dataController = __esm({ "packages/ag-charts-community/src/chart/data/dataController.ts"() { "use strict"; init_core(); init_debug(); init_caching(); init_dataModel(); _DataController = class _DataController { constructor(mode, suppressFieldDotNotation) { this.mode = mode; this.suppressFieldDotNotation = suppressFieldDotNotation; this.debug = Debug.create(true, "data-model"); this.requested = []; this.status = "setup"; } async request(id, data, opts) { if (this.status !== "setup") { throw new Error(`AG Charts - data request after data setup phase.`); } return new Promise((resolve, reject) => { this.requested.push({ id, opts, data, resolve, reject }); }); } execute(cachedData) { if (this.status !== "setup") { throw new Error(`AG Charts - data request after data setup phase.`); } this.status = "executed"; this.debug("DataController.execute() - requested", this.requested); const valid = this.validateRequests(this.requested); this.debug("DataController.execute() - validated", valid); const merged = this.mergeRequested(valid); this.debug("DataController.execute() - merged", merged); if (this.debug.check()) { getWindow().processedData = []; } const nextCachedData = []; for (const { data, ids, opts, resolves, rejects } of merged) { const reusableCache = cachedData?.find((cacheItem) => canReuseCachedData(cacheItem, data, ids, opts)); let dataModel; let processedData; if (reusableCache == null) { try { dataModel = new DataModel(opts, this.mode, this.suppressFieldDotNotation); const sources = new Map(valid.map((v) => [v.id, v.data])); processedData = dataModel.processData(sources); } catch (error3) { rejects.forEach((cb) => cb(error3)); continue; } } else { ({ dataModel, processedData } = reusableCache); } nextCachedData.push({ opts, data, ids, dataModel, processedData }); if (this.debug.check()) { getWindow("processedData").push(processedData); } if (processedData?.partialValidDataCount === 0) { resolves.forEach( (resolve) => resolve({ dataModel, processedData }) ); } else if (processedData) { this.splitResult(dataModel, processedData, ids, resolves); } else { rejects.forEach((cb) => cb(new Error(`AG Charts - no processed data generated`))); } } return nextCachedData; } validateRequests(requested) { const valid = []; for (const [index, request] of requested.entries()) { if (index > 0 && request.data.length !== requested[0].data.length && request.opts.groupByData === false && request.opts.groupByKeys === false) { request.reject( new Error("all series[].data arrays must be of the same length and have matching keys.") ); } else { valid.push(request); } } return valid; } mergeRequested(requested) { const grouped = []; for (const request of requested) { const match = grouped.find(_DataController.groupMatch(request)); if (match) { match.push(request); } else { grouped.push([request]); } } return grouped.map(_DataController.mergeRequests); } splitResult(dataModel, processedData, scopes, resolves) { for (let i = 0; i < scopes.length; i++) { const resolve = resolves[i]; resolve({ dataModel, processedData }); } } static groupMatch({ data, opts }) { function keys(props2) { return props2.filter((p) => p.type === "key").map((p) => p.property).join(";"); } const { groupByData, groupByKeys = false, groupByFn, props } = opts; const propsKeys = keys(props); return ([group]) => (groupByData === false || group.data === data) && (group.opts.groupByKeys ?? false) === groupByKeys && group.opts.groupByFn === groupByFn && keys(group.opts.props) === propsKeys; } static mergeRequests(requests) { const crossScopeMergableTypes = /* @__PURE__ */ new Set(["key", "group-value-processor"]); return requests.reduce( (result, { id, data, resolve, reject, opts: { props, ...opts } }) => { result.ids.push(id); result.rejects.push(reject); result.resolves.push(resolve); result.data ?? (result.data = data); result.opts ?? (result.opts = { ...opts, props: [] }); for (const prop of props) { const clone2 = { ...prop, scopes: [id], data }; _DataController.createIdsMap(id, clone2); const match = result.opts.props.find( (existing) => existing.type === clone2.type && (crossScopeMergableTypes.has(existing.type) || existing.data === clone2.data) && _DataController.deepEqual(existing, clone2) ); if (!match) { result.opts.props.push(clone2); continue; } match.scopes ?? (match.scopes = []); match.scopes.push(...clone2.scopes ?? []); if ((match.type === "key" || match.type === "value") && clone2.idsMap?.size) { _DataController.mergeIdsMap(clone2.idsMap, match.idsMap); } } return result; }, { ids: [], rejects: [], resolves: [], data: null, opts: null } ); } static mergeIdsMap(fromMap, toMap) { for (const [scope, ids] of fromMap) { const toMapValue = toMap.get(scope); if (toMapValue == null) { toMap.set(scope, new Set(ids)); } else { for (const id of ids) { toMapValue.add(id); } } } } static createIdsMap(scope, prop) { if (prop.id == null) return; prop.idsMap ?? (prop.idsMap = /* @__PURE__ */ new Map()); if (prop.idsMap.has(scope)) { prop.idsMap.get(scope).add(prop.id); } else { prop.idsMap.set(scope, /* @__PURE__ */ new Set([prop.id])); } } static deepEqual(a, b) { if (a === b) { return true; } if (a && b && typeof a == "object" && typeof b == "object") { if (a.constructor !== b.constructor) { return false; } let i, length2; if (Array.isArray(a)) { length2 = a.length; if (length2 !== b.length) { return false; } for (i = length2 - 1; i >= 0; i--) { if (!_DataController.deepEqual(a[i], b[i])) { return false; } } return true; } const keys = Object.keys(a); length2 = keys.length; if (length2 !== Object.keys(b).length) { return false; } for (i = length2 - 1; i >= 0; i--) { const key = keys[i]; if (!_DataController.skipKeys.has(key) && (!Object.hasOwn(b, key) || !_DataController.deepEqual(a[key], b[key]))) { return false; } } return true; } return false; } }; // optimized version of deep equality for `mergeRequests` which can potentially loop over 1M times _DataController.skipKeys = /* @__PURE__ */ new Set(["id", "idsMap", "type", "scopes", "data"]); DataController = _DataController; } }); // packages/ag-charts-community/src/chart/factory/axisRegistry.ts var AxisRegistry, axisRegistry; var init_axisRegistry = __esm({ "packages/ag-charts-community/src/chart/factory/axisRegistry.ts"() { "use strict"; AxisRegistry = class { constructor() { this.axesMap = /* @__PURE__ */ new Map(); this.themeTemplates = /* @__PURE__ */ new Map(); } register(axisType, module2) { this.axesMap.set(axisType, module2.moduleFactory); if (module2.themeTemplate) { this.setThemeTemplate(axisType, module2.themeTemplate); } } create(axisType, moduleContext) { const axisFactory = this.axesMap.get(axisType); if (axisFactory) { return axisFactory(moduleContext); } throw new Error(`AG Charts - unknown axis type: ${axisType}`); } has(axisType) { return this.axesMap.has(axisType); } keys() { return this.axesMap.keys(); } setThemeTemplate(axisType, themeTemplate) { this.themeTemplates.set(axisType, themeTemplate); return this; } getThemeTemplate(axisType) { return this.themeTemplates.get(axisType); } }; axisRegistry = new AxisRegistry(); } }); // packages/ag-charts-community/src/chart/factory/expectedEnterpriseModules.ts function isEnterpriseSeriesType(type) { return EXPECTED_ENTERPRISE_MODULES.some((s) => s.type === "series" && s.identifier === type); } function getEnterpriseSeriesChartTypes(type) { return EXPECTED_ENTERPRISE_MODULES.find((s) => s.type === "series" && s.identifier === type)?.chartTypes; } function isEnterpriseCartesian(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "cartesian"); return type === "cartesian"; } function isEnterprisePolar(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "polar"); return type === "polar"; } function isEnterpriseHierarchy(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "hierarchy"); return type === "hierarchy"; } function isEnterpriseTopology(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "topology"); return type === "topology"; } function isEnterpriseFlowProportion(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "flow-proportion"); return type === "flow-proportion"; } function isEnterpriseStandalone(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "standalone"); return type === "standalone"; } function isEnterpriseGauge(seriesType) { const type = getEnterpriseSeriesChartTypes(seriesType)?.find((v) => v === "gauge"); return type === "gauge"; } function isEnterpriseModule(module2) { return module2.packageType === "enterprise"; } function verifyIfModuleExpected(module2) { if (!isEnterpriseModule(module2)) { throw new Error("AG Charts - internal configuration error, only enterprise modules need verification."); } const stub = EXPECTED_ENTERPRISE_MODULES.find((s) => { return s.type === module2.type && ("optionsKey" in s && "optionsKey" in module2 ? s.optionsKey === module2.optionsKey : true) && ("contextKey" in s && "contextKey" in module2 ? s.contextKey === module2.contextKey : true) && s.identifier === module2.identifier && module2.chartTypes.every((t) => s.chartTypes.includes(t)); }); if (stub) { stub.useCount ?? (stub.useCount = 0); stub.useCount++; } return stub != null; } function getUnusedExpectedModules() { return EXPECTED_ENTERPRISE_MODULES.filter(({ useCount }) => useCount == null || useCount === 0); } var EXPECTED_ENTERPRISE_MODULES; var init_expectedEnterpriseModules = __esm({ "packages/ag-charts-community/src/chart/factory/expectedEnterpriseModules.ts"() { "use strict"; EXPECTED_ENTERPRISE_MODULES = [ { type: "root", optionsKey: "animation", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"] }, { type: "root", optionsKey: "annotations", chartTypes: ["cartesian"] }, { type: "root", optionsKey: "background", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], optionsInnerKey: "image" }, { type: "root", optionsKey: "foreground", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], optionsInnerKey: "image" }, { type: "root", optionsKey: "chartToolbar", chartTypes: ["cartesian"] }, { type: "root", optionsKey: "contextMenu", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"] }, { type: "root", optionsKey: "statusBar", chartTypes: ["cartesian"], identifier: "status-bar" }, { type: "root", optionsKey: "dataSource", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"] }, { type: "root", optionsKey: "sync", chartTypes: ["cartesian"] }, { type: "root", optionsKey: "zoom", chartTypes: ["cartesian", "topology"] }, { type: "root", optionsKey: "ranges", chartTypes: ["cartesian"] }, { type: "legend", optionsKey: "gradientLegend", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], identifier: "gradient" }, { type: "root", optionsKey: "navigator", chartTypes: ["cartesian"] }, { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "angle-category" }, { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "angle-number" }, { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "radius-category" }, { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "radius-number" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "bar", community: true }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "line", community: true }, { type: "axis", optionsKey: "axes[]", chartTypes: ["cartesian"], identifier: "ordinal-time" }, { type: "axis-option", optionsKey: "crosshair", chartTypes: ["cartesian"] }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "box-plot" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "candlestick" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "cone-funnel" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "funnel" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "ohlc" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "heatmap" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "range-area" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "range-bar" }, { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "waterfall" }, { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "nightingale" }, { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radar-area" }, { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radar-line" }, { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radial-bar" }, { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radial-column" }, { type: "series", optionsKey: "series[]", chartTypes: ["hierarchy"], identifier: "sunburst" }, { type: "series", optionsKey: "series[]", chartTypes: ["hierarchy"], identifier: "treemap" }, { type: "series", optionsKey: "series[]", chartTypes: ["topology"], identifier: "map-shape" }, { type: "series", optionsKey: "series[]", chartTypes: ["topology"], identifier: "map-line" }, { type: "series", optionsKey: "series[]", chartTypes: ["topology"], identifier: "map-marker" }, { type: "series", optionsKey: "series[]", chartTypes: ["topology"], identifier: "map-shape-background" }, { type: "series", optionsKey: "series[]", chartTypes: ["topology"], identifier: "map-line-background" }, { type: "series", optionsKey: "series[]", chartTypes: ["flow-proportion"], identifier: "chord" }, { type: "series", optionsKey: "series[]", chartTypes: ["flow-proportion"], identifier: "sankey" }, { type: "series", optionsKey: "series[]", chartTypes: ["standalone"], identifier: "pyramid" }, { type: "series", optionsKey: "series[]", chartTypes: ["gauge"], identifier: "linear-gauge" }, { type: "series", optionsKey: "series[]", chartTypes: ["gauge"], identifier: "radial-gauge" }, { type: "series-option", optionsKey: "errorBar", chartTypes: ["cartesian"], identifier: "error-bars" }, { type: "context", contextKey: "sharedToolbar", chartTypes: ["cartesian"] } ]; } }); // packages/ag-charts-community/src/chart/factory/legendRegistry.ts var LegendRegistry, legendRegistry; var init_legendRegistry = __esm({ "packages/ag-charts-community/src/chart/factory/legendRegistry.ts"() { "use strict"; LegendRegistry = class { constructor() { this.legendMap = /* @__PURE__ */ new Map(); this.themeTemplates = /* @__PURE__ */ new Map(); } register(legendType, { optionsKey, moduleFactory, themeTemplate }) { this.legendMap.set(legendType, { optionsKey, moduleFactory }); this.themeTemplates.set(optionsKey, themeTemplate); } create(legendType, moduleContext) { const legendFactory = this.legendMap.get(legendType)?.moduleFactory; if (legendFactory) { return legendFactory(moduleContext); } throw new Error(`AG Charts - unknown legend type: ${legendType}`); } getThemeTemplates() { return Object.fromEntries(this.themeTemplates); } getKeys() { return Array.from(this.legendMap.entries()).reduce( (result, [legendType, record]) => { result[legendType] = record.optionsKey; return result; }, {} ); } }; legendRegistry = new LegendRegistry(); } }); // packages/ag-charts-community/src/chart/factory/chartTypes.ts var ChartTypes, ChartDefaults, chartTypes2, publicChartTypes, chartDefaults; var init_chartTypes = __esm({ "packages/ag-charts-community/src/chart/factory/chartTypes.ts"() { "use strict"; init_object(); ChartTypes = class extends Map { get(seriesType) { return super.get(seriesType) ?? "unknown"; } isCartesian(seriesType) { return this.get(seriesType) === "cartesian"; } isPolar(seriesType) { return this.get(seriesType) === "polar"; } isHierarchy(seriesType) { return this.get(seriesType) === "hierarchy"; } isTopology(seriesType) { return this.get(seriesType) === "topology"; } isFlowProportion(seriesType) { return this.get(seriesType) === "flow-proportion"; } isStandalone(seriesType) { return this.get(seriesType) === "standalone"; } isGauge(seriesType) { return this.get(seriesType) === "gauge"; } get seriesTypes() { return Array.from(this.keys()); } get cartesianTypes() { return this.seriesTypes.filter((t) => this.isCartesian(t)); } get polarTypes() { return this.seriesTypes.filter((t) => this.isPolar(t)); } get hierarchyTypes() { return this.seriesTypes.filter((t) => this.isHierarchy(t)); } get topologyTypes() { return this.seriesTypes.filter((t) => this.isTopology(t)); } get flowProportionTypes() { return this.seriesTypes.filter((t) => this.isFlowProportion(t)); } get standaloneTypes() { return this.seriesTypes.filter((t) => this.isStandalone(t)); } get gaugeTypes() { return this.seriesTypes.filter((t) => this.isGauge(t)); } }; ChartDefaults = class extends Map { set(chartType, defaults) { return super.set(chartType, mergeDefaults(defaults, this.get(chartType))); } }; chartTypes2 = new ChartTypes(); publicChartTypes = new ChartTypes(); chartDefaults = new ChartDefaults(); } }); // packages/ag-charts-community/src/chart/factory/seriesRegistry.ts var SeriesRegistry, seriesRegistry; var init_seriesRegistry = __esm({ "packages/ag-charts-community/src/chart/factory/seriesRegistry.ts"() { "use strict"; init_json(); init_object(); init_chartTypes(); SeriesRegistry = class { constructor() { this.seriesMap = /* @__PURE__ */ new Map(); this.themeTemplates = /* @__PURE__ */ new Map(); } register(seriesType, { chartTypes: [chartType], moduleFactory, tooltipDefaults: tooltipDefaults2, defaultAxes, themeTemplate, paletteFactory, solo, stackable, groupable, stackedByDefault, hidden }) { this.setThemeTemplate(seriesType, themeTemplate); this.seriesMap.set(seriesType, { moduleFactory, tooltipDefaults: tooltipDefaults2, defaultAxes, paletteFactory, solo, stackable, groupable, stackedByDefault }); chartTypes2.set(seriesType, chartType); if (!hidden) { publicChartTypes.set(seriesType, chartType); } } create(seriesType, moduleContext) { const seriesFactory = this.seriesMap.get(seriesType)?.moduleFactory; if (seriesFactory) { return seriesFactory(moduleContext); } throw new Error(`AG Charts - unknown series type: ${seriesType}`); } cloneDefaultAxes(seriesType, options) { const defaultAxes = this.seriesMap.get(seriesType)?.defaultAxes; if (defaultAxes == null) return null; const axes = typeof defaultAxes === "function" ? defaultAxes(options) : defaultAxes; return { axes: deepClone(axes) }; } isDerivedDefaultAxes(seriesType) { return typeof this.seriesMap.get(seriesType)?.defaultAxes === "function"; } setThemeTemplate(seriesType, themeTemplate) { const currentTemplate = this.themeTemplates.get(seriesType); this.themeTemplates.set(seriesType, mergeDefaults(themeTemplate, currentTemplate)); } getThemeTemplate(seriesType) { return this.themeTemplates.get(seriesType); } getPaletteFactory(seriesType) { return this.seriesMap.get(seriesType)?.paletteFactory; } getTooltipDefauls(seriesType) { return this.seriesMap.get(seriesType)?.tooltipDefaults; } isSolo(seriesType) { return this.seriesMap.get(seriesType)?.solo ?? false; } isGroupable(seriesType) { return this.seriesMap.get(seriesType)?.groupable ?? false; } isStackable(seriesType) { return this.seriesMap.get(seriesType)?.stackable ?? false; } isStackedByDefault(seriesType) { return this.seriesMap.get(seriesType)?.stackedByDefault ?? false; } }; seriesRegistry = new SeriesRegistry(); } }); // packages/ag-charts-community/src/chart/interaction/syncManager.ts var _SyncManager, SyncManager; var init_syncManager = __esm({ "packages/ag-charts-community/src/chart/interaction/syncManager.ts"() { "use strict"; init_baseManager(); _SyncManager = class _SyncManager extends BaseManager { constructor(chart) { super(); this.chart = chart; } subscribe(groupId = _SyncManager.DEFAULT_GROUP) { let syncGroup = this.get(groupId); if (!syncGroup) { syncGroup = /* @__PURE__ */ new Set(); _SyncManager.chartsGroups.set(groupId, syncGroup); } syncGroup.add(this.chart); return this; } unsubscribe(groupId = _SyncManager.DEFAULT_GROUP) { this.get(groupId)?.delete(this.chart); return this; } getChart() { return this.chart; } getGroup(groupId = _SyncManager.DEFAULT_GROUP) { const syncGroup = this.get(groupId); return syncGroup ? Array.from(syncGroup) : []; } getGroupSiblings(groupId = _SyncManager.DEFAULT_GROUP) { return this.getGroup(groupId).filter((chart) => chart !== this.chart); } get(groupId) { return _SyncManager.chartsGroups.get(groupId); } }; _SyncManager.chartsGroups = /* @__PURE__ */ new Map(); _SyncManager.DEFAULT_GROUP = Symbol("sync-group-default"); SyncManager = _SyncManager; } }); // packages/ag-charts-community/src/chart/keyboard.ts var Keyboard; var init_keyboard = __esm({ "packages/ag-charts-community/src/chart/keyboard.ts"() { "use strict"; init_properties(); init_validation2(); Keyboard = class extends BaseProperties { constructor() { super(...arguments); this.enabled = false; } }; __decorateClass([ Validate(BOOLEAN) ], Keyboard.prototype, "enabled", 2); __decorateClass([ Validate(NUMBER) ], Keyboard.prototype, "tabIndex", 2); } }); // packages/ag-charts-community/src/chart/mapping/prepareAxis.ts function isAxisPosition(position) { return typeof position === "string" && CartesianAxisPositions.includes(position); } function guessInvalidPositions(axes) { const invalidAxes = []; const usedPositions = []; const guesses = [...CartesianAxisPositions]; for (const axis of axes) { if (axis instanceof CartesianAxis) { if (isAxisPosition(axis.position)) { usedPositions.push(axis.position); } else { invalidAxes.push(axis); } } } for (const axis of invalidAxes) { let nextGuess; do { nextGuess = guesses.pop(); } while (nextGuess && usedPositions.includes(nextGuess)); if (nextGuess == null) break; axis.position = nextGuess; } } var CartesianAxisPositions; var init_prepareAxis = __esm({ "packages/ag-charts-community/src/chart/mapping/prepareAxis.ts"() { "use strict"; init_cartesianAxis(); CartesianAxisPositions = ["top", "right", "bottom", "left"]; } }); // packages/ag-charts-community/src/chart/mapping/prepareSeries.ts function matchSeriesOptions(series, optSeries, oldOptsSeries) { const generateKey = (type, i, opts) => { const result = [type]; for (const key of MATCHING_KEYS) { if (key in i && i[key] != null) result.push(`${key}=${i[key]}`); } if (opts?.seriesGrouping) { result.push(`seriesGrouping.groupId=${opts?.seriesGrouping.groupId}`); } return result.join(";"); }; const seriesMap = /* @__PURE__ */ new Map(); let idx = 0; for (const s of series) { const key = generateKey(s.type, s.properties, oldOptsSeries?.[idx]); if (!seriesMap.has(key)) { seriesMap.set(key, []); } seriesMap.get(key)?.push([s, idx++]); } const optsMap = /* @__PURE__ */ new Map(); idx = 0; for (const o of optSeries) { const key = generateKey(o.type, o, o); if (!optsMap.has(key)) { optsMap.set(key, []); } optsMap.get(key)?.push([o, idx++]); } const overlap = [...seriesMap.keys()].some((k) => optsMap.has(k)); if (!overlap) { return { status: "no-overlap", oldKeys: seriesMap.keys(), newKeys: optsMap.keys() }; } const changes = []; for (const [key, optsTuples] of optsMap.entries()) { for (const [opts, targetIdx] of optsTuples) { const seriesArray = seriesMap.get(key); if (seriesArray == null || seriesArray.length < 1) { changes.push({ opts, targetIdx, idx: targetIdx, status: "add" }); seriesMap.delete(key); continue; } const [outputSeries, currentIdx] = seriesArray.shift(); const previousOpts = oldOptsSeries?.[currentIdx] ?? {}; const diff8 = jsonDiff(previousOpts, opts ?? {}); const { groupIndex, stackIndex } = diff8?.seriesGrouping ?? {}; if (groupIndex != null || stackIndex != null) { changes.push({ opts, series: outputSeries, diff: diff8, targetIdx, idx: currentIdx, status: "series-grouping" }); } else if (diff8) { changes.push({ opts, series: outputSeries, diff: diff8, targetIdx, idx: currentIdx, status: "update" }); } else { changes.push({ opts, series: outputSeries, targetIdx, idx: currentIdx, status: "no-op" }); } if (seriesArray.length === 0) { seriesMap.delete(key); } } } for (const seriesArray of seriesMap.values()) { for (const [outputSeries, currentIdx] of seriesArray) { changes.push({ series: outputSeries, idx: currentIdx, targetIdx: -1, status: "remove" }); } } return { status: "overlap", changes }; } var MATCHING_KEYS; var init_prepareSeries = __esm({ "packages/ag-charts-community/src/chart/mapping/prepareSeries.ts"() { "use strict"; init_json(); MATCHING_KEYS = ["direction", "xKey", "yKey", "sizeKey", "angleKey", "radiusKey", "normalizedTo"]; } }); // packages/ag-charts-community/src/chart/mapping/types.ts function optionsType(input) { const { series } = input; if (!series) return; return series[0]?.type ?? "line"; } function isAgCartesianChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isCartesian(specifiedType) || isEnterpriseCartesian(specifiedType); } function isAgPolarChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isPolar(specifiedType) || isEnterprisePolar(specifiedType); } function isAgHierarchyChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isHierarchy(specifiedType) || isEnterpriseHierarchy(specifiedType); } function isAgTopologyChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isTopology(specifiedType) || isEnterpriseTopology(specifiedType); } function isAgFlowProportionChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isFlowProportion(specifiedType) || isEnterpriseFlowProportion(specifiedType); } function isAgStandaloneChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isStandalone(specifiedType) || isEnterpriseStandalone(specifiedType); } function isAgGaugeChartOptions(input) { const specifiedType = optionsType(input); if (specifiedType == null) { return false; } return chartTypes2.isGauge(specifiedType) || isEnterpriseGauge(specifiedType); } function isAgPolarChartOptionsWithSeriesBasedLegend(input) { const specifiedType = optionsType(input); return isAgPolarChartOptions(input) && specifiedType !== "pie" && specifiedType !== "donut"; } function isSeriesOptionType(input) { if (input == null) { return false; } return chartTypes2.has(input); } function isAxisOptionType(input) { if (input == null) { return false; } return axisRegistry.has(input); } var init_types = __esm({ "packages/ag-charts-community/src/chart/mapping/types.ts"() { "use strict"; init_axisRegistry(); init_chartTypes(); init_expectedEnterpriseModules(); } }); // packages/ag-charts-community/src/chart/modulesManager.ts var ModulesManager; var init_modulesManager = __esm({ "packages/ag-charts-community/src/chart/modulesManager.ts"() { "use strict"; init_moduleMap(); init_properties(); ModulesManager = class extends ModuleMap { applyOptions(options) { for (const m of this.moduleMap.values()) { if (m.module.optionsKey in options && isProperties(m.moduleInstance)) { m.moduleInstance.set(options[m.module.optionsKey]); } } } *legends() { for (const { module: module2, moduleInstance } of this.moduleMap.values()) { if (module2.type !== "legend") continue; yield { legendType: module2.identifier, legend: moduleInstance }; } } }; } }); // packages/ag-charts-community/src/chart/overlay/overlay.ts var DEFAULT_OVERLAY_CLASS, DEFAULT_OVERLAY_DARK_CLASS, Overlay; var init_overlay = __esm({ "packages/ag-charts-community/src/chart/overlay/overlay.ts"() { "use strict"; init_core(); init_properties(); init_validation2(); DEFAULT_OVERLAY_CLASS = "ag-charts-overlay"; DEFAULT_OVERLAY_DARK_CLASS = "ag-charts-dark-overlay"; Overlay = class extends BaseProperties { constructor(className, defaultMessageId) { super(); this.className = className; this.defaultMessageId = defaultMessageId; this.enabled = true; } getText(localeManager) { return localeManager.t(this.text ?? this.defaultMessageId); } getElement(animationManager, localeManager, rect) { this.content?.remove(); this.focusBox = rect; if (this.renderer) { const htmlContent = this.renderer(); if (htmlContent instanceof HTMLElement) { this.content = htmlContent; } else { const tempDiv = createElement("div"); tempDiv.innerHTML = htmlContent; this.content = tempDiv.firstElementChild; } } else { const content = createElement("div", { display: "flex", alignItems: "center", justifyContent: "center", boxSizing: "border-box", height: "100%", margin: "8px", fontFamily: "var(--ag-charts-font-family)", fontSize: "var(--ag-charts-font-size)", fontWeight: "var(--ag-charts-font-weight)" }); content.innerText = this.getText(localeManager); this.content = content; animationManager?.animate({ from: 0, to: 1, id: "overlay", phase: "add", groupId: "opacity", onUpdate(value) { content.style.opacity = String(value); }, onStop() { content.style.opacity = "1"; } }); } return this.content; } removeElement(cleanup = () => this.content?.remove(), animationManager) { if (!this.content) return; if (animationManager) { const { content } = this; animationManager.animate({ from: 1, to: 0, phase: "remove", id: "overlay", groupId: "opacity", onUpdate(value) { content.style.opacity = String(value); }, onStop() { cleanup?.(); } }); } else { cleanup?.(); } this.content = void 0; this.focusBox = void 0; } }; __decorateClass([ Validate(BOOLEAN) ], Overlay.prototype, "enabled", 2); __decorateClass([ Validate(STRING, { optional: true }) ], Overlay.prototype, "text", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], Overlay.prototype, "renderer", 2); } }); // packages/ag-charts-community/src/chart/overlay/chartOverlays.ts var ChartOverlays; var init_chartOverlays = __esm({ "packages/ag-charts-community/src/chart/overlay/chartOverlays.ts"() { "use strict"; init_properties(); init_validation2(); init_overlay(); ChartOverlays = class extends BaseProperties { constructor() { super(...arguments); this.darkTheme = false; this.loading = new Overlay("ag-charts-loading-overlay", "overlayLoadingData"); this.noData = new Overlay("ag-charts-no-data-overlay", "overlayNoData"); this.noVisibleSeries = new Overlay("ag-charts-no-visible-series", "overlayNoVisibleSeries"); this.unsupportedBrowser = new Overlay("ag-charts-unsupported-browser", "overlayUnsupportedBrowser"); } getFocusInfo(localeManager) { for (const overlay of [this.loading, this.noData, this.noVisibleSeries, this.unsupportedBrowser]) { if (overlay.focusBox !== void 0) { return { text: overlay.getText(localeManager), rect: overlay.focusBox }; } } return void 0; } destroy() { this.loading.removeElement(); this.noData.removeElement(); this.noVisibleSeries.removeElement(); this.unsupportedBrowser.removeElement(); } }; __decorateClass([ Validate(BOOLEAN) ], ChartOverlays.prototype, "darkTheme", 2); __decorateClass([ Validate(OBJECT) ], ChartOverlays.prototype, "loading", 2); __decorateClass([ Validate(OBJECT) ], ChartOverlays.prototype, "noData", 2); __decorateClass([ Validate(OBJECT) ], ChartOverlays.prototype, "noVisibleSeries", 2); __decorateClass([ Validate(OBJECT) ], ChartOverlays.prototype, "unsupportedBrowser", 2); } }); // packages/ag-charts-community/src/chart/overlay/loadingSpinner.ts function getLoadingSpinner(text3, defaultDuration) { const { animationDuration } = PHASE_METADATA["add"]; const duration = animationDuration * defaultDuration; const container = createElement("div", `${DEFAULT_OVERLAY_CLASS}--loading`, { display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column", height: "100%", boxSizing: "border-box", font: "13px Verdana, sans-serif", // FONT_SIZE.MEDIUM userSelect: "none", animation: `ag-charts-loading ${duration}ms linear 50ms both` }); const matrix = createElement("span", { width: "45px", height: "40px", backgroundImage: [ "linear-gradient(#0000 calc(1 * 100% / 6), #ccc 0 calc(3 * 100% / 6), #0000 0), ", "linear-gradient(#0000 calc(2 * 100% / 6), #ccc 0 calc(4 * 100% / 6), #0000 0), ", "linear-gradient(#0000 calc(3 * 100% / 6), #ccc 0 calc(5 * 100% / 6), #0000 0)" ].join(""), backgroundSize: "10px 400%", backgroundRepeat: "no-repeat", animation: "ag-charts-loading-matrix 1s infinite linear" }); const label = createElement("p", { marginTop: "1em" }); label.innerText = text3; const background = createElement("div", `${DEFAULT_OVERLAY_CLASS}__loading-background`, { position: "absolute", inset: "0", opacity: "0.5", zIndex: "-1" }); const animationStyles = createElement("style"); animationStyles.innerText = [ "@keyframes ag-charts-loading { from { opacity: 0 } to { opacity: 1 } }", "@keyframes ag-charts-loading-matrix {", "0% { background-position: 0% 0%, 50% 0%, 100% 0%; }", "100% { background-position: 0% 100%, 50% 100%, 100% 100%; }", "}" ].join(" "); container.replaceChildren(animationStyles, matrix, label, background); return container; } var init_loadingSpinner = __esm({ "packages/ag-charts-community/src/chart/overlay/loadingSpinner.ts"() { "use strict"; init_core(); init_animation(); init_overlay(); } }); // packages/ag-charts-community/src/chart/series/seriesZIndexMap.ts var SeriesZIndexMap, SeriesContentZIndexMap; var init_seriesZIndexMap = __esm({ "packages/ag-charts-community/src/chart/series/seriesZIndexMap.ts"() { "use strict"; SeriesZIndexMap = /* @__PURE__ */ ((SeriesZIndexMap3) => { SeriesZIndexMap3[SeriesZIndexMap3["BACKGROUND"] = 0] = "BACKGROUND"; SeriesZIndexMap3[SeriesZIndexMap3["ANY_CONTENT"] = 1] = "ANY_CONTENT"; return SeriesZIndexMap3; })(SeriesZIndexMap || {}); SeriesContentZIndexMap = /* @__PURE__ */ ((SeriesContentZIndexMap2) => { SeriesContentZIndexMap2[SeriesContentZIndexMap2["FOREGROUND"] = 0] = "FOREGROUND"; SeriesContentZIndexMap2[SeriesContentZIndexMap2["HIGHLIGHT"] = 1] = "HIGHLIGHT"; SeriesContentZIndexMap2[SeriesContentZIndexMap2["LABEL"] = 2] = "LABEL"; return SeriesContentZIndexMap2; })(SeriesContentZIndexMap || {}); } }); // packages/ag-charts-community/src/chart/series/series.ts var SeriesNodePickMode, CROSS_FILTER_MARKER_FILL_OPACITY_FACTOR, CROSS_FILTER_MARKER_STROKE_OPACITY_FACTOR, SeriesNodeEvent, SeriesGroupingChangedEvent, Series; var init_series = __esm({ "packages/ag-charts-community/src/chart/series/series.ts"() { "use strict"; init_moduleMap(); init_bbox(); init_group(); init_format_util(); init_id(); init_json(); init_listeners(); init_lruCache(); init_nearest(); init_number(); init_object(); init_observable(); init_proxy(); SeriesNodePickMode = /* @__PURE__ */ ((SeriesNodePickMode19) => { SeriesNodePickMode19[SeriesNodePickMode19["EXACT_SHAPE_MATCH"] = 0] = "EXACT_SHAPE_MATCH"; SeriesNodePickMode19[SeriesNodePickMode19["NEAREST_NODE"] = 1] = "NEAREST_NODE"; SeriesNodePickMode19[SeriesNodePickMode19["AXIS_ALIGNED"] = 2] = "AXIS_ALIGNED"; return SeriesNodePickMode19; })(SeriesNodePickMode || {}); CROSS_FILTER_MARKER_FILL_OPACITY_FACTOR = 0.25; CROSS_FILTER_MARKER_STROKE_OPACITY_FACTOR = 0.125; SeriesNodeEvent = class { constructor(type, event, { datum }, series) { this.type = type; this.event = event; this.datum = datum; this.seriesId = series.id; } }; SeriesGroupingChangedEvent = class { constructor(series, seriesGrouping, oldGrouping) { this.series = series; this.seriesGrouping = seriesGrouping; this.oldGrouping = oldGrouping; this.type = "groupingChanged"; } }; Series = class extends Observable { constructor(seriesOpts) { super(); this.destroyFns = []; this.usesPlacedLabels = false; this.seriesGrouping = void 0; this.NodeEvent = SeriesNodeEvent; this.internalId = createId(this); // The group node that contains the series rendering in its default (non-highlighted) state. this.contentGroup = new TranslatableGroup({ name: `${this.internalId}-content`, zIndex: 1 /* ANY_CONTENT */ }); // The group node that contains all highlighted series items. This is a performance optimisation // for large-scale data-sets, where the only thing that routinely varies is the currently // highlighted node. this.highlightGroup = new TranslatableGroup({ name: `${this.internalId}-highlight`, zIndex: 1 /* ANY_CONTENT */ }); // Error bars etc. this.annotationGroup = new TranslatableGroup({ name: `${this.internalId}-annotation` }); // Lazily initialised labelGroup for label presentation. this.labelGroup = new TranslatableGroup({ name: `${this.internalId}-series-labels` }); this.axes = { ["x" /* X */]: void 0, ["y" /* Y */]: void 0 }; this.directions = ["x" /* X */, "y" /* Y */]; // Flag to determine if we should recalculate node data. this.nodeDataRefresh = true; this.moduleMap = new ModuleMap(); this.datumCallbackCache = /* @__PURE__ */ new Map(); this.connectsToYAxis = false; this._declarationOrder = -1; this.seriesListeners = new Listeners(); this._pickNodeCache = new LRUCache(); const { moduleCtx, pickModes, directionKeys = {}, directionNames = {}, canHaveAxes = false, usesPlacedLabels = false } = seriesOpts; this.ctx = moduleCtx; this.directionKeys = directionKeys; this.directionNames = directionNames; this.canHaveAxes = canHaveAxes; this.usesPlacedLabels = usesPlacedLabels; this.highlightGroup = new TranslatableGroup({ name: `${this.internalId}-highlight` }); this.highlightNode = this.highlightGroup.appendChild(new Group({ name: "highlightNode", zIndex: 0 })); this.highlightLabel = this.highlightGroup.appendChild(new Group({ name: "highlightLabel", zIndex: 10 })); this.pickModes = pickModes; } get pickModeAxis() { return "main"; } get id() { return this.properties?.id ?? this.internalId; } get type() { return this.constructor.type ?? ""; } get focusable() { return true; } get data() { return this._data ?? this._chartData; } set visible(newVisibility) { this.properties.visible = newVisibility; this.ctx.legendManager.toggleItem({ enabled: newVisibility, seriesId: this.id }); this.ctx.legendManager.update(); this.visibleMaybeChanged(); } get visible() { return this.ctx.legendManager.getSeriesEnabled(this.id) ?? this.properties.visible; } get hasData() { return this.data != null && this.data.length > 0; } get tooltipEnabled() { return this.properties.tooltip?.enabled ?? false; } onDataChange() { this.nodeDataRefresh = true; this._pickNodeCache.clear(); } setOptionsData(input) { this._data = input; this.onDataChange(); } setChartData(input) { this._chartData = input; if (this.data === input) { this.onDataChange(); } } onSeriesGroupingChange(prev, next) { const { internalId, type, visible } = this; if (prev) { this.ctx.seriesStateManager.deregisterSeries(this); } if (next) { this.ctx.seriesStateManager.registerSeries({ internalId, type, visible, seriesGrouping: next }); } this.fireEvent(new SeriesGroupingChangedEvent(this, next, prev)); } getBandScalePadding() { return { inner: 1, outer: 0 }; } attachSeries(seriesContentNode, seriesNode, annotationNode) { seriesContentNode.appendChild(this.contentGroup); seriesNode.appendChild(this.highlightGroup); seriesNode.appendChild(this.labelGroup); annotationNode?.appendChild(this.annotationGroup); } detachSeries(seriesContentNode, seriesNode, annotationNode) { seriesContentNode?.removeChild(this.contentGroup); seriesNode.removeChild(this.highlightGroup); seriesNode.removeChild(this.labelGroup); annotationNode?.removeChild(this.annotationGroup); } setSeriesIndex(index) { if (index === this._declarationOrder) return false; this._declarationOrder = index; this.contentGroup.zIndex = [1 /* ANY_CONTENT */, index, 0 /* FOREGROUND */]; this.highlightGroup.zIndex = [1 /* ANY_CONTENT */, index, 1 /* HIGHLIGHT */]; this.labelGroup.zIndex = [1 /* ANY_CONTENT */, index, 2 /* LABEL */]; this.annotationGroup.zIndex = index; return true; } renderToOffscreenCanvas() { return false; } addEventListener(type, listener) { return super.addEventListener(type, listener); } addListener(type, listener) { return this.seriesListeners.addListener(type, listener); } dispatch(type, event) { this.seriesListeners.dispatch(type, event); } addChartEventListeners() { return; } destroy() { this.destroyFns.forEach((f) => f()); this.destroyFns = []; this.resetDatumCallbackCache(); this.ctx.seriesStateManager.deregisterSeries(this); } getDirectionValues(direction, properties) { const resolvedDirection = this.resolveKeyDirection(direction); const keys = properties?.[resolvedDirection]; const values = []; if (!keys) { return values; } const addValues = (...items) => { for (const value of items) { if (Array.isArray(value)) { addValues(...value); } else if (typeof value === "object") { addValues(...Object.values(value)); } else { values.push(value); } } }; addValues(...keys.map((key) => this.properties[key])); return values; } getKeys(direction) { return this.getDirectionValues(direction, this.directionKeys); } getKeyProperties(direction) { return this.directionKeys[this.resolveKeyDirection(direction)] ?? []; } getNames(direction) { return this.getDirectionValues(direction, this.directionNames); } resolveKeyDirection(direction) { return direction; } // The union of the series domain ('community') and series-option domains ('enterprise'). getDomain(direction) { const seriesDomain = this.getSeriesDomain(direction); const moduleDomains = this.moduleMap.mapModules((module2) => module2.getDomain(direction)).flat(); return moduleDomains.length !== 0 ? seriesDomain.concat(moduleDomains) : seriesDomain; } getRange(direction, visibleRange) { return this.getSeriesRange(direction, visibleRange); } getVisibleItems(_xVisibleRange, _yVisibleRange, _minVisibleItems) { return Infinity; } getGradientFillOptions({ bounds }, defaultColorRange) { const { axes } = this; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; const xRange = xAxis?.range ?? [0, 1]; const yRange = yAxis?.range ?? [0, 1]; const [x1, x2] = findMinMax(xRange); const [y1, y2] = findMinMax(yRange); const width2 = x2 - x1; const height2 = y2 - y1; let domain = [0, 1]; if (bounds === "series") { domain = this.getSeriesDomain("y" /* Y */); } else if (bounds === "axes") { domain = yAxis?.scale.domain ?? [0, 1]; } return { bbox: new BBox(x1, y1, width2, height2), domain, defaultColorRange }; } // Indicate that something external changed and we should recalculate nodeData. markNodeDataDirty() { this.nodeDataRefresh = true; this._pickNodeCache.clear(); this.visibleMaybeChanged(); } visibleMaybeChanged() { this.ctx.seriesStateManager.updateSeries(this); } getOpacity() { const defaultOpacity = 1; const { dimOpacity = 1, enabled = true } = this.properties.highlightStyle.series; if (!enabled || dimOpacity === defaultOpacity) { return defaultOpacity; } switch (this.isItemIdHighlighted()) { case 0 /* None */: case 1 /* This */: return defaultOpacity; case 2 /* Other */: default: return dimOpacity; } } getStrokeWidth(defaultStrokeWidth) { const { strokeWidth, enabled = true } = this.properties.highlightStyle.series; if (!enabled || strokeWidth === void 0) { return defaultStrokeWidth; } switch (this.isItemIdHighlighted()) { case 1 /* This */: return strokeWidth; case 0 /* None */: case 2 /* Other */: return defaultStrokeWidth; } } isItemIdHighlighted() { const series = this.ctx.highlightManager?.getActiveHighlight()?.series; if (series == null) { return 0 /* None */; } if (series !== this) { return 2 /* Other */; } return 1 /* This */; } getModuleTooltipParams() { return this.moduleMap.mapModules((module2) => module2.getTooltipParams()).reduce((total, current) => Object.assign(total, current), {}); } pickNode(point, intent, exactMatchOnly = false) { const { pickModes, pickModeAxis, visible, contentGroup } = this; if (!visible || !contentGroup.visible) return; if (intent === "highlight" && !this.properties.highlight.enabled) return; if (intent === "highlight-tooltip" && !this.properties.highlight.enabled) return; let maxDistance = Infinity; if (intent === "tooltip" || intent === "highlight-tooltip") { const { tooltip } = this.properties; maxDistance = typeof tooltip.range === "number" ? tooltip.range : Infinity; exactMatchOnly || (exactMatchOnly = tooltip.range === "exact"); } else if (intent === "event" || intent === "context-menu") { const { nodeClickRange } = this.properties; maxDistance = typeof nodeClickRange === "number" ? nodeClickRange : Infinity; exactMatchOnly || (exactMatchOnly = nodeClickRange === "exact"); } const selectedPickModes = pickModes.filter( (m) => !exactMatchOnly || m === 0 /* EXACT_SHAPE_MATCH */ ); const { x, y } = point; const key = JSON.stringify({ x, y, maxDistance, selectedPickModes }); if (this._pickNodeCache.has(key)) { return this._pickNodeCache.get(key); } for (const pickMode of selectedPickModes) { let match; switch (pickMode) { case 0 /* EXACT_SHAPE_MATCH */: match = this.pickNodeExactShape(point); break; case 1 /* NEAREST_NODE */: match = this.pickNodeClosestDatum(point); break; case 2 /* AXIS_ALIGNED */: match = pickModeAxis != null ? this.pickNodeMainAxisFirst(point, pickModeAxis === "main-category") : void 0; break; } if (match && match.distance <= maxDistance) { return this._pickNodeCache.set(key, { pickMode, match: match.datum, distance: match.distance }); } } return this._pickNodeCache.set(key, void 0); } pickNodeExactShape(point) { const match = this.contentGroup.pickNode(point.x, point.y); if (match && match.datum.missing !== true) { return { datum: match.datum, distance: 0 }; } return void 0; } pickNodeClosestDatum(_point) { throw new Error("AG Charts - Series.pickNodeClosestDatum() not implemented"); } pickNodeNearestDistantObject(point, items) { const match = nearestSquared(point.x, point.y, items); if (match.nearest !== void 0 && match.nearest.datum.missing !== true) { return { datum: match.nearest.datum, distance: Math.sqrt(match.distanceSquared) }; } return void 0; } pickNodeMainAxisFirst(_point, _requireCategoryAxis) { throw new Error("AG Charts - Series.pickNodeMainAxisFirst() not implemented"); } getLabelData() { return []; } updatePlacedLabelData(_labels) { return; } fireNodeClickEvent(event, datum) { this.fireEvent(new this.NodeEvent("nodeClick", event, datum, this)); } fireNodeDoubleClickEvent(event, datum) { this.fireEvent(new this.NodeEvent("nodeDoubleClick", event, datum, this)); } createNodeContextMenuActionEvent(event, datum) { return new this.NodeEvent("nodeContextMenuAction", event, datum, this); } onLegendInitialState(legendType, initialState) { const { visible = true, itemId, legendItemName } = initialState ?? {}; this.toggleSeriesItem(visible, legendType, itemId, legendItemName); } onLegendItemClick(event) { const { enabled, itemId, series, legendType } = event; const legendItemName = "legendItemName" in this.properties ? this.properties.legendItemName : void 0; const legendItemKey = "legendItemKey" in this.properties ? this.properties.legendItemKey : void 0; const matchedLegendItemName = legendItemName != void 0 && legendItemName === event.legendItemName; if (series.id === this.id || matchedLegendItemName || legendItemKey != void 0) { this.toggleSeriesItem(enabled, legendType, itemId, legendItemName, event); } } onLegendItemDoubleClick(event) { const { enabled, itemId, series, numVisibleItems, legendType } = event; const legendItemName = "legendItemName" in this.properties ? this.properties.legendItemName : void 0; const legendItemKey = "legendItemKey" in this.properties ? this.properties.legendItemKey : void 0; const matchedLegendItemName = legendItemName != void 0 && legendItemName === event.legendItemName; if (series.id === this.id || matchedLegendItemName || legendItemKey != void 0) { this.toggleSeriesItem(true, legendType, itemId, legendItemName, event); } else if (enabled && numVisibleItems === 1) { this.toggleSeriesItem(true, legendType, void 0, legendItemName); } else { this.toggleSeriesItem(false, legendType, void 0, legendItemName); } } toggleSeriesItem(enabled, legendType, itemId, legendItemName, legendEvent) { const seriesId = this.id; if (enabled || legendType !== "category") { this.visible = enabled; } this.nodeDataRefresh = true; this._pickNodeCache.clear(); const event = { type: "seriesVisibilityChange", seriesId, itemId, legendItemName: legendEvent?.legendItemName ?? legendItemName, visible: enabled }; this.fireEvent(event); this.ctx.legendManager.toggleItem({ enabled, seriesId, itemId, legendItemName }); } isEnabled() { return this.visible; } getModuleMap() { return this.moduleMap; } createModuleContext() { return { ...this.ctx, series: this }; } getLabelText(label, params, defaultFormatter = formatValue) { if (label.formatter) { return this.ctx.callbackCache.call(label.formatter, { seriesId: this.id, ...params }) ?? defaultFormatter(params.value); } return defaultFormatter(params.value); } getMarkerStyle(marker, params, defaultStyle = marker.getStyle()) { const defaultSize = { size: params.datum.point?.size ?? 0 }; const markerStyle = mergeDefaults(defaultSize, defaultStyle); if (marker.itemStyler) { const style = this.ctx.callbackCache.call(marker.itemStyler, { seriesId: this.id, ...markerStyle, ...params, datum: params.datum.datum }); return mergeDefaults(style, markerStyle); } return markerStyle; } updateMarkerStyle(markerNode, marker, params, defaultStyle = marker.getStyle(), { applyTranslation = true, selected = true } = {}) { const { point } = params.datum; const activeStyle = this.getMarkerStyle(marker, params, defaultStyle); const visible = this.visible && activeStyle.size > 0 && point && !isNaN(point.x) && !isNaN(point.y); if (applyTranslation) { markerNode.setProperties({ visible, ...activeStyle, translationX: point?.x, translationY: point?.y }); } else { markerNode.setProperties({ visible, ...activeStyle }); } if (!selected) { markerNode.fillOpacity *= CROSS_FILTER_MARKER_FILL_OPACITY_FACTOR; markerNode.strokeOpacity *= CROSS_FILTER_MARKER_STROKE_OPACITY_FACTOR; } if (typeof marker.shape === "function" && !markerNode.dirtyPath) { markerNode.path.clear(true); markerNode.updatePath(); markerNode.checkPathDirty(); const bb = markerNode.getBBox(); if (point !== void 0 && bb.isFinite()) { const center2 = bb.computeCenter(); const [dx2, dy2] = ["x", "y"].map( (key) => (activeStyle.strokeWidth ?? 0) + Math.abs(center2[key] - point[key]) ); point.focusSize = Math.max(bb.width + dx2, bb.height + dy2); } } } get nodeDataDependencies() { return this._nodeDataDependencies ?? { seriesRectWidth: NaN, seriesRectHeight: NaN }; } checkResize(newSeriesRect) { const { width: seriesRectWidth, height: seriesRectHeight } = newSeriesRect ?? { width: NaN, height: NaN }; const newNodeDataDependencies = newSeriesRect ? { seriesRectWidth, seriesRectHeight } : void 0; const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null; if (resize) { this._nodeDataDependencies = newNodeDataDependencies; this.markNodeDataDirty(); } return resize; } pickFocus(_opts) { return void 0; } resetDatumCallbackCache() { this.datumCallbackCache.clear(); } cachedDatumCallback(id, fn) { const { datumCallbackCache } = this; const existing = datumCallbackCache.get(id); if (existing != null) return existing; const value = fn(); datumCallbackCache.set(id, value); return value; } }; __decorateClass([ ActionOnSet({ changeValue: function(newVal, oldVal) { this.onSeriesGroupingChange(oldVal, newVal); } }) ], Series.prototype, "seriesGrouping", 2); } }); // packages/ag-charts-community/src/scene/polyRoots.ts function linearRoot(a, b) { const t = -b / a; return a !== 0 && t >= 0 && t <= 1 ? [t] : []; } function quadraticRoots(a, b, c) { if (a === 0) { return linearRoot(b, c); } const D = b * b - 4 * a * c; const roots = []; if (D === 0) { const t = -b / (2 * a); if (t >= 0 && t <= 1) { roots.push(t); } } else if (D > 0) { const rD = Math.sqrt(D); const t1 = (-b - rD) / (2 * a); const t2 = (-b + rD) / (2 * a); if (t1 >= 0 && t1 <= 1) { roots.push(t1); } if (t2 >= 0 && t2 <= 1) { roots.push(t2); } } return roots; } function cubicRoots(a, b, c, d) { if (a === 0) { return quadraticRoots(b, c, d); } const A = b / a; const B = c / a; const C2 = d / a; const Q = (3 * B - A * A) / 9; const R = (9 * A * B - 27 * C2 - 2 * A * A * A) / 54; const D = Q * Q * Q + R * R; const third = 1 / 3; const roots = []; if (D >= 0) { const rD = Math.sqrt(D); const S = Math.sign(R + rD) * Math.pow(Math.abs(R + rD), third); const T = Math.sign(R - rD) * Math.pow(Math.abs(R - rD), third); const Im = Math.abs(Math.sqrt(3) * (S - T) / 2); const t = -third * A + (S + T); if (t >= 0 && t <= 1) { roots.push(t); } if (Im === 0) { const t2 = -third * A - (S + T) / 2; if (t2 >= 0 && t2 <= 1) { roots.push(t2); } } } else { const theta = Math.acos(R / Math.sqrt(-Q * Q * Q)); const thirdA = third * A; const twoSqrtQ = 2 * Math.sqrt(-Q); const t1 = twoSqrtQ * Math.cos(third * theta) - thirdA; const t2 = twoSqrtQ * Math.cos(third * (theta + 2 * Math.PI)) - thirdA; const t3 = twoSqrtQ * Math.cos(third * (theta + 4 * Math.PI)) - thirdA; if (t1 >= 0 && t1 <= 1) { roots.push(t1); } if (t2 >= 0 && t2 <= 1) { roots.push(t2); } if (t3 >= 0 && t3 <= 1) { roots.push(t3); } } return roots; } var init_polyRoots = __esm({ "packages/ag-charts-community/src/scene/polyRoots.ts"() { "use strict"; } }); // packages/ag-charts-community/src/scene/intersection.ts function segmentIntersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) { const d = (ax2 - ax1) * (by2 - by1) - (ay2 - ay1) * (bx2 - bx1); if (d === 0) { return 0; } const ua = ((bx2 - bx1) * (ay1 - by1) - (ax1 - bx1) * (by2 - by1)) / d; const ub = ((ax2 - ax1) * (ay1 - by1) - (ay2 - ay1) * (ax1 - bx1)) / d; if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) { return 1; } return 0; } function cubicSegmentIntersections(px1, py1, px2, py2, px3, py3, px4, py4, x1, y1, x2, y2) { let intersections = 0; const A = y1 - y2; const B = x2 - x1; const C2 = x1 * (y2 - y1) - y1 * (x2 - x1); const bx = bezierCoefficients(px1, px2, px3, px4); const by = bezierCoefficients(py1, py2, py3, py4); const a = A * bx[0] + B * by[0]; const b = A * bx[1] + B * by[1]; const c = A * bx[2] + B * by[2]; const d = A * bx[3] + B * by[3] + C2; const roots = cubicRoots(a, b, c, d); for (const t of roots) { const tt = t * t; const ttt = t * tt; const x = bx[0] * ttt + bx[1] * tt + bx[2] * t + bx[3]; const y = by[0] * ttt + by[1] * tt + by[2] * t + by[3]; let s; if (x1 === x2) { s = (y - y1) / (y2 - y1); } else { s = (x - x1) / (x2 - x1); } if (s >= 0 && s <= 1) { intersections++; } } return intersections; } function bezierCoefficients(P1, P2, P3, P4) { return [ // Bézier expressed as matrix operations: -P1 + 3 * P2 - 3 * P3 + P4, // |-1 3 -3 1| |P1| 3 * P1 - 6 * P2 + 3 * P3, // [t^3 t^2 t 1] | 3 -6 3 0| |P2| -3 * P1 + 3 * P2, // |-3 3 0 0| |P3| P1 // | 1 0 0 0| |P4| ]; } function arcIntersections(cx, cy, r, startAngle, endAngle, counterClockwise, x1, y1, x2, y2) { if (isNaN(cx) || isNaN(cy)) { return 0; } if (counterClockwise) { [endAngle, startAngle] = [startAngle, endAngle]; } const k = (y2 - y1) / (x2 - x1); const y0 = y1 - k * x1; const a = Math.pow(k, 2) + 1; const b = 2 * (k * (y0 - cy) - cx); const c = Math.pow(cx, 2) + Math.pow(y0 - cy, 2) - Math.pow(r, 2); const d = Math.pow(b, 2) - 4 * a * c; if (d < 0) { return 0; } const i1x = (-b + Math.sqrt(d)) / 2 / a; const i2x = (-b - Math.sqrt(d)) / 2 / a; let intersections = 0; [i1x, i2x].forEach((x) => { const isXInsideLine = x >= Math.min(x1, x2) && x <= Math.max(x1, x2); if (!isXInsideLine) { return; } const y = k * x + y0; const adjacent = x - cx; const opposite = y - cy; const angle2 = Math.atan2(opposite, adjacent); if (isBetweenAngles(angle2, startAngle, endAngle)) { intersections++; } }); return intersections; } var init_intersection = __esm({ "packages/ag-charts-community/src/scene/intersection.ts"() { "use strict"; init_angle(); init_polyRoots(); } }); // packages/ag-charts-community/src/scene/util/bezier.ts function evaluateBezier(p0, p1, p2, p3, t) { return (1 - t) ** 3 * p0 + 3 * (1 - t) ** 2 * t * p1 + 3 * (1 - t) * t ** 2 * p2 + t ** 3 * p3; } function solveBezier(p0, p1, p2, p3, value) { if (value <= Math.min(p0, p3)) { return p0 < p3 ? 0 : 1; } else if (value >= Math.max(p0, p3)) { return p0 < p3 ? 1 : 0; } let t0 = 0; let t1 = 1; let t = NaN; for (let i = 0; i < 12; i += 1) { t = (t0 + t1) / 2; const curveValue = evaluateBezier(p0, p1, p2, p3, t); if (curveValue < value) { t0 = t; } else { t1 = t; } } return t; } function splitBezier(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, t) { const x01 = (1 - t) * p0x + t * p1x; const y01 = (1 - t) * p0y + t * p1y; const x12 = (1 - t) * p1x + t * p2x; const y12 = (1 - t) * p1y + t * p2y; const x23 = (1 - t) * p2x + t * p3x; const y23 = (1 - t) * p2y + t * p3y; const x012 = (1 - t) * x01 + t * x12; const y012 = (1 - t) * y01 + t * y12; const x123 = (1 - t) * x12 + t * x23; const y123 = (1 - t) * y12 + t * y23; const x0123 = (1 - t) * x012 + t * x123; const y0123 = (1 - t) * y012 + t * y123; return [ [ { x: p0x, y: p0y }, { x: x01, y: y01 }, { x: x012, y: y012 }, { x: x0123, y: y0123 } ], [ { x: x0123, y: y0123 }, { x: x123, y: y123 }, { x: x23, y: y23 }, { x: p3x, y: p3y } ] ]; } function calculateDerivativeExtrema(p0, p1, p2, p3) { const a = -p0 + 3 * p1 - 3 * p2 + p3; const b = 3 * p0 - 6 * p1 + 3 * p2; const c = -3 * p0 + 3 * p1; if (a === 0) { if (b !== 0) { const t = -c / b; if (t > 0 && t < 1) { return [t]; } } return []; } const discriminant = b * b - 4 * a * c; if (discriminant >= 0) { const sqrtDiscriminant = Math.sqrt(discriminant); const t1 = (-b + sqrtDiscriminant) / (2 * a); const t2 = (-b - sqrtDiscriminant) / (2 * a); return [t1, t2].filter((t) => t > 0 && t < 1); } return []; } function calculateDerivativeExtremaXY(sx, sy, cp1x, cp1y, cp2x, cp2y, x, y) { const tx = calculateDerivativeExtrema(sx, cp1x, cp2x, x); const ty = calculateDerivativeExtrema(sy, cp1y, cp2y, y); return [...tx, ...ty]; } var init_bezier = __esm({ "packages/ag-charts-community/src/scene/util/bezier.ts"() { "use strict"; } }); // packages/ag-charts-community/src/scene/extendedPath2D.ts var ExtendedPath2D; var init_extendedPath2D = __esm({ "packages/ag-charts-community/src/scene/extendedPath2D.ts"() { "use strict"; init_main(); init_angle(); init_distance(); init_bbox(); init_intersection(); init_bezier(); ExtendedPath2D = class { constructor() { // The methods of this class will likely be called many times per animation frame, // and any allocation can trigger a GC cycle during animation, so we attempt // to minimize the number of allocations. this.path2d = new Path2D(); this.previousCommands = []; this.previousParams = []; this.previousClosedPath = false; this.commands = []; this.params = []; this.openedPath = false; this.closedPath = false; } isEmpty() { return this.commands.length === 0; } isDirty() { return this.closedPath !== this.previousClosedPath || this.previousCommands.length !== this.commands.length || this.previousParams.length !== this.params.length || this.previousCommands.toString() !== this.commands.toString() || this.previousParams.toString() !== this.params.toString(); } getPath2D() { return this.path2d; } moveTo(x, y) { this.openedPath = true; this.path2d.moveTo(x, y); this.commands.push(0 /* Move */); this.params.push(x, y); } lineTo(x, y) { if (this.openedPath) { this.path2d.lineTo(x, y); this.commands.push(1 /* Line */); this.params.push(x, y); } else { this.moveTo(x, y); } } rect(x, y, width2, height2) { this.moveTo(x, y); this.lineTo(x + width2, y); this.lineTo(x + width2, y + height2); this.lineTo(x, y + height2); this.closePath(); } roundRect(x, y, width2, height2, radii) { radii = Math.min(radii, width2 / 2, height2 / 2); this.moveTo(x, y + radii); this.arc(x + radii, y + radii, radii, Math.PI, 1.5 * Math.PI); this.lineTo(x + radii, y); this.lineTo(x + width2 - radii, y); this.arc(x + width2 - radii, y + radii, radii, 1.5 * Math.PI, 2 * Math.PI); this.lineTo(x + width2, y + radii); this.lineTo(x + width2, y + height2 - radii); this.arc(x + width2 - radii, y + height2 - radii, radii, 0, Math.PI / 2); this.lineTo(x + width2 - radii, y + height2); this.lineTo(x + radii, y + height2); this.arc(x + +radii, y + height2 - radii, radii, Math.PI / 2, Math.PI); this.lineTo(x, y + height2 - radii); this.closePath(); } arc(x, y, r, sAngle, eAngle, counterClockwise) { this.openedPath = true; this.path2d.arc(x, y, r, sAngle, eAngle, counterClockwise); this.commands.push(2 /* Arc */); this.params.push(x, y, r, sAngle, eAngle, counterClockwise ? 1 : 0); } cubicCurveTo(cx1, cy1, cx2, cy2, x, y) { if (!this.openedPath) { this.moveTo(cx1, cy1); } this.path2d.bezierCurveTo(cx1, cy1, cx2, cy2, x, y); this.commands.push(3 /* Curve */); this.params.push(cx1, cy1, cx2, cy2, x, y); } closePath() { if (this.openedPath) { this.path2d.closePath(); this.commands.push(4 /* ClosePath */); this.openedPath = false; this.closedPath = true; } } clear(trackChanges) { if (trackChanges) { this.previousCommands = this.commands; this.previousParams = this.params; this.previousClosedPath = this.closedPath; } this.path2d = new Path2D(); this.openedPath = false; this.closedPath = false; this.commands = []; this.params = []; } isPointInPath(x, y) { const commands = this.commands; const params = this.params; const cn = commands.length; const ox = -1e4; const oy = -1e4; let sx = NaN; let sy = NaN; let px = 0; let py = 0; let intersectionCount = 0; for (let ci = 0, pi = 0; ci < cn; ci++) { switch (commands[ci]) { case 0 /* Move */: intersectionCount += segmentIntersection(sx, sy, px, py, ox, oy, x, y); px = params[pi++]; sx = px; py = params[pi++]; sy = py; break; case 1 /* Line */: intersectionCount += segmentIntersection(px, py, params[pi++], params[pi++], ox, oy, x, y); px = params[pi - 2]; py = params[pi - 1]; break; case 3 /* Curve */: intersectionCount += cubicSegmentIntersections( px, py, params[pi++], params[pi++], params[pi++], params[pi++], params[pi++], params[pi++], ox, oy, x, y ); px = params[pi - 2]; py = params[pi - 1]; break; case 2 /* Arc */: { const cx = params[pi++]; const cy = params[pi++]; const r = params[pi++]; const startAngle = params[pi++]; const endAngle = params[pi++]; const counterClockwise = Boolean(params[pi++]); intersectionCount += arcIntersections( cx, cy, r, startAngle, endAngle, counterClockwise, ox, oy, x, y ); if (!isNaN(sx)) { const startX = cx + Math.cos(startAngle) * r; const startY = cy + Math.sin(startAngle) * r; intersectionCount += segmentIntersection(px, py, startX, startY, ox, oy, x, y); } px = cx + Math.cos(endAngle) * r; py = cy + Math.sin(endAngle) * r; break; } case 4 /* ClosePath */: intersectionCount += segmentIntersection(sx, sy, px, py, ox, oy, x, y); break; } } return intersectionCount % 2 === 1; } distanceSquared(x, y) { let best = Infinity; const commands = this.commands; const params = this.params; const cn = commands.length; let sx = NaN; let sy = NaN; let px = 0; let py = 0; for (let ci = 0, pi = 0; ci < cn; ci++) { switch (commands[ci]) { case 0 /* Move */: px = sx = params[pi++]; py = sy = params[pi++]; break; case 1 /* Line */: { const nx = params[pi++]; const ny = params[pi++]; best = lineDistanceSquared(x, y, px, py, nx, ny, best); break; } case 3 /* Curve */: logger_exports.error("Command.Curve distanceSquare not implemented"); break; case 2 /* Arc */: { const cx = params[pi++]; const cy = params[pi++]; const r = params[pi++]; const startAngle = params[pi++]; const endAngle = params[pi++]; const startX = cx + Math.cos(startAngle) * r; const startY = cy + Math.sin(startAngle) * r; const counterClockwise = Boolean(params[pi++]); best = lineDistanceSquared(x, y, px, py, startX, startY, best); best = arcDistanceSquared(x, y, cx, cy, r, startAngle, endAngle, counterClockwise, best); px = cx + Math.cos(endAngle) * r; py = cy + Math.sin(endAngle) * r; break; } case 4 /* ClosePath */: best = lineDistanceSquared(x, y, px, py, sx, sy, best); break; } } return best; } // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d toSVG(transform = (x, y) => ({ x, y })) { const buffer = []; const { commands, params } = this; const addCommand = (command, ...points) => { buffer.push(command); for (let i = 0; i < points.length; i += 2) { const { x, y } = transform(points[i], points[i + 1]); buffer.push(x, y); } }; let pi = 0; for (const command of commands) { switch (command) { case 0 /* Move */: addCommand("M", params[pi++], params[pi++]); break; case 1 /* Line */: addCommand("L", params[pi++], params[pi++]); break; case 3 /* Curve */: addCommand("C", params[pi++], params[pi++], params[pi++], params[pi++], params[pi++], params[pi++]); break; case 2 /* Arc */: { const cx = params[pi++]; const cy = params[pi++]; const r = params[pi++]; const A0 = params[pi++]; const A1 = params[pi++]; const ccw = params[pi++]; let sweep = ccw ? A0 - A1 : A1 - A0; if (sweep < 0) { sweep += Math.ceil(-sweep / (2 * Math.PI)) * 2 * Math.PI; } if (ccw) { sweep = -sweep; } const arcSections = Math.max(Math.ceil(Math.abs(sweep) / (Math.PI / 2)), 1); const step = sweep / arcSections; const h = 4 / 3 * Math.tan(step / 4); const move = buffer.length === 0 ? "M" : "L"; addCommand(move, cx + Math.cos(A0) * r, cy + Math.sin(A0) * r); for (let i = 0; i < arcSections; i += 1) { const a0 = A0 + step * (i + 0); const a1 = A0 + step * (i + 1); const rSinStart = r * Math.sin(a0); const rCosStart = r * Math.cos(a0); const rSinEnd = r * Math.sin(a1); const rCosEnd = r * Math.cos(a1); addCommand( "C", cx + rCosStart - h * rSinStart, cy + rSinStart + h * rCosStart, cx + rCosEnd + h * rSinEnd, cy + rSinEnd - h * rCosEnd, cx + rCosEnd, cy + rSinEnd ); } break; } case 4 /* ClosePath */: buffer.push("Z"); break; } } return buffer.join(" "); } computeBBox() { const { commands, params } = this; let [top, left, right, bot] = [Infinity, Infinity, -Infinity, -Infinity]; let [sx, sy] = [NaN, NaN]; let [mx, my] = [NaN, NaN]; const joinPoint = (x, y, updatestart) => { top = Math.min(y, top); left = Math.min(x, left); right = Math.max(x, right); bot = Math.max(y, bot); if (updatestart) { [sx, sy] = [x, y]; } }; let pi = 0; for (const command of commands) { switch (command) { case 0 /* Move */: joinPoint(params[pi++], params[pi++], true); [mx, my] = [sx, sy]; break; case 1 /* Line */: joinPoint(params[pi++], params[pi++], true); break; case 3 /* Curve */: { const cp1x = params[pi++]; const cp1y = params[pi++]; const cp2x = params[pi++]; const cp2y = params[pi++]; const x = params[pi++]; const y = params[pi++]; joinPoint(x, y, true); const Ts = calculateDerivativeExtremaXY(sx, sy, cp1x, cp1y, cp2x, cp2y, x, y); Ts.forEach((t) => { const px = evaluateBezier(sx, cp1x, cp2x, x, t); const py = evaluateBezier(sy, cp1y, cp2y, y, t); joinPoint(px, py); }); break; } case 2 /* Arc */: { const cx = params[pi++]; const cy = params[pi++]; const r = params[pi++]; let A0 = normalizeAngle360(params[pi++]); let A1 = normalizeAngle360(params[pi++]); const ccw = params[pi++]; if (ccw) { [A0, A1] = [A1, A0]; } const joinAngle = (angle2, updatestart) => { const px = cx + r * Math.cos(angle2); const py = cy + r * Math.sin(angle2); joinPoint(px, py, updatestart); }; joinAngle(A0); joinAngle(A1, true); const criticalAngles = [0, Math.PI / 2, Math.PI, 3 * Math.PI / 2]; for (const crit of criticalAngles) { if (A0 < A1 && A0 <= crit && crit <= A1 || A0 > A1 && (A0 <= crit || crit <= A1)) { joinAngle(crit); } } break; } case 4 /* ClosePath */: [sx, sy] = [mx, my]; break; } } return new BBox(left, top, right - left, bot - top); } }; } }); // packages/ag-charts-community/src/scene/shape/path.ts function ScenePathChangeDetection(opts) { const { changeCb, convertor } = opts ?? {}; return SceneChangeDetection({ type: "path", convertor, changeCb }); } var Path; var init_path = __esm({ "packages/ag-charts-community/src/scene/shape/path.ts"() { "use strict"; init_core(); init_extendedPath2D(); init_node(); init_shape(); Path = class extends Shape { constructor() { super(...arguments); /** * Declare a path to retain for later rendering and hit testing * using custom Path2D class. Think of it as a TypeScript version * of the native Path2D (with some differences) that works in all browsers. */ this.path = new ExtendedPath2D(); this._clipX = NaN; this._clipY = NaN; this.clip = false; /** * The path only has to be updated when certain attributes change. * For example, if transform attributes (such as `translationX`) * are changed, we don't have to update the path. The `dirtyPath` flag * is how we keep track if the path has to be updated or not. */ this._dirtyPath = true; this.lastPixelRatio = NaN; } set clipX(value) { this._clipX = value; this.dirtyPath = true; } set clipY(value) { this._clipY = value; this.dirtyPath = true; } set dirtyPath(value) { if (this._dirtyPath !== value) { this._dirtyPath = value; if (value) { this.markDirty(); } } } get dirtyPath() { return this._dirtyPath; } checkPathDirty() { if (this._dirtyPath) { return; } this.dirtyPath = this.path.isDirty() || (this.fillShadow?.isDirty() ?? false) || (this._clipPath?.isDirty() ?? false); } isPointInPath(x, y) { this.updatePathIfDirty(); return this.path.closedPath && this.path.isPointInPath(x, y); } distanceSquared(x, y) { return this.distanceSquaredTransformedPoint(x, y); } svgPathData(transform) { this.updatePathIfDirty(); return this.path.toSVG(transform); } distanceSquaredTransformedPoint(x, y) { this.updatePathIfDirty(); if (this.path.closedPath && this.path.isPointInPath(x, y)) { return 0; } return this.path.distanceSquared(x, y); } isDirtyPath() { return false; } updatePath() { } updatePathIfDirty() { if (this.dirtyPath || this.isDirtyPath()) { this.updatePath(); this.dirtyPath = false; } } preRender(renderCtx) { if (renderCtx.devicePixelRatio !== this.lastPixelRatio) { this.dirtyPath = true; } this.lastPixelRatio = renderCtx.devicePixelRatio; this.updatePathIfDirty(); return super.preRender(renderCtx, this.path.commands.length); } render(renderCtx) { const { ctx } = renderCtx; if (this.clip && !isNaN(this._clipX) && !isNaN(this._clipY)) { ctx.save(); const margin = this.strokeWidth / 2; this._clipPath ?? (this._clipPath = new ExtendedPath2D()); this._clipPath.clear(); this._clipPath.rect(-margin, -margin, this._clipX + margin, this._clipY + margin + margin); ctx.clip(this._clipPath?.getPath2D()); if (this._clipX > 0 && this._clipY > 0) { this.drawPath(ctx); } ctx.restore(); } else { this._clipPath = void 0; this.drawPath(ctx); } this.fillShadow?.markClean(); super.render(renderCtx); } drawPath(ctx) { this.fillStroke(ctx, this.path.getPath2D()); } toSVG() { if (!this.visible) return; const element2 = createSvgElement("path"); element2.setAttribute("d", this.svgPathData()); this.applySvgFillAttributes(element2); this.applySvgStrokeAttributes(element2); return { elements: [element2] }; } }; Path.className = "Path"; __decorateClass([ ScenePathChangeDetection() ], Path.prototype, "clip", 2); __decorateClass([ ScenePathChangeDetection() ], Path.prototype, "clipX", 1); __decorateClass([ ScenePathChangeDetection() ], Path.prototype, "clipY", 1); } }); // packages/ag-charts-community/src/dom/focusIndicator.ts var FocusIndicator; var init_focusIndicator = __esm({ "packages/ag-charts-community/src/dom/focusIndicator.ts"() { "use strict"; init_core(); init_bbox(); init_path(); init_transformable(); init_dom(); FocusIndicator = class { constructor(swapChain) { this.swapChain = swapChain; this.div = createElement("div"); this.svg = createSvgElement("svg"); this.outerPath = createSvgElement("path"); this.innerPath = createSvgElement("path"); this.svg.append(this.outerPath); this.svg.append(this.innerPath); this.outerPath.classList.add("ag-charts-focus-svg-outer-path"); this.innerPath.classList.add("ag-charts-focus-svg-inner-path"); this.element = createElement("div", "ag-charts-focus-indicator"); this.element.ariaHidden = "true"; this.element.append(this.svg); this.swapChain.addListener("swap", (parent) => this.onSwap(parent)); } clear() { } update(focus, rect, clip) { if (rect == null) return; if (focus instanceof Path) { const transform = (localX, localY) => { let { x, y } = Transformable.toCanvasPoint(focus, localX, localY); x -= rect.x ?? 0; y -= rect.y ?? 0; return { x, y }; }; const d = focus.svgPathData(transform); this.outerPath.setAttribute("d", d); this.innerPath.setAttribute("d", d); this.show(this.svg); } else { let bbox; if (clip) { const x0 = Math.max(focus.x - rect.x, 0); const y0 = Math.max(focus.y - rect.y, 0); const x1 = Math.min(focus.x + focus.width - rect.x, rect.width); const y1 = Math.min(focus.y + focus.height - rect.y, rect.height); bbox = new BBox(x0, y0, x1 - x0, y1 - y0); } else { bbox = new BBox(focus.x - rect.x, focus.y - rect.y, focus.width, focus.height); } setElementBBox(this.div, bbox); this.show(this.div); } } onSwap(newParent) { if (newParent === this.element.parentElement) return; this.element.remove(); newParent.appendChild(this.element); this.overrideFocusVisible(this.focusVisible); } show(child) { this.element.innerHTML = ""; this.element.append(child); } overrideFocusVisible(focusVisible) { this.focusVisible = focusVisible; const opacity = { true: "1", false: "0", undefined: "" }; const parent = this.element.parentElement; parent?.style.setProperty("opacity", opacity[`${focusVisible}`]); } // Get the `:focus-visible` CSS state. isFocusVisible() { const parent = this.element.parentElement; return parent != null && getWindow().getComputedStyle(parent).opacity === "1"; } }; } }); // packages/ag-charts-community/src/dom/focusSwapChain.ts var FocusSwapChain; var init_focusSwapChain = __esm({ "packages/ag-charts-community/src/dom/focusSwapChain.ts"() { "use strict"; init_core(); init_attributeUtil(); FocusSwapChain = class { constructor(label1, label2, id, announcerRole) { this.label1 = label1; this.label2 = label2; this.hasFocus = false; this.skipDispatch = false; this.listeners = { blur: [], focus: [], swap: [] }; this.onBlur = (e) => { setElementStyle(e.target, "pointer-events", void 0); return !this.skipDispatch && this.dispatch("blur", e); }; this.onFocus = (e) => { setElementStyle(e.target, "pointer-events", "auto"); return !this.skipDispatch && this.dispatch("focus", e); }; setAttribute(this.label1, "id", `${id}-label1`); setAttribute(this.label2, "id", `${id}-label2`); setElementStyle(this.label1, "display", "none"); setElementStyle(this.label2, "display", "none"); this.activeAnnouncer = this.createAnnouncer(announcerRole); this.inactiveAnnouncer = this.createAnnouncer(announcerRole); setAttribute(this.activeAnnouncer, "tabindex", 0); this.label2.insertAdjacentElement("afterend", this.activeAnnouncer); this.label2.insertAdjacentElement("afterend", this.inactiveAnnouncer); this.swap(""); } createAnnouncer(role) { const announcer = createElement("div"); announcer.role = role; announcer.className = "ag-charts-swapchain"; announcer.addEventListener("blur", this.onBlur); announcer.addEventListener("focus", this.onFocus); return announcer; } destroy() { for (const announcer of [this.activeAnnouncer, this.inactiveAnnouncer]) { announcer.removeEventListener("blur", this.onBlur); announcer.removeEventListener("focus", this.onFocus); announcer.remove(); } } focus(opts) { this.focusOptions = opts; this.activeAnnouncer.focus(opts); this.focusOptions = void 0; } update(newLabel) { this.skipDispatch = true; this.swap(newLabel); if (this.hasFocus) { this.activeAnnouncer.focus(this.focusOptions); } this.skipDispatch = false; } addListener(type, handler) { this.listeners[type].push(handler); if (type === "swap") { const swapHandler = handler; swapHandler(this.activeAnnouncer); } } dispatch(type, param) { if (type === "focus") this.hasFocus = true; else if (type === "blur") this.hasFocus = false; this.listeners[type].forEach((fn) => fn(param)); } swap(newLabel) { const userTabIndex = this.activeAnnouncer.tabIndex; this.label2.textContent = newLabel; [this.inactiveAnnouncer, this.activeAnnouncer] = [this.activeAnnouncer, this.inactiveAnnouncer]; [this.label1, this.label2] = [this.label2, this.label1]; setAttributes(this.inactiveAnnouncer, { "aria-labelledby": this.label1.id, "aria-hidden": true, tabindex: void 0 }); setAttributes(this.activeAnnouncer, { "aria-labelledby": this.label1.id, "aria-hidden": false, tabindex: userTabIndex }); this.dispatch("swap", this.activeAnnouncer); } }; } }); // packages/ag-charts-community/src/chart/interaction/keyBindings.ts function matchesKeyBinding(e, bindings) { for (const kb of bindings) { if ("code" in kb) { if (kb.code === e.code) return true; } else { const matches = kb.key === e.key && (kb.shift === void 0 || kb.shift === e.shiftKey) && (kb.ctrlOrMeta === void 0 || kb.ctrlOrMeta === e.ctrlKey || kb.ctrlOrMeta === e.metaKey); if (matches) return true; } } return false; } function mapKeyboardEventToAction(event) { for (const [actionName, { activatesFocusIndicator = true, bindings }] of Object.entries(KEY_BINDINGS)) { if (matchesKeyBinding(event, bindings)) { const name = actionName; return { name, activatesFocusIndicator }; } } return void 0; } var KEY_BINDINGS; var init_keyBindings = __esm({ "packages/ag-charts-community/src/chart/interaction/keyBindings.ts"() { "use strict"; KEY_BINDINGS = { arrowdown: { bindings: [{ code: "ArrowDown" }] }, arrowleft: { bindings: [{ code: "ArrowLeft" }] }, arrowright: { bindings: [{ code: "ArrowRight" }] }, arrowup: { bindings: [{ code: "ArrowUp" }] }, delete: { bindings: [{ key: "Backspace" }, { key: "Delete" }], activatesFocusIndicator: false }, redo: { bindings: [ { key: "y", ctrlOrMeta: true }, { key: "z", ctrlOrMeta: true, shift: true } ], activatesFocusIndicator: false }, undo: { bindings: [{ key: "z", ctrlOrMeta: true }], activatesFocusIndicator: false }, submit: { bindings: [{ key: "Enter" }, { code: "Enter" }, { code: "Space" }] }, zoomin: { bindings: [{ key: "+" }, { code: "ZoomIn" }, { code: "Add" }], activatesFocusIndicator: false }, zoomout: { bindings: [{ key: "-" }, { code: "ZoomOut" }, { code: "Substract" }], activatesFocusIndicator: false } }; } }); // packages/ag-charts-community/src/chart/keyboardUtil.ts function computeCenter(series, hoverRect, pick) { const refPoint = getDatumRefPoint(series, pick.datum); if (refPoint != null) return { x: refPoint.canvasX, y: refPoint.canvasY }; const bboxOrPath = pick.bounds; if (bboxOrPath == null) return; if (bboxOrPath instanceof BBox) { const { x: centerX, y: centerY } = bboxOrPath.computeCenter(); return { x: hoverRect.x + centerX, y: hoverRect.y + centerY }; } return Transformable.toCanvas(bboxOrPath).computeCenter(); } function getPickedFocusBBox({ bounds }) { if (bounds instanceof BBox) return bounds; if (bounds != null) return Transformable.toCanvas(bounds); return BBox.NaN; } function makeKeyboardPointerEvent(series, hoverRect, pick) { const { x: canvasX, y: canvasY } = computeCenter(series, hoverRect, pick) ?? {}; if (canvasX !== void 0 && canvasY !== void 0) { return { type: "keyboard", canvasX, canvasY }; } return void 0; } var init_keyboardUtil = __esm({ "packages/ag-charts-community/src/chart/keyboardUtil.ts"() { "use strict"; init_bbox(); init_transformable(); init_util(); } }); // packages/ag-charts-community/src/util/placement.ts function calculatePlacement(naturalWidth, naturalHeight, container, bounds) { let { top, right, bottom, left, width: width2, height: height2 } = bounds; if (left != null) { if (width2 != null) { right = container.width - left + width2; } else if (right != null) { width2 = container.width - left - right; } } else if (right != null && width2 != null) { left = container.width - right - width2; } if (top != null) { if (height2 != null) { bottom = container.height - top - height2; } else if (bottom != null) { height2 = container.height - bottom - top; } } else if (bottom != null && height2 != null) { top = container.height - bottom - height2; } if (width2 == null) { if (height2 == null) { width2 = naturalWidth; height2 = naturalHeight; } else { width2 = Math.ceil(naturalWidth * height2 / naturalHeight); } } else if (height2 == null) { height2 = Math.ceil(naturalHeight * width2 / naturalWidth); } if (left == null) { if (right == null) { left = Math.floor((container.width - width2) / 2); } else { left = container.width - right - width2; } } if (top == null) { if (bottom == null) { top = Math.floor((container.height - height2) / 2); } else { top = container.height - height2 - bottom; } } return { x: left, y: top, width: width2, height: height2 }; } var init_placement = __esm({ "packages/ag-charts-community/src/util/placement.ts"() { "use strict"; } }); // packages/ag-charts-community/src/util/sanitize.ts function sanitizeHtml(text3) { if (text3 == null) { return; } else if (text3 === "") { return ""; } element ?? (element = createElement("div")); element.textContent = String(text3); return element.innerHTML; } var element; var init_sanitize = __esm({ "packages/ag-charts-community/src/util/sanitize.ts"() { "use strict"; init_core(); element = null; } }); // packages/ag-charts-community/src/chart/marker/shapes.ts function drawMarkerUnitPolygon(params, moves) { const { path, size } = params; const { x: x0, y: y0 } = params; path.clear(); let didMove = false; for (const [dx2, dy2] of moves) { const x = x0 + (dx2 - 0.5) * size; const y = y0 + (dy2 - 0.5) * size; if (didMove) { path.lineTo(x, y); } else { path.moveTo(x, y); } didMove = true; } path.closePath(); } var MARKER_SHAPES; var init_shapes = __esm({ "packages/ag-charts-community/src/chart/marker/shapes.ts"() { "use strict"; init_pixel(); init_angle(); MARKER_SHAPES = { circle({ path, x, y, size }) { const r = size / 2; path.clear(); path.arc(x, y, r, 0, Math.PI * 2); path.closePath(); }, cross(params) { drawMarkerUnitPolygon(params, [ [0.25, 0], [0.5, 0.25], [0.75, 0], [1, 0.25], [0.75, 0.5], [1, 0.75], [0.75, 1], [0.5, 0.75], [0.25, 1], [0, 0.75], [0.25, 0.5], [0, 0.25] ]); }, diamond(params) { drawMarkerUnitPolygon(params, [ [0.5, 0], [1, 0.5], [0.5, 1], [0, 0.5] ]); }, heart({ path, x, y, size }) { const r = size / 4; y = y + r / 2; path.clear(); path.arc(x - r, y - r, r, toRadians(130), toRadians(330)); path.arc(x + r, y - r, r, toRadians(220), toRadians(50)); path.lineTo(x, y + r); path.closePath(); }, pin({ path, x, y, size: s }) { const cx = 0.5; const cy = 0.5; path.moveTo(x + (0.15625 - cx) * s, y + (0.34375 - cy) * s); path.cubicCurveTo( x + (0.15625 - cx) * s, y + (0.151491 - cy) * s, x + (0.307741 - cx) * s, y + (0 - cy) * s, x + (0.5 - cx) * s, y + (0 - cy) * s ); path.cubicCurveTo( x + (0.692259 - cx) * s, y + (0 - cy) * s, x + (0.84375 - cx) * s, y + (0.151491 - cy) * s, x + (0.84375 - cx) * s, y + (0.34375 - cy) * s ); path.cubicCurveTo( x + (0.84375 - cx) * s, y + (0.493824 - cy) * s, x + (0.784625 - cx) * s, y + (0.600181 - cy) * s, x + (0.716461 - cx) * s, y + (0.695393 - cy) * s ); path.cubicCurveTo( x + (0.699009 - cx) * s, y + (0.719769 - cy) * s, x + (0.681271 - cx) * s, y + (0.743104 - cy) * s, x + (0.663785 - cx) * s, y + (0.766105 - cy) * s ); path.cubicCurveTo( x + (0.611893 - cx) * s, y + (0.834367 - cy) * s, x + (0.562228 - cx) * s, y + (0.899699 - cy) * s, x + (0.528896 - cx) * s, y + (0.980648 - cy) * s ); path.cubicCurveTo( x + (0.524075 - cx) * s, y + (0.992358 - cy) * s, x + (0.512663 - cx) * s, y + (1 - cy) * s, x + (0.5 - cx) * s, y + (1 - cy) * s ); path.cubicCurveTo( x + (0.487337 - cx) * s, y + (1 - cy) * s, x + (0.475925 - cx) * s, y + (0.992358 - cy) * s, x + (0.471104 - cx) * s, y + (0.980648 - cy) * s ); path.cubicCurveTo( x + (0.487337 - cx) * s, y + (1 - cy) * s, x + (0.475925 - cx) * s, y + (0.992358 - cy) * s, x + (0.471104 - cx) * s, y + (0.980648 - cy) * s ); path.cubicCurveTo( x + (0.437772 - cx) * s, y + (0.899699 - cy) * s, x + (0.388107 - cx) * s, y + (0.834367 - cy) * s, x + (0.336215 - cx) * s, y + (0.766105 - cy) * s ); path.cubicCurveTo( x + (0.318729 - cx) * s, y + (0.743104 - cy) * s, x + (0.300991 - cx) * s, y + (0.719769 - cy) * s, x + (0.283539 - cx) * s, y + (0.695393 - cy) * s ); path.cubicCurveTo( x + (0.215375 - cx) * s, y + (0.600181 - cy) * s, x + (0.15625 - cx) * s, y + (0.493824 - cy) * s, x + (0.15625 - cx) * s, y + (0.34375 - cy) * s ); path.closePath(); }, plus(params) { drawMarkerUnitPolygon(params, [ [1 / 3, 0], [2 / 3, 0], [2 / 3, 1 / 3], [1, 1 / 3], [1, 2 / 3], [2 / 3, 2 / 3], [2 / 3, 1], [1 / 3, 1], [1 / 3, 2 / 3], [0, 2 / 3], [0, 1 / 3], [1 / 3, 1 / 3] ]); }, square({ path, x, y, size, pixelRatio }) { const hs = size / 2; path.clear(); path.moveTo(align(pixelRatio, x - hs), align(pixelRatio, y - hs)); path.lineTo(align(pixelRatio, x + hs), align(pixelRatio, y - hs)); path.lineTo(align(pixelRatio, x + hs), align(pixelRatio, y + hs)); path.lineTo(align(pixelRatio, x - hs), align(pixelRatio, y + hs)); path.closePath(); }, star({ path, x, y, size }) { const spikes = 5; const outerRadius = size / 2; const innerRadius = outerRadius / 2; const rotation = Math.PI / 2; for (let i = 0; i < spikes * 2; i++) { const radius = i % 2 === 0 ? outerRadius : innerRadius; const angle2 = i * Math.PI / spikes - rotation; const xCoordinate = x + Math.cos(angle2) * radius; const yCoordinate = y + Math.sin(angle2) * radius; path.lineTo(xCoordinate, yCoordinate); } path.closePath(); }, triangle(params) { drawMarkerUnitPolygon(params, [ [0.5, 0], [1, 0.87], [0, 0.87] ]); } }; } }); // packages/ag-charts-community/src/chart/marker/marker.ts var InternalMarker, Marker; var init_marker = __esm({ "packages/ag-charts-community/src/chart/marker/marker.ts"() { "use strict"; init_bbox(); init_path(); init_transformable(); init_shapes(); InternalMarker = class extends Path { constructor() { super(...arguments); this.shape = "square"; this.x = 0; this.y = 0; this.size = 12; } updatePath() { const { path, shape, x, y, size } = this; const pixelRatio = this.layerManager?.canvas?.pixelRatio ?? 1; const anchor = Marker.anchor(shape); const drawParams = { path, x: x - (anchor.x - 0.5) * size, y: y - (anchor.y - 0.5) * size, size, pixelRatio }; path.clear(); if (typeof shape === "string") { MARKER_SHAPES[shape](drawParams); } else if (typeof shape === "function") { shape(drawParams); } } computeBBox() { const { x, y, size } = this; const anchor = Marker.anchor(this.shape); return new BBox(x - size * anchor.x, y - size * anchor.y, size, size); } executeFill(ctx, path) { if (!path) return; return super.executeFill(ctx, path); } executeStroke(ctx, path) { if (!path) return; return super.executeStroke(ctx, path); } }; __decorateClass([ ScenePathChangeDetection() ], InternalMarker.prototype, "shape", 2); __decorateClass([ ScenePathChangeDetection() ], InternalMarker.prototype, "x", 2); __decorateClass([ ScenePathChangeDetection() ], InternalMarker.prototype, "y", 2); __decorateClass([ ScenePathChangeDetection({ convertor: Math.abs }) ], InternalMarker.prototype, "size", 2); Marker = class extends Rotatable(Scalable(Translatable(InternalMarker))) { static anchor(shape) { if (shape === "pin") { return { x: 0.5, y: 1 }; } else if (typeof shape === "function" && "anchor" in shape) { return shape.anchor; } return { x: 0.5, y: 0.5 }; } constructor(options) { super(options); if (options?.shape != null) { this.shape = options.shape; } } }; } }); // packages/ag-charts-community/src/chart/legend/legendSymbol.ts function legendSymbolSvg(symbol, size, lineSize = size * (5 / 3)) { const group = new Group(); const markerStrokeWidth = Math.min(symbol.marker.strokeWidth, 2); const lineStrokeWidth = Math.min(symbol.line?.strokeWidth ?? 0, 2); const width2 = Math.max(symbol.marker.enabled === false ? 0 : size, symbol.line == null ? 0 : lineSize); const height2 = Math.max(symbol.marker.enabled === false ? 0 : size, lineStrokeWidth); if (symbol.line != null) { const { stroke: stroke3, strokeOpacity, lineDash } = symbol.line; const line = new Line(); line.x1 = 0; line.y1 = height2 / 2; line.x2 = width2; line.y2 = height2 / 2; line.stroke = stroke3; line.strokeOpacity = strokeOpacity; line.strokeWidth = lineStrokeWidth; line.lineDash = lineDash; group.append(line); } if (symbol.marker.enabled !== false) { const { shape, fill, fillOpacity, stroke: stroke3, strokeOpacity, lineDash, lineDashOffset } = symbol.marker; const marker = new Marker(); marker.shape = shape ?? "square"; marker.size = size; marker.fill = fill; marker.fillOpacity = fillOpacity; marker.stroke = stroke3; marker.strokeOpacity = strokeOpacity; marker.strokeWidth = markerStrokeWidth; marker.lineDash = lineDash; marker.lineDashOffset = lineDashOffset; const anchor = Marker.anchor(shape); const x = width2 / 2 + (anchor.x - 0.5) * size; const y = height2 / 2 + (anchor.y - 0.5) * size; const scale2 = size / (size + markerStrokeWidth); marker.x = 0; marker.y = 0; marker.translationX = x; marker.translationY = y; marker.scalingX = scale2; marker.scalingY = scale2; group.append(marker); } return Group.toSVG(group, width2, height2); } var init_legendSymbol = __esm({ "packages/ag-charts-community/src/chart/legend/legendSymbol.ts"() { "use strict"; init_group(); init_line(); init_marker(); } }); // packages/ag-charts-community/src/chart/tooltip/springAnimation.ts var M, K, C, DELTA, SpringAnimation; var init_springAnimation = __esm({ "packages/ag-charts-community/src/chart/tooltip/springAnimation.ts"() { "use strict"; init_listeners(); M = 0.1; K = 200; C = 12; DELTA = 0.5; SpringAnimation = class extends Listeners { constructor() { super(...arguments); this.x1 = NaN; this.y1 = NaN; this.x = NaN; this.y = NaN; this.vx = 0; this.vy = 0; this.t0 = NaN; this.animationFrameHandle = void 0; } reset() { this.x = NaN; this.y = NaN; if (this.animationFrameHandle != null) { cancelAnimationFrame(this.animationFrameHandle); this.animationFrameHandle = void 0; } } update(x, y) { if (Number.isNaN(this.x) || Number.isNaN(this.y)) { this.x = x; this.y = y; this.vx = 0; this.vy = 0; this.emitUpdate(); if (this.animationFrameHandle != null) { cancelAnimationFrame(this.animationFrameHandle); this.animationFrameHandle = void 0; } return; } this.x1 = x; this.y1 = y; this.t0 = Date.now(); if (this.animationFrameHandle == null) { this.animationFrameHandle = requestAnimationFrame(this.onFrame.bind(this)); } } onFrame() { this.animationFrameHandle = void 0; const { x1, y1, t0 } = this; const t1 = Date.now(); const dt = t1 - t0; this.t0 = t1; const stepT = 1e-3; const iterations = Math.ceil(dt / (stepT * 1e3)) | 0; let { x, y, vx, vy } = this; for (let i = 0; i < iterations; i += 1) { const dx2 = x - x1; const dy2 = y - y1; const ax = -(K * dx2 + C * vx) / M; const ay = -(K * dy2 + C * vy) / M; vx += ax * stepT; vy += ay * stepT; x += vx * stepT; y += vy * stepT; } if (Math.hypot(x - x1, y - y1) < DELTA) { this.x = this.x1; this.y = this.y1; this.vx = 0; this.vy = 0; } else { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.animationFrameHandle = requestAnimationFrame(this.onFrame.bind(this)); } this.emitUpdate(); } emitUpdate() { this.dispatch("update", { type: "update", x: this.x, y: this.y }); } }; } }); // packages/ag-charts-community/src/chart/tooltip/tooltip.ts function tooltipContentAriaLabel(content) { const ariaLabel = []; if (content.type === "raw") return ""; if (content.heading != null) ariaLabel.push(content.heading); if (content.title != null) ariaLabel.push(content.title); content.data?.forEach((datum) => { ariaLabel.push(datum.label ?? datum.fallbackLabel, datum.value); }); return ariaLabel.join("; "); } function dataHtml(label, value, inline) { let rowHtml = ""; if (label == null) { rowHtml += `${sanitizeHtml(value)}`; } else { rowHtml += `${sanitizeHtml(label)}`; rowHtml += " "; rowHtml += `${sanitizeHtml(value)}`; } const rowClassNames = [`${DEFAULT_TOOLTIP_CLASS}-row`]; if (inline) rowClassNames.push(`${DEFAULT_TOOLTIP_CLASS}-row--inline`); rowHtml = `
${rowHtml}
`; return rowHtml; } function tooltipContentHtml(content) { if (content.type === "raw") return content.rawHtmlString; let html = ""; if ((content.heading == null || content.title == null) && content.data?.length === 1 && content.data[0].label == null && content.data[0].value != null) { const datum = content.data[0]; html += dataHtml(content.heading ?? content.title, datum.value, false); } else { const dataInline = content.title == null && content.data?.length === 1; if (content.heading != null) { html += `${sanitizeHtml(content.heading)}`; html += " "; } const symbol = content.symbol == null ? void 0 : legendSymbolSvg(content.symbol, 12); if (symbol != null && (content.title != null || content.data?.length)) { html += `${symbol}`; } if (content.title != null) { html += `${sanitizeHtml(content.title)}`; html += " "; } content.data?.forEach((datum) => { html += dataHtml(datum.label ?? datum.fallbackLabel, datum.value, dataInline); html += " "; }); } html = `
${html.trimEnd()}
`; return html; } var DEFAULT_TOOLTIP_CLASS, DEFAULT_TOOLTIP_DARK_CLASS, TooltipPosition, Tooltip; var init_tooltip = __esm({ "packages/ag-charts-community/src/chart/tooltip/tooltip.ts"() { "use strict"; init_core(); init_number(); init_placement(); init_properties(); init_sanitize(); init_validation2(); init_legendSymbol(); init_springAnimation(); DEFAULT_TOOLTIP_CLASS = "ag-charts-tooltip"; DEFAULT_TOOLTIP_DARK_CLASS = "ag-charts-tooltip--dark"; TooltipPosition = class extends BaseProperties { constructor() { super(...arguments); /** The type of positioning for the tooltip. By default, the tooltip follows the pointer. */ this.type = "pointer"; /** The horizontal offset in pixels for the position of the tooltip. */ this.xOffset = 0; /** The vertical offset in pixels for the position of the tooltip. */ this.yOffset = 0; } }; __decorateClass([ Validate( UNION( [ "pointer", "node", "top", "right", "bottom", "left", "top-left", "top-right", "bottom-right", "bottom-left", { value: "sparkline", undocumented: true }, { value: "sparkline-", undocumented: true } ], "a position type" ) ) ], TooltipPosition.prototype, "type", 2); __decorateClass([ Validate(NUMBER) ], TooltipPosition.prototype, "xOffset", 2); __decorateClass([ Validate(NUMBER) ], TooltipPosition.prototype, "yOffset", 2); Tooltip = class extends BaseProperties { constructor() { super(); this.enabled = true; this.delay = 0; this.range = void 0; this.wrapping = "hyphenate"; this.position = new TooltipPosition(); this.darkTheme = false; this.bounds = "extended"; this.destroyFns = []; this.springAnimation = new SpringAnimation(); this.enableInteraction = false; this.wrapTypes = ["always", "hyphenate", "on-space", "never"]; this.showTimeout = 0; this._showArrow = true; this._compact = false; this._visible = false; this.positionParams = void 0; this.destroyFns.push(this.springAnimation.addListener("update", this.updateTooltipPosition.bind(this))); } get interactive() { return this.enableInteraction; } setup(domManager) { if ("togglePopover" in getWindow().HTMLElement.prototype) { this.element = domManager.addChild("canvas-overlay", DEFAULT_TOOLTIP_CLASS); this.element.setAttribute("popover", "manual"); this.element.className = DEFAULT_TOOLTIP_CLASS; } } destroy(domManager) { domManager.removeChild("canvas-overlay", DEFAULT_TOOLTIP_CLASS); this.destroyFns.forEach((f) => f()); } isVisible() { return this._visible; } contains(node) { return this.element?.contains(node) ?? false; } updateTooltipPosition() { const { element: element2, positionParams } = this; if (element2 == null || positionParams == null) return; const { canvasRect, relativeRect, meta } = positionParams; const { x: canvasX, y: canvasY } = this.springAnimation; const positionType = meta.position?.type ?? this.position.type; const xOffset = meta.position?.xOffset ?? 0; const yOffset = meta.position?.yOffset ?? 0; const minX = relativeRect.x; const minY = relativeRect.y; const maxX = relativeRect.width - element2.clientWidth - 1 + minX; const maxY = relativeRect.height - element2.clientHeight + minY; let tooltipBounds = this.getTooltipBounds({ positionType, canvasX, canvasY, yOffset, xOffset, canvasRect }); let position = calculatePlacement(element2.clientWidth, element2.clientHeight, relativeRect, tooltipBounds); if (positionType === "sparkline" && (position.x <= minX || position.x >= maxX)) { tooltipBounds = this.getTooltipBounds({ positionType: "sparkline-constrained", canvasX, canvasY, yOffset, xOffset, canvasRect }); position = calculatePlacement(element2.clientWidth, element2.clientHeight, relativeRect, tooltipBounds); } const left = clamp(minX, position.x, maxX); const top = clamp(minY, position.y, maxY); const constrained = left !== position.x || top !== position.y; const defaultShowArrow = (positionType === "node" || positionType === "pointer") && !constrained && !xOffset && !yOffset; const showArrow = meta.showArrow ?? this.showArrow ?? defaultShowArrow; this.updateShowArrow(showArrow); this.updateCompact(positionType === "sparkline" || positionType === "sparkline-constrained"); element2.style.transform = `translate(${left}px, ${top}px)`; } /** * Shows tooltip at the given event's coordinates. * If the `html` parameter is missing, moves the existing tooltip to the new position. */ show(boundingRect, canvasRect, meta, content, instantly = false) { const { element: element2 } = this; if (element2 != null && content != null) { element2.innerHTML = tooltipContentHtml(content); } else if (element2 == null || element2.innerHTML === "") { this.toggle(false); return; } const relativeRect = { x: boundingRect.x - canvasRect.x, y: boundingRect.y - canvasRect.y, width: boundingRect.width, height: boundingRect.height }; this.positionParams = { canvasRect, relativeRect, meta }; this.springAnimation.update(meta.canvasX, meta.canvasY); element2.style.top = `${canvasRect.top}px`; element2.style.left = `${canvasRect.left}px`; if (meta.enableInteraction) { this.enableInteraction = true; element2.style.pointerEvents = "auto"; element2.removeAttribute("aria-hidden"); } else { this.enableInteraction = false; element2.style.pointerEvents = "none"; element2.setAttribute("aria-hidden", "true"); } if (this.delay > 0 && !instantly) { this.toggle(false); this.showTimeout = setTimeout(() => { this.toggle(true); }, this.delay); } else { this.toggle(true); } } hide() { this.springAnimation.reset(); this.toggle(false); } toggle(visible) { if (!this.element?.isConnected) return; this._visible = visible; const { classList } = this.element; const toggleClass = (name, include) => classList.toggle(`${DEFAULT_TOOLTIP_CLASS}--${name}`, include); if (!visible) { clearTimeout(this.showTimeout); } toggleClass("no-interaction", !this.enableInteraction); toggleClass("arrow", this._showArrow); toggleClass("compact", this._compact); classList.toggle(DEFAULT_TOOLTIP_DARK_CLASS, this.darkTheme); this.element.togglePopover(visible); if (visible) { this.updateTooltipPosition(); } for (const wrapType of this.wrapTypes) { classList.toggle(`${DEFAULT_TOOLTIP_CLASS}--wrap-${wrapType}`, wrapType === this.wrapping); } } updateShowArrow(show) { this._showArrow = show; } updateCompact(compact) { this._compact = compact; } getTooltipBounds(opts) { if (!this.element) return {}; const { positionType, canvasX, canvasY, yOffset, xOffset, canvasRect } = opts; const { clientWidth: tooltipWidth, clientHeight: tooltipHeight } = this.element; const bounds = { width: tooltipWidth, height: tooltipHeight }; switch (positionType) { case "node": case "pointer": { bounds.top = canvasY + yOffset - tooltipHeight - 8; bounds.left = canvasX + xOffset - tooltipWidth / 2; return bounds; } case "top": { bounds.top = yOffset; bounds.left = canvasRect.width / 2 - tooltipWidth / 2 + xOffset; return bounds; } case "right": { bounds.top = canvasRect.height / 2 - tooltipHeight / 2 + yOffset; bounds.left = canvasRect.width - tooltipWidth / 2 + xOffset; return bounds; } case "left": { bounds.top = canvasRect.height / 2 - tooltipHeight / 2 + yOffset; bounds.left = xOffset; return bounds; } case "bottom": { bounds.top = canvasRect.height - tooltipHeight + yOffset; bounds.left = canvasRect.width / 2 - tooltipWidth / 2 + xOffset; return bounds; } case "top-left": { bounds.top = yOffset; bounds.left = xOffset; return bounds; } case "top-right": { bounds.top = yOffset; bounds.left = canvasRect.width - tooltipWidth + xOffset; return bounds; } case "bottom-right": { bounds.top = canvasRect.height - tooltipHeight + yOffset; bounds.left = canvasRect.width - tooltipWidth + xOffset; return bounds; } case "bottom-left": { bounds.top = canvasRect.height - tooltipHeight + yOffset; bounds.left = xOffset; return bounds; } case "sparkline": { bounds.top = canvasY + yOffset - tooltipHeight / 2; bounds.left = canvasX + xOffset + 8; return bounds; } case "sparkline-constrained": { bounds.top = canvasY + yOffset - tooltipHeight / 2; bounds.left = canvasX + xOffset - 8 - tooltipWidth; return bounds; } } } }; __decorateClass([ Validate(BOOLEAN) ], Tooltip.prototype, "enabled", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], Tooltip.prototype, "showArrow", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Tooltip.prototype, "delay", 2); __decorateClass([ Validate(INTERACTION_RANGE, { optional: true }) ], Tooltip.prototype, "range", 2); __decorateClass([ Validate(TEXT_WRAP) ], Tooltip.prototype, "wrapping", 2); __decorateClass([ Validate(OBJECT) ], Tooltip.prototype, "position", 2); __decorateClass([ Validate(BOOLEAN) ], Tooltip.prototype, "darkTheme", 2); __decorateClass([ Validate(UNION(["extended", "canvas"])) ], Tooltip.prototype, "bounds", 2); } }); // packages/ag-charts-community/src/chart/series/seriesAreaManager.ts function excludesType(obj, excluded) { return obj.type !== excluded; } var SeriesAreaManager; var init_seriesAreaManager = __esm({ "packages/ag-charts-community/src/chart/series/seriesAreaManager.ts"() { "use strict"; init_focusIndicator(); init_focusSwapChain(); init_transformable(); init_baseManager(); init_id(); init_number(); init_render(); init_keyBindings(); init_tooltipManager(); init_keyboardUtil(); init_tooltip(); SeriesAreaManager = class extends BaseManager { constructor(chart) { super(); this.chart = chart; this.id = createId(this); this.series = []; this.highlight = { /** Last received event that still needs to be applied. */ pendingHoverEvent: void 0, /** Last applied event. */ appliedHoverEvent: void 0, /** Last applied event, which has been temporarily stashed during the main chart update cycle. */ stashedHoverEvent: void 0 }; this.tooltip = { lastHover: void 0 }; /** * A11y Requirements for Tooltip/Highlight (see AG-13051 for details): * * - When the series-area is blurred, always the mouse to update the tooltip/highlight. * * - When the series-area receives a `focus` event, use `:focus-visible` to guess the input device. * (this is decided by the browser). * * - For keyboard users, `focus` and `keydown` events always updates & shows the tooltip/highlight on * the currently (or newly) focused datum. * * - For keyboard users, `mousemove` events update the tooltip/highlight iff `pickNode` finds a match * for the mouse event offsets. */ this.hoverDevice = "pointer"; /** * This is the "second last" input event. It can be useful for keydown * events that for which don't to set the isFocusVisible state * (e.g. Backspace/Delete key on FC annotations, see AG-13041). * * Use with caution! The focus indicator must ALWAYS be visible for * keyboard-only users. */ this.previousInputDevice = "keyboard"; this.focus = { sortedSeries: [], series: void 0, seriesIndex: 0, datumIndex: 0, datum: void 0 }; this.hoverScheduler = debouncedAnimationFrame(() => { if (!this.tooltip.lastHover && !this.highlight.pendingHoverEvent) return; if (this.chart.getUpdateType() <= 4 /* SERIES_UPDATE */) { this.hoverScheduler.schedule(); return; } if (this.highlight.pendingHoverEvent) { this.handleHoverHighlight(false); } if (this.tooltip.lastHover) { this.handleHoverTooltip(this.tooltip.lastHover, false); } }); const label1 = chart.ctx.domManager.addChild("series-area", "series-area-aria-label1"); const label2 = chart.ctx.domManager.addChild("series-area", "series-area-aria-label2"); this.swapChain = new FocusSwapChain(label1, label2, this.id, "img"); this.swapChain.addListener("blur", () => this.onBlur()); this.swapChain.addListener("focus", () => this.onFocus()); this.focusIndicator = new FocusIndicator(this.swapChain); this.focusIndicator.overrideFocusVisible(chart.mode === "integrated" ? false : void 0); const { seriesDragInterpreter, seriesWidget, containerWidget } = chart.ctx.widgets; seriesWidget.setTabIndex(-1); this.destroyFns.push( () => chart.ctx.domManager.removeChild("series-area", "series-area-aria-label1"), () => chart.ctx.domManager.removeChild("series-area", "series-area-aria-label2"), seriesWidget.addListener("focus", () => this.swapChain.focus()), seriesWidget.addListener("mousemove", (event) => this.onHover(event)), seriesWidget.addListener("wheel", (event) => this.onWheel(event)), seriesWidget.addListener("mouseleave", (event) => this.onLeave(event)), seriesWidget.addListener("keydown", (event) => this.onKeyDown(event)), seriesWidget.addListener("contextmenu", (event, current) => this.onContextMenu(event, current)), seriesDragInterpreter.addListener("drag-move", (event) => this.onDragMove(event)), seriesDragInterpreter.addListener("click", (event) => this.onClick(event, seriesWidget)), seriesDragInterpreter.addListener("dblclick", (event) => this.onClick(event, seriesWidget)), containerWidget.addListener("contextmenu", (event, current) => this.onContextMenu(event, current)), containerWidget.addListener("click", (event, current) => this.onClick(event, current)), containerWidget.addListener("dblclick", (event, current) => this.onClick(event, current)), chart.ctx.animationManager.addListener("animation-start", () => this.clearAll()), chart.ctx.domManager.addListener("resize", () => this.clearAll()), chart.ctx.highlightManager.addListener("highlight-change", (event) => this.changeHighlightDatum(event)), chart.ctx.layoutManager.addListener("layout:complete", (event) => this.layoutComplete(event)), chart.ctx.updateService.addListener("pre-scene-render", () => this.preSceneRender()), chart.ctx.updateService.addListener("update-complete", () => this.updateComplete()), chart.ctx.zoomManager.addListener("zoom-change", () => this.clearAll()), chart.ctx.zoomManager.addListener("zoom-pan-start", () => this.clearAll()) ); } isState(allowedStates) { return this.chart.ctx.interactionManager.isState(allowedStates); } isIgnoredTouch(event) { if (event.device !== "touch" || event.type === "click") return false; if (this.chart.ctx.chartService.touch.dragAction === "hover") return false; if (this.chart.ctx.chartService.touch.dragAction === "drag") { if (this.isState(9 /* AnnotationsMoveable */)) { return false; } } return true; } dataChanged() { var _a; (_a = this.highlight).stashedHoverEvent ?? (_a.stashedHoverEvent = this.highlight.appliedHoverEvent); this.chart.ctx.tooltipManager.removeTooltip(this.id); this.focusIndicator.clear(); this.clearHighlight(); } preSceneRender() { if (this.highlight.stashedHoverEvent != null) { this.highlight.pendingHoverEvent = this.highlight.stashedHoverEvent; this.highlight.stashedHoverEvent = void 0; this.handleHoverHighlight(true); } if (this.tooltip.lastHover != null) { this.handleHoverTooltip(this.tooltip.lastHover, true); } } updateComplete() { if (this.focusIndicator.isFocusVisible() && this.isState(34 /* Focusable */)) { this.handleSeriesFocus(0, 0, true); } } update(type, opts) { this.chart.ctx.updateService.update(type, opts); } seriesChanged(series) { this.focus.sortedSeries = [...series].sort((a, b) => { let fpA = a.properties.focusPriority ?? Infinity; let fpB = b.properties.focusPriority ?? Infinity; if (fpA === fpB) { [fpA, fpB] = [a._declarationOrder, b._declarationOrder]; } if (fpA < fpB) { return -1; } else if (fpA > fpB) { return 1; } return 0; }); this.series = series; } layoutComplete(event) { this.seriesRect = event.series.rect; this.hoverRect = event.series.paddedRect; this.chart.ctx.widgets.seriesWidget.setBounds(event.series.paddedRect); this.chart.ctx.widgets.chartWidget.setBounds(event.chart); } onContextMenu(event, current) { const { sourceEvent } = event; if (sourceEvent.currentTarget != current.getElement()) return; if (sourceEvent.target == this.chart.ctx.widgets.containerWidget.getElement()) { if (this.isState(36 /* ContextMenuable */)) { const { currentX: canvasX2, currentY: canvasY2 } = event; this.chart.ctx.contextMenuRegistry.dispatchContext("all", { sourceEvent, canvasX: canvasX2, canvasY: canvasY2 }, {}); } return; } let pickedNode; let position; if (this.focusIndicator.isFocusVisible()) { pickedNode = this.chart.ctx.highlightManager.getActiveHighlight(); if (pickedNode && this.seriesRect && pickedNode.midPoint) { position = Transformable.toCanvasPoint( pickedNode.series.contentGroup, pickedNode.midPoint.x, pickedNode.midPoint.y ); } } else if (this.isState(36 /* ContextMenuable */)) { const match = this.pickNode({ x: event.currentX, y: event.currentY }, "context-menu"); if (match) { this.chart.ctx.highlightManager.updateHighlight(this.id); pickedNode = match.datum; } } const pickedSeries = pickedNode?.series; this.clearAll(); const canvasX = event.currentX + current.cssLeft(); const canvasY = event.currentY + current.cssTop(); this.chart.ctx.contextMenuRegistry.dispatchContext( "series-area", { sourceEvent, canvasX, canvasY }, { pickedSeries, pickedNode }, position ); } onLeave(event) { if (!this.isState(41 /* Clickable */)) return; const relatedTarget = event.sourceEvent.relatedTarget; if (relatedTarget?.className === "ag-charts-text-input__textarea") { return; } if (this.chart.ctx.tooltipManager.isEnteringInteractiveTooltip(event)) { return; } this.chart.ctx.domManager.updateCursor(this.id); if (!this.focusIndicator.isFocusVisible()) this.clearAll(); } onWheel(_event) { if (!this.isState(41 /* Clickable */)) return; this.focusIndicator?.overrideFocusVisible(false); this.previousInputDevice = "pointer"; } onDragMove(event) { if (!this.isState(41 /* Clickable */)) return; this.focusIndicator?.overrideFocusVisible(false); this.onHoverLikeEvent(event); } onHover(event) { if (!this.isState(41 /* Clickable */)) return; this.onHoverLikeEvent(event); } onHoverLikeEvent(event) { if (this.isIgnoredTouch(event)) return; if (event.device === "touch" || excludesType(event, "drag-move")) { this.tooltip.lastHover = event; } if (event.device === "touch" && this.chart.ctx.chartService.touch.dragAction === "hover") { event.sourceEvent.preventDefault(); } this.hoverDevice = "pointer"; this.previousInputDevice = "pointer"; this.highlight.pendingHoverEvent = event; this.hoverScheduler.schedule(); if (this.isState(32 /* Default */)) { const { currentX: x, currentY: y } = event; const found = this.pickNode({ x, y }, "event"); if (found?.series.hasEventListener("nodeClick") || found?.series.hasEventListener("nodeDoubleClick")) { this.chart.ctx.domManager.updateCursor(this.id, "pointer"); } else { this.chart.ctx.domManager.updateCursor(this.id); } } } onClick(event, current) { if (event.device === "touch" && current === this.chart.ctx.widgets.seriesWidget) { this.swapChain.focus({ preventScroll: true }); } if (!this.isState(41 /* Clickable */)) return; if (current === this.chart.ctx.widgets.seriesWidget) { if (!current.getElement().contains(event.sourceEvent.target)) { return; } } else if (event.sourceEvent.target != current.getElement()) { return; } this.focusIndicator.overrideFocusVisible(false); this.onHoverLikeEvent(event); if (!this.isState(32 /* Default */)) return; if (current == this.chart.ctx.widgets.seriesWidget && this.checkSeriesNodeClick(event)) { this.update(4 /* SERIES_UPDATE */); event.sourceEvent.preventDefault(); return; } const newEvent = { type: event.type === "click" ? "click" : "doubleClick", event: event.sourceEvent }; this.chart.fireEvent(newEvent); } onFocus() { if (!this.isState(34 /* Focusable */)) return; this.hoverDevice = this.focusIndicator.isFocusVisible() ? "keyboard" : "pointer"; this.handleFocus(0, 0); } onBlur() { if (!this.isState(34 /* Focusable */)) return; this.hoverDevice = "pointer"; this.clearAll(); this.focusIndicator.overrideFocusVisible(void 0); } onKeyDown(widgetEvent) { if (!this.isState(43 /* Keyable */)) return; const action = mapKeyboardEventToAction(widgetEvent.sourceEvent); if (action?.activatesFocusIndicator === false) { this.focusIndicator.overrideFocusVisible(this.previousInputDevice === "keyboard"); } switch (action?.name) { case "redo": return this.chart.ctx.chartEventManager.seriesEvent("series-redo"); case "undo": return this.chart.ctx.chartEventManager.seriesEvent("series-undo"); case "zoomin": return this.chart.ctx.chartEventManager.seriesKeyNavZoom(1, widgetEvent); case "zoomout": return this.chart.ctx.chartEventManager.seriesKeyNavZoom(-1, widgetEvent); case "arrowup": return this.onArrow(-1, 0, widgetEvent); case "arrowdown": return this.onArrow(1, 0, widgetEvent); case "arrowleft": return this.onArrow(0, -1, widgetEvent); case "arrowright": return this.onArrow(0, 1, widgetEvent); case "submit": return this.onSubmit(widgetEvent); } } onArrow(seriesIndexDelta, datumIndexDelta, event) { if (!this.isState(34 /* Focusable */)) return; this.hoverDevice = "keyboard"; this.previousInputDevice = "keyboard"; this.focusIndicator.overrideFocusVisible(true); this.focus.seriesIndex += seriesIndexDelta; this.focus.datumIndex += datumIndexDelta; this.handleFocus(seriesIndexDelta, datumIndexDelta); event.sourceEvent.preventDefault(); this.chart.ctx.chartEventManager.seriesEvent("series-focus-change"); } onSubmit(event) { if (!this.isState(34 /* Focusable */)) return; const { series, datum } = this.focus; const sourceEvent = event.sourceEvent; if (series !== void 0 && datum !== void 0) { series.fireNodeClickEvent(sourceEvent, datum); } else { this.chart.fireEvent({ type: "click", event: sourceEvent }); } sourceEvent.preventDefault(); } checkSeriesNodeClick(event) { const result = this.pickNode({ x: event.currentX, y: event.currentY }, "event"); if (result == null) return false; if (event.type === "click") { result.series.fireNodeClickEvent(event.sourceEvent, result.datum); return true; } if (event.type === "dblclick") { event.preventZoomDblClick = result.distance === 0; result.series.fireNodeDoubleClickEvent(event.sourceEvent, result.datum); return true; } return false; } handleFocus(seriesIndexDelta, datumIndexDelta) { const overlayFocus = this.chart.overlays.getFocusInfo(this.chart.ctx.localeManager); if (overlayFocus == null) { this.handleSeriesFocus(seriesIndexDelta, datumIndexDelta); } else { this.focusIndicator.update(overlayFocus.rect, this.seriesRect, false); } } handleSeriesFocus(otherIndexDelta, datumIndexDelta, refresh = false) { if (this.chart.chartType === "hierarchy" || this.chart.chartType === "gauge") { this.handleSoloSeriesFocus(otherIndexDelta, datumIndexDelta, refresh); return; } const { focus, seriesRect } = this; const visibleSeries = focus.sortedSeries.filter((s) => s.visible && s.focusable); if (visibleSeries.length === 0) return; const oldPick = { datumIndex: focus.datumIndex - datumIndexDelta, otherIndex: focus.seriesIndex - otherIndexDelta }; focus.seriesIndex = clamp(0, focus.seriesIndex, visibleSeries.length - 1); focus.series = visibleSeries[focus.seriesIndex]; const { datumIndex, seriesIndex: otherIndex } = focus; const pick = focus.series.pickFocus({ datumIndex, datumIndexDelta, otherIndex, otherIndexDelta, seriesRect }); this.updatePickedFocus(otherIndexDelta, datumIndexDelta, oldPick, pick, refresh); } handleSoloSeriesFocus(otherIndexDelta, datumIndexDelta, refresh) { this.focus.series = this.focus.sortedSeries[0]; const { focus: { series, seriesIndex: otherIndex, datumIndex }, seriesRect } = this; if (series == null) return; const oldPick = { datumIndex: this.focus.datumIndex - datumIndexDelta, otherIndex: this.focus.seriesIndex - otherIndexDelta }; const pick = series.pickFocus({ datumIndex, datumIndexDelta, otherIndex, otherIndexDelta, seriesRect }); this.updatePickedFocus(otherIndexDelta, datumIndexDelta, oldPick, pick, refresh); } updatePickedFocus(otherIndexDelta, datumIndexDelta, oldPick, pick, refresh) { const { focus, hoverRect } = this; if (pick === void 0 || focus.series === void 0 || hoverRect === void 0) return; const { datum, datumIndex, otherIndex } = pick; if (otherIndex !== void 0) { focus.seriesIndex = otherIndex; } focus.datumIndex = datumIndex; focus.datum = datum; if (this.focusIndicator.isFocusVisible()) { this.chart.ctx.animationManager.reset(); } if (this.focusIndicator.isFocusVisible()) { const focusBBox = getPickedFocusBBox(pick); const { x, y } = focusBBox.computeCenter(); if (!hoverRect.containsPoint(x, y)) { const panSuccess = this.chart.ctx.zoomManager.panToBBox(this.id, hoverRect, focusBBox); if (panSuccess) { return; } } } this.focusIndicator.update(pick.bounds, this.seriesRect, pick.clipFocusBox); const keyboardEvent = makeKeyboardPointerEvent(focus.series, hoverRect, pick); if (keyboardEvent !== void 0 && this.hoverDevice === "keyboard") { this.tooltip.lastHover = void 0; this.highlight.appliedHoverEvent = void 0; this.highlight.pendingHoverEvent = void 0; this.highlight.stashedHoverEvent = void 0; const tooltipContent = focus.series.getTooltipContent(datum); const meta = TooltipManager.makeTooltipMeta(keyboardEvent, focus.series, datum); this.chart.ctx.highlightManager.updateHighlight(this.id, datum); const tooltipEnabled = this.chart.tooltip.enabled && focus.series.tooltipEnabled; if (tooltipEnabled) { this.chart.ctx.tooltipManager.updateTooltip(this.id, meta, tooltipContent); } else { this.chart.ctx.tooltipManager.removeTooltip(this.id); } if (!refresh) { const shouldAnnouncePick = datumIndexDelta === 0 && otherIndexDelta === 0 || oldPick.datumIndex !== pick.datumIndex || oldPick.otherIndex !== (pick.otherIndex ?? focus.seriesIndex); if (shouldAnnouncePick) { this.swapChain.update(this.getDatumAriaText(datum, tooltipContent)); } } } } getDatumAriaText(datum, tooltipContent) { const description = tooltipContent == null ? "" : tooltipContentAriaLabel(tooltipContent); return this.chart.ctx.localeManager.t("ariaAnnounceHoverDatum", { datum: datum.series.getDatumAriaText?.(datum, description) ?? description }); } clearHighlight() { this.highlight.pendingHoverEvent = void 0; this.highlight.appliedHoverEvent = void 0; this.chart.ctx.highlightManager.updateHighlight(this.id); } clearTooltip() { this.chart.ctx.tooltipManager.removeTooltip(this.id); this.tooltip.lastHover = void 0; } clearAll() { this.clearHighlight(); this.clearTooltip(); this.focusIndicator.clear(); } handleHoverHighlight(redisplay) { this.highlight.appliedHoverEvent = this.highlight.pendingHoverEvent; this.highlight.pendingHoverEvent = void 0; const event = this.highlight.appliedHoverEvent; if (!event || !this.isState(41 /* Clickable */)) return; const { currentX, currentY } = event; const canvasX = event.currentX + (this.hoverRect?.x ?? 0); const canvasY = event.currentY + (this.hoverRect?.y ?? 0); if (redisplay ? this.chart.ctx.animationManager.isActive() : !this.hoverRect?.containsPoint(canvasX, canvasY)) { this.clearHighlight(); return; } const { range: range4 } = this.chart.highlight; const intent = range4 === "tooltip" ? "highlight-tooltip" : "highlight"; const found = this.pickNode({ x: currentX, y: currentY }, intent); if (found) { this.chart.ctx.highlightManager.updateHighlight(this.id, found.datum); this.hoverDevice = "pointer"; return; } this.chart.ctx.highlightManager.updateHighlight(this.id); } handleHoverTooltip(event, redisplay) { if (!this.isState(41 /* Clickable */)) return; const { currentX, currentY } = event; const canvasX = currentX + (this.hoverRect?.x ?? 0); const canvasY = currentY + (this.hoverRect?.y ?? 0); const targetElement = event.sourceEvent.target; if (redisplay ? this.chart.ctx.animationManager.isActive() : !this.hoverRect?.containsPoint(canvasX, canvasY)) { if (this.hoverDevice == "pointer") this.clearTooltip(); return; } if (targetElement && this.chart.tooltip.interactive && this.chart.ctx.domManager.isManagedChildDOMElement(targetElement, "canvas-overlay", DEFAULT_TOOLTIP_CLASS)) { return; } const pick = this.pickNode({ x: event.currentX, y: event.currentY }, "tooltip"); if (!pick) { if (this.hoverDevice == "pointer") this.clearTooltip(); return; } this.hoverDevice = "pointer"; const content = pick.series.getTooltipContent(pick.datum); const tooltipEnabled = this.chart.tooltip.enabled && pick.series.tooltipEnabled; const shouldUpdateTooltip = tooltipEnabled && content != null; if (shouldUpdateTooltip) { const meta = TooltipManager.makeTooltipMeta( { type: "pointermove", canvasX, canvasY }, pick.series, pick.datum ); this.chart.ctx.tooltipManager.updateTooltip(this.id, meta, content); } else { this.chart.ctx.tooltipManager.removeTooltip(this.id); } } changeHighlightDatum(event) { const seriesToUpdate = /* @__PURE__ */ new Set(); const { series: newSeries = void 0, datum: newDatum } = event.currentHighlight ?? {}; const { series: lastSeries = void 0, datum: lastDatum } = event.previousHighlight ?? {}; if (lastSeries) { seriesToUpdate.add(lastSeries); } if (newSeries) { seriesToUpdate.add(newSeries); } if (lastSeries?.properties.cursor && lastDatum) { this.chart.ctx.domManager.updateCursor(lastSeries.id); } if (newSeries?.properties.cursor && newSeries?.properties.cursor !== "default" && newDatum) { this.chart.ctx.domManager.updateCursor(newSeries.id, newSeries.properties.cursor); } const updateAll = newSeries == null || lastSeries == null; if (updateAll) { this.update(4 /* SERIES_UPDATE */); } else { this.update(4 /* SERIES_UPDATE */, { seriesToUpdate }); } } pickNode(point, intent, exactMatchOnly) { const reverseSeries = [...this.series].reverse(); let result; for (const series of reverseSeries) { if (!series.visible || !series.contentGroup.visible) { continue; } const { match, distance: distance2 } = series.pickNode(point, intent, exactMatchOnly) ?? {}; if (!match || distance2 == null) { continue; } if (!result || result.distance > distance2) { result = { series, distance: distance2, datum: match }; } if (distance2 === 0) { break; } } return result; } }; } }); // packages/ag-charts-community/src/chart/series/seriesLayerManager.ts var SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION, SeriesLayerManager; var init_seriesLayerManager = __esm({ "packages/ag-charts-community/src/chart/series/seriesLayerManager.ts"() { "use strict"; init_group(); init_zIndex(); init_number(); SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION = 30; SeriesLayerManager = class { constructor(seriesRoot) { this.seriesRoot = seriesRoot; this.groups = /* @__PURE__ */ new Map(); this.series = /* @__PURE__ */ new Map(); this.expectedSeriesCount = 1; this.mode = "normal"; } setSeriesCount(count) { this.expectedSeriesCount = count; } requestGroup(seriesConfig) { const { internalId, type, contentGroup: seriesContentGroup, seriesGrouping } = seriesConfig; const { groupIndex = internalId } = seriesGrouping ?? {}; const seriesInfo = this.series.get(internalId); if (seriesInfo != null) { throw new Error(`AG Charts - series already has an allocated layer: ${JSON.stringify(seriesInfo)}`); } if (this.series.size === 0) { this.mode = this.expectedSeriesCount >= SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION ? "aggressive-grouping" : "normal"; } let group = this.groups.get(type); if (group == null) { group = /* @__PURE__ */ new Map(); this.groups.set(type, group); } const lookupIndex = this.lookupIdx(groupIndex); let groupInfo = group.get(lookupIndex); if (groupInfo == null) { groupInfo = { type, id: lookupIndex, seriesIds: [], group: this.seriesRoot.appendChild( new Group({ name: `${seriesConfig.contentGroup.name ?? type}-managed-layer`, zIndex: seriesConfig.contentGroup.zIndex, // Set in updateLayerCompositing renderToOffscreenCanvas: false }) ) }; group.set(lookupIndex, groupInfo); } this.series.set(internalId, { layerState: groupInfo, seriesConfig }); groupInfo.seriesIds.push(internalId); groupInfo.group.appendChild(seriesContentGroup); return groupInfo.group; } changeGroup(seriesConfig) { const { internalId, seriesGrouping, type, contentGroup, oldGrouping } = seriesConfig; const { groupIndex = internalId } = seriesGrouping ?? {}; if (this.groups.get(type)?.get(groupIndex)?.seriesIds.includes(internalId)) { return; } if (this.series.has(internalId)) { this.releaseGroup({ internalId, seriesGrouping: oldGrouping, type, contentGroup }); } this.requestGroup(seriesConfig); } releaseGroup(seriesConfig) { const { internalId, contentGroup, type } = seriesConfig; if (!this.series.has(internalId)) { throw new Error(`AG Charts - series doesn't have an allocated layer: ${internalId}`); } const groupInfo = this.series.get(internalId)?.layerState; if (groupInfo) { groupInfo.seriesIds = groupInfo.seriesIds.filter((v) => v !== internalId); groupInfo.group.removeChild(contentGroup); } if (groupInfo?.seriesIds.length === 0) { this.seriesRoot.removeChild(groupInfo.group); this.groups.get(groupInfo.type)?.delete(groupInfo.id); this.groups.get(type)?.delete(internalId); } else if (groupInfo != null && groupInfo.seriesIds.length > 0) { groupInfo.group.zIndex = this.getLowestSeriesZIndex(groupInfo.seriesIds); } this.series.delete(internalId); } updateLayerCompositing() { this.groups.forEach((groups) => { groups.forEach((groupInfo) => { const { group, seriesIds } = groupInfo; let renderToOffscreenCanvas; if (seriesIds.length === 0) { renderToOffscreenCanvas = false; } else if (seriesIds.length > 1) { renderToOffscreenCanvas = true; } else { const series = this.series.get(seriesIds[0]); renderToOffscreenCanvas = series?.seriesConfig.renderToOffscreenCanvas() === true; } group.renderToOffscreenCanvas = renderToOffscreenCanvas; group.zIndex = this.getLowestSeriesZIndex(seriesIds); }); }); } lookupIdx(groupIndex) { if (this.mode === "normal") { return groupIndex; } if (typeof groupIndex === "string") { groupIndex = Number(groupIndex.split("-").at(-1)); if (!groupIndex) { return 0; } } return Math.floor( clamp(0, groupIndex / this.expectedSeriesCount, 1) * SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION ); } destroy() { this.groups.forEach((groups) => { groups.forEach((groupInfo) => { this.seriesRoot.removeChild(groupInfo.group); }); }); this.groups.clear(); this.series.clear(); } getLowestSeriesZIndex(seriesIds) { const lowestSeriesZIndex = seriesIds.reduce((currentLowest, seriesId) => { const series = this.series.get(seriesId); const zIndex = series?.seriesConfig.contentGroup.zIndex; if (currentLowest == null || zIndex == null) return zIndex; return compareZIndex(currentLowest, zIndex) <= 0 ? currentLowest : zIndex; }, void 0); return lowestSeriesZIndex ?? 1 /* ANY_CONTENT */; } }; } }); // packages/ag-charts-community/src/chart/touch.ts var Touch; var init_touch = __esm({ "packages/ag-charts-community/src/chart/touch.ts"() { "use strict"; init_properties(); init_validation2(); Touch = class extends BaseProperties { constructor() { super(...arguments); this.dragAction = "drag"; } }; __decorateClass([ Validate(UNION(["none", "drag", "hover"])) ], Touch.prototype, "dragAction", 2); } }); // packages/ag-charts-community/src/chart/update/dataWindowProcessor.ts var DataWindowProcessor; var init_dataWindowProcessor = __esm({ "packages/ag-charts-community/src/chart/update/dataWindowProcessor.ts"() { "use strict"; DataWindowProcessor = class { constructor(chart, dataService, updateService, zoomManager, animationManager) { this.chart = chart; this.dataService = dataService; this.updateService = updateService; this.zoomManager = zoomManager; this.animationManager = animationManager; this.dirtyZoom = false; this.dirtyDataSource = false; this.lastAxisZooms = /* @__PURE__ */ new Map(); this.destroyFns = []; this.destroyFns.push( this.dataService.addListener("data-source-change", () => this.onDataSourceChange()), this.dataService.addListener("data-load", () => this.onDataLoad()), this.dataService.addListener("data-error", () => this.onDataError()), this.updateService.addListener("update-complete", () => this.onUpdateComplete()), this.zoomManager.addListener("zoom-change", () => this.onZoomChange()) ); } destroy() { this.destroyFns.forEach((cb) => cb()); } onDataLoad() { this.animationManager.skip(); this.updateService.update(1 /* UPDATE_DATA */); } onDataError() { this.updateService.update(3 /* PERFORM_LAYOUT */); } onDataSourceChange() { this.dirtyDataSource = true; } onUpdateComplete() { if (!this.dirtyZoom && !this.dirtyDataSource) return; this.updateWindow(); } onZoomChange() { this.dirtyZoom = true; } updateWindow() { if (!this.dataService.isLazy()) return; const axis = this.getValidAxis(); let window2; let shouldRefresh = true; if (axis) { const zoom = this.zoomManager.getAxisZoom(axis.id); window2 = this.getAxisWindow(axis, zoom); shouldRefresh = this.shouldRefresh(axis, zoom); } this.dirtyZoom = false; this.dirtyDataSource = false; if (!shouldRefresh) return; this.dataService.load({ windowStart: window2?.min, windowEnd: window2?.max }); } getValidAxis() { return this.chart.axes.find((axis) => axis.type === "time"); } shouldRefresh(axis, zoom) { if (this.dirtyDataSource) return true; if (!this.dirtyZoom) return false; const lastZoom = this.lastAxisZooms.get(axis.id); if (lastZoom && zoom.min === lastZoom.min && zoom.max === lastZoom.max) { return false; } this.lastAxisZooms.set(axis.id, zoom); return true; } getAxisWindow(axis, zoom) { const { domain } = axis.scale; if (!zoom || domain.length === 0 || isNaN(Number(domain[0]))) return; const diff8 = Number(domain[1]) - Number(domain[0]); const min = new Date(Number(domain[0]) + diff8 * zoom.min); const max = new Date(Number(domain[0]) + diff8 * zoom.max); return { min, max }; } }; } }); // packages/ag-charts-community/src/util/browser.ts function isUnsupportedBrowser() { const { userAgent } = getWindow("navigator"); if (isSafariRegexp.test(userAgent)) { const version = parseFloat(safariVersionRegexp.exec(userAgent)?.[1] ?? "0"); const supported = Math.floor(version) > 16; if (!supported) { logger_exports.warnOnce(`Unsupported Safari version: ${version}; ${userAgent}`); } return !supported; } else if (isChromeRegexp.test(userAgent) && !isEdge.test(userAgent) && !isOpera.test(userAgent)) { const version = parseInt(chromeVersionRegexp.exec(userAgent)?.[1] ?? "0", 10); const supported = version > 126; if (!supported) { logger_exports.warnOnce(`Unsupported Chrome version: ${version}; ${userAgent}`); } return !supported; } return false; } var isSafariRegexp, safariVersionRegexp, isChromeRegexp, chromeVersionRegexp, isEdge, isOpera; var init_browser = __esm({ "packages/ag-charts-community/src/util/browser.ts"() { "use strict"; init_main(); init_core(); isSafariRegexp = /^((?!chrome|android).)*safari/i; safariVersionRegexp = /Version\/(\d+(\.\d+)?)/; isChromeRegexp = /Chrome/; chromeVersionRegexp = /Chrome\/(\d+)/; isEdge = /Edg/; isOpera = /OPR/; } }); // packages/ag-charts-community/src/chart/update/overlaysProcessor.ts var visibleIgnoredSeries, OverlaysProcessor; var init_overlaysProcessor = __esm({ "packages/ag-charts-community/src/chart/update/overlaysProcessor.ts"() { "use strict"; init_attributeUtil(); init_browser(); init_overlay(); visibleIgnoredSeries = /* @__PURE__ */ new Set(["map-shape-background", "map-line-background"]); OverlaysProcessor = class { constructor(chartLike, overlays, dataService, layoutManager, localeManager, animationManager, domManager) { this.chartLike = chartLike; this.overlays = overlays; this.dataService = dataService; this.layoutManager = layoutManager; this.localeManager = localeManager; this.animationManager = animationManager; this.domManager = domManager; this.destroyFns = []; this.overlayElem = this.domManager.addChild("canvas-overlay", "overlay"); this.overlayElem.role = "status"; this.overlayElem.ariaAtomic = "false"; this.overlayElem.ariaLive = "polite"; this.overlayElem.classList.toggle(DEFAULT_OVERLAY_CLASS); this.destroyFns.push(this.layoutManager.addListener("layout:complete", (e) => this.onLayoutComplete(e))); } destroy() { this.destroyFns.forEach((cb) => cb()); this.domManager.removeStyles("overlays"); this.domManager.removeChild("canvas-overlay", "overlay"); } onLayoutComplete({ series: { rect } }) { const isLoading = this.dataService.isLoading(); const hasData = this.chartLike.series.some((s) => s.hasData); const anySeriesVisible = this.chartLike.series.some((s) => s.visible && !visibleIgnoredSeries.has(s.type)); if (this.overlays.darkTheme) { this.overlayElem.classList.add(DEFAULT_OVERLAY_DARK_CLASS); } else { this.overlayElem.classList.remove(DEFAULT_OVERLAY_DARK_CLASS); } this.overlayElem.style.left = `${rect.x}px`; this.overlayElem.style.top = `${rect.y}px`; this.overlayElem.style.width = `${rect.width}px`; this.overlayElem.style.height = `${rect.height}px`; const loadingShown = isLoading; const noDataShown = !isLoading && !hasData; const noVisibleSeriesShown = hasData && !anySeriesVisible; const unsupportedBrowser = this.overlays.unsupportedBrowser.enabled && isUnsupportedBrowser(); if (loadingShown) { this.showOverlay(this.overlays.loading, rect); } else { this.hideOverlay(this.overlays.loading); } if (noDataShown) { this.showOverlay(this.overlays.noData, rect); } else { this.hideOverlay(this.overlays.noData); } if (noVisibleSeriesShown) { this.showOverlay(this.overlays.noVisibleSeries, rect); } else { this.hideOverlay(this.overlays.noVisibleSeries); } if (unsupportedBrowser) { this.showOverlay(this.overlays.unsupportedBrowser, rect); } else { this.hideOverlay(this.overlays.unsupportedBrowser); } const shown = loadingShown || noDataShown || noVisibleSeriesShown || unsupportedBrowser; setAttribute(this.overlayElem, "aria-hidden", !shown); } showOverlay(overlay, seriesRect) { if (!overlay.enabled) return; const element2 = overlay.getElement(this.animationManager, this.localeManager, seriesRect); this.overlayElem.appendChild(element2); } hideOverlay(overlay) { overlay.removeElement(() => { this.overlayElem.innerText = "\xA0"; }, this.animationManager); } }; } }); // packages/ag-charts-community/src/chart/chart.ts var debug, SeriesArea, _Chart, Chart; var init_chart = __esm({ "packages/ag-charts-community/src/chart/chart.ts"() { "use strict"; init_main(); init_module(); init_group(); init_async(); init_debug(); init_dom(); init_id(); init_json(); init_mutex(); init_object(); init_observable(); init_padding(); init_properties(); init_proxy(); init_render(); init_validation2(); init_widget(); init_chartCaptions(); init_chartContext(); init_chartHighlight(); init_chartUpdateType(); init_dataController(); init_axisRegistry(); init_expectedEnterpriseModules(); init_legendRegistry(); init_seriesRegistry(); init_syncManager(); init_keyboard(); init_prepareAxis(); init_prepareSeries(); init_types(); init_modulesManager(); init_chartOverlays(); init_loadingSpinner(); init_series(); init_seriesAreaManager(); init_seriesLayerManager(); init_tooltip(); init_touch(); init_dataWindowProcessor(); init_overlaysProcessor(); debug = Debug.create(true, "opts"); SeriesArea = class extends BaseProperties { constructor() { super(...arguments); this.padding = new Padding(0); } }; __decorateClass([ Validate(BOOLEAN, { optional: true }) ], SeriesArea.prototype, "clip", 2); __decorateClass([ Validate(OBJECT) ], SeriesArea.prototype, "padding", 2); _Chart = class _Chart extends Observable { constructor(options, resources) { var _a; super(); this.id = createId(this); this.seriesRoot = new TranslatableGroup({ name: `${this.id}-series-root`, zIndex: 5 /* SERIES_LAYER */ }); this.annotationRoot = new TranslatableGroup({ name: `${this.id}-annotation-root`, zIndex: 9 /* SERIES_ANNOTATION */ }); this.titleGroup = new Group({ name: "titles", zIndex: 13 /* SERIES_LABEL */ }); this.debug = Debug.create(); this.extraDebugStats = {}; this.data = []; this._firstAutoSize = true; this._autoSizeNotify = new AsyncAwaitQueue(); this.padding = new Padding(20); this.seriesArea = new SeriesArea(); this.keyboard = new Keyboard(); this.touch = new Touch(); this.mode = "standalone"; this.chartCaptions = new ChartCaptions(); this.suppressFieldDotNotation = false; this.destroyed = false; this._destroyFns = []; // Used to prevent infinite update loops when syncing charts. this.skipSync = false; this.chartAnimationPhase = "initial"; this.modulesManager = new ModulesManager(); this.processors = []; this.queuedUserOptions = []; this.queuedChartOptions = []; this.firstApply = true; this._pendingFactoryUpdatesCount = 0; this._performUpdateSkipAnimations = false; this._performUpdateNotify = new AsyncAwaitQueue(); this.performUpdateType = 7 /* NONE */; this.runningUpdateType = 7 /* NONE */; this.updateShortcutCount = 0; this.seriesToUpdate = /* @__PURE__ */ new Set(); this.updateMutex = new Mutex(); this.updateRequestors = {}; this.performUpdateTrigger = debouncedCallback(({ count }) => { if (this.destroyed) return; this.updateMutex.acquire(async () => { try { await this.performUpdate(count); } catch (error3) { logger_exports.error("update error", error3); } }).catch((e) => logger_exports.errorOnce(e)); }); this._performUpdateSplits = {}; this.axes = []; this.series = []; this._cachedData = void 0; this.onSeriesNodeClick = (event) => { this.fireEvent({ ...event, type: "seriesNodeClick" }); }; this.onSeriesNodeDoubleClick = (event) => { this.fireEvent({ ...event, type: "seriesNodeDoubleClick" }); }; this.onSeriesVisibilityChange = (event) => { this.fireEvent(event); }; this.seriesGroupingChanged = (event) => { if (!(event instanceof SeriesGroupingChangedEvent)) return; const { series, seriesGrouping, oldGrouping } = event; if (series.contentGroup.isRoot()) return; this.seriesLayerManager.changeGroup({ internalId: series.internalId, type: series.type, contentGroup: series.contentGroup, renderToOffscreenCanvas: () => series.renderToOffscreenCanvas(), seriesGrouping, oldGrouping }); }; this.chartOptions = options; const scene = resources?.scene; const container = resources?.container ?? options.processedOptions.container ?? void 0; const styleContainer = resources?.styleContainer ?? options.specialOverrides.styleContainer; if (scene) { this._firstAutoSize = false; this._lastAutoSize = [scene.width, scene.height, scene.pixelRatio]; } const root = new Group({ name: "root" }); root.visible = false; root.append(this.seriesRoot); root.append(this.annotationRoot); root.append(this.titleGroup); this.titleGroup.append(this.title.node); this.titleGroup.append(this.subtitle.node); this.titleGroup.append(this.footnote.node); this.tooltip = new Tooltip(); this.seriesLayerManager = new SeriesLayerManager(this.seriesRoot); this.mode = options.userOptions.mode ?? this.mode; const ctx = this.ctx = new ChartContext(this, { chartType: this.getChartType(), scene, root, container, styleContainer, syncManager: new SyncManager(this), fireEvent: (event) => this.fireEvent(event), updateCallback: (type, opts) => this.update(type, opts), updateMutex: this.updateMutex }); this._destroyFns.push( ctx.domManager.addListener("resize", () => this.parentResize(ctx.domManager.containerSize)) ); this.overlays = new ChartOverlays(); (_a = this.overlays.loading).renderer ?? (_a.renderer = () => getLoadingSpinner(this.overlays.loading.getText(ctx.localeManager), ctx.animationManager.defaultDuration)); this.processors = [ new DataWindowProcessor(this, ctx.dataService, ctx.updateService, ctx.zoomManager, ctx.animationManager), new OverlaysProcessor( this, this.overlays, ctx.dataService, ctx.layoutManager, ctx.localeManager, ctx.animationManager, ctx.domManager ) ]; this.highlight = new ChartHighlight(); this.container = container; const moduleContext = this.getModuleContext(); ctx.domManager.setDataBoolean("animating", false); this.seriesAreaManager = new SeriesAreaManager(this.initSeriesAreaDependencies()); this._destroyFns.push( ctx.layoutManager.registerElement(0 /* Caption */, (e) => { e.layoutBox.shrink(this.padding.toJson()); this.chartCaptions.positionCaptions(e); }), ctx.layoutManager.addListener("layout:complete", (e) => this.chartCaptions.positionAbsoluteCaptions(e)), ctx.dataService.addListener("data-load", (event) => { this.data = event.data; }), this.title.registerInteraction(moduleContext, "beforebegin"), this.subtitle.registerInteraction(moduleContext, "beforebegin"), this.footnote.registerInteraction(moduleContext, "afterend"), Widget.addWindowEvent("page-left", () => this.destroy()), ctx.animationManager.addListener("animation-frame", () => { this.update(6 /* SCENE_RENDER */); }), ctx.animationManager.addListener("animation-start", () => ctx.domManager.setDataBoolean("animating", true)), ctx.animationManager.addListener("animation-stop", () => ctx.domManager.setDataBoolean("animating", false)), ctx.zoomManager.addListener("zoom-change", () => { this.series.forEach((s) => s.animationState?.transition("updateData")); const skipAnimations = this.chartAnimationPhase !== "initial"; this.update(3 /* PERFORM_LAYOUT */, { forceNodeDataRefresh: true, skipAnimations }); }) ); this.parentResize(ctx.domManager.containerSize); } static getInstance(element2) { return _Chart.chartsInstances.get(element2); } /** NOTE: This is exposed for use by Integrated charts only. */ get canvasElement() { return this.ctx.scene.canvas.element; } download(fileName, fileFormat) { this.ctx.scene.download(fileName, fileFormat); } getCanvasDataURL(fileFormat) { return this.ctx.scene.getDataURL(fileFormat); } toSVG() { return this.ctx.scene.toSVG(); } getOptions() { return this.queuedUserOptions.at(-1) ?? this.chartOptions.userOptions; } getChartOptions() { return this.queuedChartOptions.at(-1) ?? this.chartOptions; } overrideFocusVisible(visible) { this.seriesAreaManager.focusIndicator.overrideFocusVisible(visible); } initSeriesAreaDependencies() { const { ctx, tooltip, highlight, overlays, seriesRoot, mode } = this; const chartType = this.getChartType(); const fireEvent = this.fireEvent.bind(this); const getUpdateType = () => this.performUpdateType; return { fireEvent, getUpdateType, chartType, ctx, tooltip, highlight, overlays, seriesRoot, mode }; } getModuleContext() { return this.ctx; } getCaptionText() { return [this.title, this.subtitle, this.footnote].filter((caption) => caption.enabled && caption.text).map((caption) => caption.text).join(". "); } getAriaLabel() { return this.ctx.localeManager.t("ariaAnnounceChart", { seriesCount: this.series.length }); } resetAnimations() { this.chartAnimationPhase = "initial"; for (const series of this.series) { series.resetAnimation(this.chartAnimationPhase); } for (const axis of this.axes) { axis.resetAnimation(this.chartAnimationPhase); } this.animationRect = void 0; this.ctx.animationManager.reset(); } skipAnimations() { this.ctx.animationManager.skipCurrentBatch(); this._performUpdateSkipAnimations = true; } detachAndClear() { this.container = void 0; this.ctx.scene.clear(); } destroy(opts) { if (this.destroyed) { return; } const keepTransferableResources = opts?.keepTransferableResources; let result; this.performUpdateType = 7 /* NONE */; this._destroyFns.forEach((fn) => fn()); this.processors.forEach((p) => p.destroy()); this.tooltip.destroy(this.ctx.domManager); this.overlays.destroy(); this.modulesManager.destroy(); if (keepTransferableResources) { this.ctx.scene.strip(); result = { container: this.container, scene: this.ctx.scene }; } else { this.ctx.scene.destroy(); this.container = void 0; } this.destroySeries(this.series); this.seriesLayerManager.destroy(); this.axes.forEach((a) => a.destroy()); this.axes = []; this.animationRect = void 0; this.ctx.destroy(); this.destroyed = true; Object.freeze(this); return result; } requestFactoryUpdate(cb) { if (this.destroyed) return; this._pendingFactoryUpdatesCount++; this.updateMutex.acquire(async () => { if (this.destroyed) return; try { await cb(this); } finally { if (!this.destroyed) { this._pendingFactoryUpdatesCount--; } } }).catch((e) => logger_exports.errorOnce(e)); } update(type = 0 /* FULL */, opts) { if (this.destroyed) return; const { forceNodeDataRefresh = false, skipAnimations, seriesToUpdate = this.series, newAnimationBatch } = opts ?? {}; this.ctx.widgets.seriesWidget.setDragTouchEnabled(this.touch.dragAction !== "none"); if (forceNodeDataRefresh) { this.series.forEach((series) => series.markNodeDataDirty()); } for (const series of seriesToUpdate) { this.seriesToUpdate.add(series); } if (skipAnimations) { this.ctx.animationManager.skipCurrentBatch(); this._performUpdateSkipAnimations = true; } if (newAnimationBatch && this.ctx.animationManager.isActive()) { this._performUpdateSkipAnimations = true; } this.skipSync = opts?.skipSync ?? false; if (this.debug.check()) { let stack = new Error().stack ?? ""; stack = stack.replace(/\([^)]*/g, ""); this.updateRequestors[stack] = type; } if (type < this.performUpdateType) { this.performUpdateType = type; this.ctx.domManager.setDataBoolean("updatePending", true); this.performUpdateTrigger.schedule(opts?.backOffMs); } } async performUpdate(count) { const { performUpdateType, extraDebugStats, _performUpdateSplits: splits, ctx } = this; const seriesToUpdate = [...this.seriesToUpdate]; this.performUpdateType = 7 /* NONE */; this.seriesToUpdate.clear(); this.runningUpdateType = performUpdateType; if (this.updateShortcutCount === 0 && performUpdateType < 6 /* SCENE_RENDER */) { ctx.animationManager.startBatch(this._performUpdateSkipAnimations); ctx.animationManager.onBatchStop(() => this.chartAnimationPhase = "ready"); } this.debug("Chart.performUpdate() - start", ChartUpdateType[performUpdateType]); let previousSplit = performance.now(); splits.start ?? (splits.start = previousSplit); const updateSplits = (splitName) => { splits[splitName] ?? (splits[splitName] = 0); splits[splitName] += performance.now() - previousSplit; previousSplit = performance.now(); }; switch (performUpdateType) { case 0 /* FULL */: if (this.checkUpdateShortcut(0 /* FULL */)) break; this.ctx.updateService.dispatchPreDomUpdate(); this.updateDOM(); case 1 /* UPDATE_DATA */: if (this.checkUpdateShortcut(1 /* UPDATE_DATA */)) break; await this.updateData(); updateSplits("\u2B07\uFE0F"); case 2 /* PROCESS_DATA */: if (this.checkUpdateShortcut(2 /* PROCESS_DATA */)) break; await this.processData(); this.seriesAreaManager.dataChanged(); updateSplits("\u{1F3ED}"); case 3 /* PERFORM_LAYOUT */: await this.checkFirstAutoSize(); if (this.checkUpdateShortcut(3 /* PERFORM_LAYOUT */)) break; await this.processLayout(); updateSplits("\u2316"); case 4 /* SERIES_UPDATE */: { if (this.checkUpdateShortcut(4 /* SERIES_UPDATE */)) break; await this.updateSeries(seriesToUpdate); updateSplits("\u{1F914}"); this.updateAriaLabels(); this.seriesLayerManager.updateLayerCompositing(); } case 5 /* PRE_SCENE_RENDER */: if (this.checkUpdateShortcut(5 /* PRE_SCENE_RENDER */)) break; ctx.updateService.dispatchPreSceneRender(); updateSplits("\u2196"); case 6 /* SCENE_RENDER */: if (this.checkUpdateShortcut(6 /* SCENE_RENDER */)) break; ctx.animationManager.endBatch(); extraDebugStats["updateShortcutCount"] = this.updateShortcutCount; ctx.scene.render({ debugSplitTimes: splits, extraDebugStats, seriesRect: this.seriesRect }); this.extraDebugStats = {}; for (const key of Object.keys(splits)) { delete splits[key]; } this.ctx.domManager.incrementDataCounter("sceneRenders"); case 7 /* NONE */: this.updateShortcutCount = 0; this.updateRequestors = {}; this._performUpdateSkipAnimations = false; ctx.animationManager.endBatch(); } if (!this.destroyed) { ctx.updateService.dispatchUpdateComplete(); this.ctx.domManager.setDataBoolean("updatePending", false); this.runningUpdateType = 7 /* NONE */; } this._performUpdateNotify.notify(); const end2 = performance.now(); this.debug("Chart.performUpdate() - end", { chart: this, durationMs: Math.round((end2 - splits["start"]) * 100) / 100, count, performUpdateType: ChartUpdateType[performUpdateType] }); } updateThemeClassName() { const themeClassNamePrefix = "ag-charts-theme-"; const validThemeClassNames = [`${themeClassNamePrefix}default`, `${themeClassNamePrefix}default-dark`]; let themeClassName = validThemeClassNames[0]; let isDark = false; let { theme } = this.chartOptions.processedOptions; while (typeof theme !== "string" && theme != null) { theme = theme.baseTheme; } if (typeof theme === "string") { themeClassName = theme.replace("ag-", themeClassNamePrefix); isDark = theme.includes("-dark"); } if (!validThemeClassNames.includes(themeClassName)) { themeClassName = isDark ? validThemeClassNames[1] : validThemeClassNames[0]; } this.ctx.domManager.setThemeClass(themeClassName); } updateDOM() { this.updateThemeClassName(); const { enabled, tabIndex } = this.keyboard; this.ctx.domManager.setTabGuardIndex(enabled ? tabIndex ?? 0 : -1); this.ctx.domManager.setThemeParameters(this.chartOptions.themeParameters); } updateAriaLabels() { this.ctx.domManager.updateCanvasLabel(this.getAriaLabel()); } checkUpdateShortcut(checkUpdateType) { const maxShortcuts = 3; if (this.destroyed) return true; if (this.updateShortcutCount > maxShortcuts) { logger_exports.warn( `exceeded the maximum number of simultaneous updates (${maxShortcuts + 1}), discarding changes and rendering`, this.updateRequestors ); return false; } if (this.performUpdateType <= checkUpdateType) { this.updateShortcutCount++; return true; } return false; } async checkFirstAutoSize() { if (this.width != null && this.height != null) { } else if (!this._lastAutoSize) { const success = await this._autoSizeNotify.await(500); if (!success) { this.debug("Chart.checkFirstAutoSize() - timeout for first size update."); } } } onAxisChange(newValue, oldValue) { if (oldValue == null && newValue.length === 0) return; this.ctx.axisManager.updateAxes(oldValue ?? [], newValue); } onSeriesChange(newValue, oldValue) { const seriesToDestroy = oldValue?.filter((series) => !newValue.includes(series)) ?? []; this.destroySeries(seriesToDestroy); this.seriesLayerManager?.setSeriesCount(newValue.length); for (const series of newValue) { if (oldValue?.includes(series)) continue; const seriesContentNode = this.seriesLayerManager.requestGroup(series); series.attachSeries(seriesContentNode, this.seriesRoot, this.annotationRoot); const chart = this; series.chart = { get mode() { return chart.mode; }, get isMiniChart() { return false; }, get seriesRect() { return chart.seriesRect; } }; series.resetAnimation(this.chartAnimationPhase); this.addSeriesListeners(series); series.addChartEventListeners(); } this.seriesAreaManager?.seriesChanged(newValue); } destroySeries(allSeries) { allSeries?.forEach((series) => { series.removeEventListener("nodeClick", this.onSeriesNodeClick); series.removeEventListener("nodeDoubleClick", this.onSeriesNodeDoubleClick); series.removeEventListener("groupingChanged", this.seriesGroupingChanged); series.destroy(); this.seriesLayerManager.releaseGroup(series); series.detachSeries(void 0, this.seriesRoot, this.annotationRoot); series.chart = void 0; }); } addSeriesListeners(series) { if (this.hasEventListener("seriesNodeClick")) { series.addEventListener("nodeClick", this.onSeriesNodeClick); } if (this.hasEventListener("seriesNodeDoubleClick")) { series.addEventListener("nodeDoubleClick", this.onSeriesNodeDoubleClick); } if (this.hasEventListener("seriesVisibilityChange")) { series.addEventListener("seriesVisibilityChange", this.onSeriesVisibilityChange); } series.addEventListener("groupingChanged", this.seriesGroupingChanged); } assignSeriesToAxes() { for (const axis of this.axes) { axis.boundSeries = this.series.filter((s) => s.axes[axis.direction] === axis); } } assignAxesToSeries() { const directionToAxesMap = groupBy(this.axes, (axis) => axis.direction); for (const series of this.series) { for (const direction of series.directions) { const directionAxes = directionToAxesMap[direction]; if (!directionAxes) { logger_exports.warnOnce( `no available axis for direction [${direction}]; check series and axes configuration.` ); return; } const seriesKeys = series.getKeys(direction); const newAxis = directionAxes.find( (axis) => !axis.keys.length || seriesKeys.some((key) => axis.keys.includes(key)) ); if (!newAxis) { logger_exports.warnOnce( `no matching axis for direction [${direction}] and keys [${seriesKeys}]; check series and axes configuration.` ); return; } series.axes[direction] = newAxis; } } } parentResize(size) { if (size == null || this.width != null && this.height != null) return; let { width: width2, height: height2 } = size; const { pixelRatio } = size; width2 = Math.floor(width2); height2 = Math.floor(height2); if (width2 === 0 && height2 === 0) return; const [autoWidth = 0, autoHeight = 0, autoPixelRatio = 1] = this._lastAutoSize ?? []; if (autoWidth === width2 && autoHeight === height2 && autoPixelRatio === pixelRatio) return; this._lastAutoSize = [width2, height2, pixelRatio]; this.resize("SizeMonitor", {}); } resize(source, opts) { const { scene, animationManager } = this.ctx; const { inWidth, inHeight, inMinWidth, inMinHeight, inOverrideDevicePixelRatio } = opts; this.ctx.domManager.setSizeOptions( inMinWidth ?? this.minWidth, inMinHeight ?? this.minHeight, inWidth ?? this.width, inHeight ?? this.height ); const width2 = inWidth ?? this.width ?? this._lastAutoSize?.[0]; const height2 = inHeight ?? this.height ?? this._lastAutoSize?.[1]; const pixelRatio = inOverrideDevicePixelRatio ?? this.overrideDevicePixelRatio ?? this._lastAutoSize?.[2]; this.debug(`Chart.resize() from ${source}`, { width: width2, height: height2, pixelRatio, stack: new Error().stack }); if (width2 == null || height2 == null || !isFiniteNumber(width2) || !isFiniteNumber(height2)) return; if (scene.resize(width2, height2, pixelRatio)) { animationManager.reset(); let skipAnimations = true; if ((this.width == null || this.height == null) && this._firstAutoSize) { skipAnimations = false; this._firstAutoSize = false; } this.update(3 /* PERFORM_LAYOUT */, { forceNodeDataRefresh: true, skipAnimations }); this._autoSizeNotify.notify(); } } async updateData() { this.series.forEach((s) => s.setChartData(this.data)); const modulePromises = this.modulesManager.mapModules((m) => m.updateData?.(this.data)); await Promise.all(modulePromises); } async processData() { if (this.series.some((s) => s.canHaveAxes)) { this.assignAxesToSeries(); this.assignSeriesToAxes(); } const dataController = new DataController(this.mode, this.suppressFieldDotNotation); const seriesPromises = this.series.map((s) => { s.resetDatumCallbackCache(); return s.processData(dataController); }); const modulePromises = this.modulesManager.mapModules((m) => m.processData?.(dataController)); this._cachedData = dataController.execute(this._cachedData); await Promise.all([...seriesPromises, ...modulePromises]); for (const axis of this.axes) { axis.processData(); } this.updateLegends(); } updateLegends(initialStateLegend) { for (const { legend, legendType } of this.modulesManager.legends()) { if (legendType === "category") { this.setCategoryLegendData(initialStateLegend); } else { this.setLegendData(legendType, legend); } } } setCategoryLegendData(initialState) { var _a; const { ctx: { legendManager, stateManager } } = this; if (initialState) { this.series.forEach((s) => { const seriesState = initialState.find((init) => init.seriesId === s.id); s.onLegendInitialState("category", seriesState); }); } const legendData = this.series.flatMap((s) => { const seriesLegendData = s.getLegendData("category"); legendManager.updateData(s.id, seriesLegendData); return seriesLegendData; }); if (initialState) { stateManager.setStateAndRestore(legendManager, initialState); return; } if (this.mode !== "integrated") { const seriesMarkerFills = {}; const seriesTypeMap = new Map(this.series.map((s) => [s.id, s.type])); for (const { seriesId, symbol: { marker }, label } of legendData.filter((d) => !d.hideInLegend)) { if (marker.fill == null) continue; const seriesType = seriesTypeMap.get(seriesId); const markerFill = seriesMarkerFills[seriesType] ?? (seriesMarkerFills[seriesType] = {}); markerFill[_a = label.text] ?? (markerFill[_a] = marker.fill); if (markerFill[label.text] !== marker.fill) { logger_exports.warnOnce( `legend item '${label.text}' has multiple fill colors, this may cause unexpected behaviour.` ); } } } legendManager.update(); } setLegendData(legendType, legend) { legend.data = this.series.filter((s) => s.properties.showInLegend).flatMap((s) => s.getLegendData(legendType)); } async processLayout() { const oldRect = this.animationRect; const { width: width2, height: height2 } = this.ctx.scene; const ctx = this.ctx.layoutManager.createContext(width2, height2); await this.performLayout(ctx); if (oldRect && !this.animationRect?.equals(oldRect)) { this.ctx.animationManager.skipCurrentBatch(); } this.debug("Chart.performUpdate() - seriesRect", this.seriesRect); } async updateSeries(seriesToUpdate) { const { seriesRect } = this; await Promise.all(seriesToUpdate.map((series) => series.update({ seriesRect }))); this.ctx.seriesLabelLayoutManager.updateLabels( this.series.filter((s) => s.visible && s.usesPlacedLabels), this.padding, this.seriesRect ); } async waitForUpdate(timeoutMs = 1e4, failOnTimeout = false) { const start2 = performance.now(); while (this._pendingFactoryUpdatesCount > 0 || this.performUpdateType !== 7 /* NONE */ || this.runningUpdateType !== 7 /* NONE */) { if (this.destroyed) break; if (this._pendingFactoryUpdatesCount > 0) { await this.updateMutex.waitForClearAcquireQueue(); } if (this.performUpdateType !== 7 /* NONE */ || this.runningUpdateType !== 7 /* NONE */) { await this._performUpdateNotify.await(); } if (performance.now() - start2 > timeoutMs) { const message = `Chart.waitForUpdate() timeout of ${timeoutMs} reached - first chart update taking too long.`; if (failOnTimeout) { throw new Error(message); } else { logger_exports.warnOnce(message); } } if (isInputPending()) { await pause(); } } } filterMiniChartSeries(series) { return series?.filter((s) => s.showInMiniChart !== false); } applyOptions(newChartOptions) { const deltaOptions = this.firstApply ? newChartOptions.processedOptions : newChartOptions.diffOptions(this.chartOptions); if (deltaOptions == null || Object.keys(deltaOptions).length === 0) return; const oldOpts = this.firstApply ? {} : this.chartOptions.processedOptions; const newOpts = newChartOptions.processedOptions; debug("Chart.applyOptions() - applying delta", deltaOptions); const modulesChanged = this.applyModules(newOpts); const skip = [ "type", "data", "series", "listeners", "preset", "theme", "legend.listeners", "navigator.miniChart.series", "navigator.miniChart.label", "locale.localeText", "axes", "topology", "nodes", "initialState", "styleContainer" ]; if (deltaOptions.listeners) { this.registerListeners(this, deltaOptions.listeners); } jsonApply(this, deltaOptions, { skip }); let forceNodeDataRefresh = false; let seriesStatus = "no-op"; if (deltaOptions.series != null) { seriesStatus = this.applySeries(this, deltaOptions.series, oldOpts?.series); forceNodeDataRefresh = true; } if (seriesStatus === "replaced") { this.resetAnimations(); } if (this.applyAxes(this, newOpts, oldOpts, seriesStatus, [])) { forceNodeDataRefresh = true; } if (deltaOptions.data) { this.data = deltaOptions.data; } if (deltaOptions.legend?.listeners && this.modulesManager.isEnabled("legend")) { Object.assign(this.legend.listeners, deltaOptions.legend.listeners); } if (deltaOptions.locale?.localeText) { this.modulesManager.getModule("locale").localeText = deltaOptions.locale?.localeText; } this.chartOptions = newChartOptions; const navigatorModule = this.modulesManager.getModule("navigator"); const zoomModule = this.modulesManager.getModule("zoom"); if (!navigatorModule?.enabled && !zoomModule?.enabled) { this.ctx.zoomManager.updateZoom("chart"); } const miniChart = navigatorModule?.miniChart; const miniChartSeries = newOpts.navigator?.miniChart?.series ?? newOpts.series; if (miniChart?.enabled === true && miniChartSeries != null) { this.applyMiniChartOptions(miniChart, miniChartSeries, newOpts, oldOpts); } else if (miniChart?.enabled === false) { miniChart.series = []; miniChart.axes = []; } this.ctx.annotationManager.setAnnotationStyles(newChartOptions.annotationThemes); forceNodeDataRefresh || (forceNodeDataRefresh = this.shouldForceNodeDataRefresh(deltaOptions, seriesStatus)); const majorChange = forceNodeDataRefresh || modulesChanged; const updateType = majorChange ? 0 /* FULL */ : 3 /* PERFORM_LAYOUT */; this.maybeResetAnimations(seriesStatus); if (this.shouldClearLegendData(newOpts, oldOpts, seriesStatus)) { this.ctx.legendManager.clearData(); } this.applyInitialState(newOpts); debug("Chart.applyOptions() - update type", ChartUpdateType[updateType], { seriesStatus, forceNodeDataRefresh }); this.update(updateType, { forceNodeDataRefresh, newAnimationBatch: true }); this.firstApply = false; } applyInitialState(options) { const { annotationManager, chartTypeOriginator, historyManager, stateManager, zoomManager } = this.ctx; const { initialState } = options; if ("annotations" in options && options.annotations?.enabled && initialState?.annotations != null) { const annotations = initialState.annotations.map((annotation) => { const annotationTheme = annotationManager.getAnnotationTypeStyles(annotation.type); return mergeDefaults(annotation, annotationTheme); }); stateManager.setState(annotationManager, annotations); } if (initialState?.chartType != null) { stateManager.setState(chartTypeOriginator, initialState.chartType); } if ((options.navigator?.enabled || options.zoom?.enabled) && initialState?.zoom != null) { stateManager.setState(zoomManager, initialState.zoom); } if (initialState?.legend != null) { this.updateLegends(initialState.legend); } if (initialState != null) { historyManager.clear(); } } maybeResetAnimations(seriesStatus) { if (this.mode !== "standalone") return; switch (seriesStatus) { case "series-grouping-change": case "replaced": this.resetAnimations(); break; default: } } shouldForceNodeDataRefresh(deltaOptions, seriesStatus) { const seriesDataUpdate = !!deltaOptions.data || seriesStatus === "data-change" || seriesStatus === "replaced"; const legendKeys = legendRegistry.getKeys(); const optionsHaveLegend = Object.values(legendKeys).some( (legendKey) => deltaOptions[legendKey] != null ); const otherRefreshUpdate = deltaOptions.title != null && deltaOptions.subtitle != null; return seriesDataUpdate || optionsHaveLegend || otherRefreshUpdate; } shouldClearLegendData(options, oldOpts, seriesStatus) { const seriesChanged = seriesStatus === "replaced" || seriesStatus === "series-grouping-change" || seriesStatus === "updated"; const legendRemoved = oldOpts.legend != null && options.legend == null; return seriesChanged || legendRemoved; } applyMiniChartOptions(miniChart, miniChartSeries, completeOptions, oldOpts) { const oldSeries = oldOpts?.navigator?.miniChart?.series ?? oldOpts?.series; const miniChartSeriesStatus = this.applySeries( miniChart, this.filterMiniChartSeries(miniChartSeries), this.filterMiniChartSeries(oldSeries) ); this.applyAxes(miniChart, completeOptions, oldOpts, miniChartSeriesStatus, [ "axes[].tick", "axes[].thickness", "axes[].title", "axes[].crosshair", "axes[].gridLine", "axes[].label" ]); const series = miniChart.series; for (const s of series) { s.properties.id = void 0; } const axes = miniChart.axes; const horizontalAxis = axes.find((axis) => axis.direction === "x" /* X */); for (const axis of axes) { axis.nice = false; axis.gridLine.enabled = false; axis.label.enabled = axis === horizontalAxis; axis.tick.enabled = false; axis.interactionEnabled = false; } if (horizontalAxis != null) { const miniChartOpts = completeOptions.navigator?.miniChart; const labelOptions = miniChartOpts?.label; const intervalOptions = miniChartOpts?.label?.interval; horizontalAxis.line.enabled = false; horizontalAxis.label.set( without(labelOptions, ["interval", "rotation", "minSpacing", "autoRotate", "autoRotateAngle"]) ); horizontalAxis.tick.set( without(intervalOptions, ["enabled", "width", "size", "color", "interval", "step"]) ); if (horizontalAxis.type === "grouped-category") { horizontalAxis.label.enabled = false; horizontalAxis.label.rotation = 0; const { depthOptions } = horizontalAxis; if (depthOptions.length === 0) { depthOptions.set([{ label: { enabled: true } }]); } else { for (let i = 1; i < depthOptions.length; i++) { depthOptions[i].label.enabled = false; } } } const step = intervalOptions?.step; if (step != null) { horizontalAxis.interval.step = step; } } } applyModules(options) { const { type: chartType } = this.constructor; let modulesChanged = false; for (const module2 of moduleRegistry.byType("root", "legend")) { const isConfigured = options[module2.optionsKey] != null; const shouldBeEnabled = isConfigured && module2.chartTypes.includes(chartType); if (shouldBeEnabled === this.modulesManager.isEnabled(module2)) continue; if (shouldBeEnabled) { this.modulesManager.addModule(module2, (m) => m.moduleFactory(this.getModuleContext())); if (module2.type === "legend") { this.modulesManager.getModule(module2)?.attachLegend(this.ctx.scene); } this[module2.optionsKey] = this.modulesManager.getModule(module2); } else { this.modulesManager.removeModule(module2); delete this[module2.optionsKey]; } modulesChanged = true; } return modulesChanged; } initSeriesDeclarationOrder(series) { for (let idx = 0; idx < series.length; idx++) { series[idx].setSeriesIndex(idx); } } applySeries(chart, optSeries, oldOptSeries) { if (!optSeries) { return "no-change"; } const matchResult = matchSeriesOptions(chart.series, optSeries, oldOptSeries); if (matchResult.status === "no-overlap") { debug(`Chart.applySeries() - creating new series instances, status: ${matchResult.status}`, matchResult); const chartSeries = optSeries.map((opts) => this.createSeries(opts)); this.initSeriesDeclarationOrder(chartSeries); chart.series = chartSeries; return "replaced"; } debug(`Chart.applySeries() - matchResult`, matchResult); const seriesInstances = []; let dataChanged = false; let groupingChanged = false; let isUpdated = false; const changes = matchResult.changes.toSorted((a, b) => a.targetIdx - b.targetIdx); for (const change of changes) { groupingChanged || (groupingChanged = change.status === "series-grouping"); dataChanged || (dataChanged = change.diff?.data != null); isUpdated || (isUpdated = change.status !== "no-op"); switch (change.status) { case "add": { const newSeries = this.createSeries(change.opts); seriesInstances.push(newSeries); debug(`Chart.applySeries() - created new series`, newSeries); break; } case "remove": debug(`Chart.applySeries() - removing series at previous idx ${change.idx}`, change.series); break; case "no-op": seriesInstances.push(change.series); debug(`Chart.applySeries() - no change to series at previous idx ${change.idx}`, change.series); break; case "series-grouping": case "update": default: { const { series, diff: diff8, idx } = change; debug(`Chart.applySeries() - applying series diff previous idx ${idx}`, diff8, series); this.applySeriesValues(series, diff8); series.markNodeDataDirty(); seriesInstances.push(series); } } } this.initSeriesDeclarationOrder(seriesInstances); debug(`Chart.applySeries() - final series instances`, seriesInstances); chart.series = seriesInstances; if (groupingChanged) { return "series-grouping-change"; } if (dataChanged) { return "data-change"; } return isUpdated ? "updated" : "no-op"; } applyAxes(chart, options, oldOpts, seriesStatus, skip = []) { if (!("axes" in options) || !options.axes) { return false; } skip = ["axes[].type", ...skip]; const { axes } = options; const forceRecreate = seriesStatus === "replaced"; const matchingTypes = !forceRecreate && chart.axes.length === axes.length && chart.axes.every((a, i) => a.type === axes[i].type); if (matchingTypes && isAgCartesianChartOptions(oldOpts)) { chart.axes.forEach((axis, index) => { const previousOpts = oldOpts.axes?.[index] ?? {}; const axisDiff = jsonDiff(previousOpts, axes[index]); debug(`Chart.applyAxes() - applying axis diff idx ${index}`, axisDiff); const path = `axes[${index}]`; jsonApply(axis, axisDiff, { path, skip }); }); return true; } debug(`Chart.applyAxes() - creating new axes instances; seriesStatus: ${seriesStatus}`); chart.axes = this.createAxis(axes, skip); return true; } createSeries(seriesOptions) { const seriesInstance = seriesRegistry.create(seriesOptions.type, this.getModuleContext()); this.applySeriesOptionModules(seriesInstance, seriesOptions); this.applySeriesValues(seriesInstance, seriesOptions); return seriesInstance; } applySeriesOptionModules(series, options) { const moduleContext = series.createModuleContext(); const moduleMap = series.getModuleMap(); for (const module2 of moduleRegistry.byType("series-option")) { if (module2.optionsKey in options && module2.seriesTypes.includes(series.type)) { moduleMap.addModule(module2, (m) => m.moduleFactory(moduleContext)); } } } applySeriesValues(target, options) { const moduleMap = target.getModuleMap(); const { type: _, data, listeners, seriesGrouping, showInMiniChart: __, ...seriesOptions } = options; for (const moduleDef of EXPECTED_ENTERPRISE_MODULES) { if (moduleDef.type !== "series-option") continue; if (moduleDef.optionsKey in seriesOptions) { const module2 = moduleMap.getModule(moduleDef.optionsKey); if (module2) { const moduleOptions = seriesOptions[moduleDef.optionsKey]; delete seriesOptions[moduleDef.optionsKey]; module2.properties.set(moduleOptions); } } } target.properties.set(seriesOptions); if ("data" in options) { target.setOptionsData(data); } if (listeners) { this.registerListeners(target, listeners); } if ("seriesGrouping" in options) { if (seriesGrouping == null) { target.seriesGrouping = void 0; } else { target.seriesGrouping = { ...target.seriesGrouping, ...seriesGrouping }; } } } createAxis(options, skip) { const newAxes = []; const moduleContext = this.getModuleContext(); for (let index = 0; index < options.length; index++) { const axisOptions = options[index]; const axis = axisRegistry.create(axisOptions.type, moduleContext); this.applyAxisModules(axis, axisOptions); jsonApply(axis, axisOptions, { path: `axes[${index}]`, skip }); newAxes.push(axis); } guessInvalidPositions(newAxes); return newAxes; } applyAxisModules(axis, options) { const moduleContext = axis.createModuleContext(); const moduleMap = axis.getModuleMap(); for (const module2 of moduleRegistry.byType("axis-option")) { const shouldBeEnabled = options[module2.optionsKey] != null; if (shouldBeEnabled === moduleMap.isEnabled(module2)) continue; if (shouldBeEnabled) { moduleMap.addModule(module2, (m) => m.moduleFactory(moduleContext)); axis[module2.optionsKey] = moduleMap.getModule(module2); } else { moduleMap.removeModule(module2); delete axis[module2.optionsKey]; } } } registerListeners(source, listeners) { source.clearEventListeners(); for (const [property, listener] of Object.entries(listeners)) { if (isFunction(listener)) { source.addEventListener(property, listener); } } } }; _Chart.chartsInstances = /* @__PURE__ */ new WeakMap(); __decorateClass([ ActionOnSet({ newValue(value) { if (this.destroyed) return; this.ctx.domManager.setContainer(value); _Chart.chartsInstances.set(value, this); }, oldValue(value) { _Chart.chartsInstances.delete(value); } }) ], _Chart.prototype, "container", 2); __decorateClass([ ActionOnSet({ newValue(value) { this.resize("width option", { inWidth: value }); } }) ], _Chart.prototype, "width", 2); __decorateClass([ ActionOnSet({ newValue(value) { this.resize("height option", { inHeight: value }); } }) ], _Chart.prototype, "height", 2); __decorateClass([ ActionOnSet({ newValue(value) { this.resize("minWidth option", { inMinWidth: value }); } }) ], _Chart.prototype, "minWidth", 2); __decorateClass([ ActionOnSet({ newValue(value) { this.resize("minHeight option", { inMinHeight: value }); } }) ], _Chart.prototype, "minHeight", 2); __decorateClass([ ActionOnSet({ newValue(value) { this.resize("overrideDevicePixelRatio option", { inOverrideDevicePixelRatio: value }); } }) ], _Chart.prototype, "overrideDevicePixelRatio", 2); __decorateClass([ Validate(OBJECT) ], _Chart.prototype, "padding", 2); __decorateClass([ Validate(OBJECT) ], _Chart.prototype, "seriesArea", 2); __decorateClass([ Validate(OBJECT) ], _Chart.prototype, "keyboard", 2); __decorateClass([ Validate(OBJECT) ], _Chart.prototype, "touch", 2); __decorateClass([ Validate(UNION(["standalone", "integrated"], "a chart mode")) ], _Chart.prototype, "mode", 2); __decorateClass([ ProxyProperty("chartCaptions.title") ], _Chart.prototype, "title", 2); __decorateClass([ ProxyProperty("chartCaptions.subtitle") ], _Chart.prototype, "subtitle", 2); __decorateClass([ ProxyProperty("chartCaptions.footnote") ], _Chart.prototype, "footnote", 2); __decorateClass([ Validate(BOOLEAN) ], _Chart.prototype, "suppressFieldDotNotation", 2); __decorateClass([ ActionOnSet({ changeValue(newValue, oldValue) { this.onAxisChange(newValue, oldValue); } }) ], _Chart.prototype, "axes", 2); __decorateClass([ ActionOnSet({ changeValue(newValue, oldValue) { this.onSeriesChange(newValue, oldValue); } }) ], _Chart.prototype, "series", 2); Chart = _Chart; } }); // packages/ag-charts-community/src/scale/logScale.ts function log2(base, domain, x) { const start2 = Math.min(...domain); const fn = logFunctions[base] ?? DEFAULT_LOG; return start2 >= 0 ? fn(base, x) : -fn(base, -x); } function pow(base, domain, x) { const start2 = Math.min(...domain); const fn = powFunctions[base] ?? DEFAULT_POW; return start2 >= 0 ? fn(base, x) : -fn(base, -x); } var logFunctions, DEFAULT_LOG, powFunctions, DEFAULT_POW, LogScale; var init_logScale = __esm({ "packages/ag-charts-community/src/scale/logScale.ts"() { "use strict"; init_number(); init_numberFormat(); init_ticks(); init_continuousScale(); init_scaleUtil(); logFunctions = { 2: (_base, x) => Math.log2(x), [Math.E]: (_base, x) => Math.log(x), 10: (_base, x) => Math.log10(x) }; DEFAULT_LOG = (base, x) => Math.log(x) / Math.log(base); powFunctions = { [Math.E]: (_base, x) => Math.exp(x), 10: (_base, x) => x >= 0 ? 10 ** x : 1 / 10 ** -x }; DEFAULT_POW = (base, x) => base ** x; LogScale = class extends ContinuousScale { constructor(d = [1, 10], r = [0, 1]) { super(d, r); this.type = "log"; // Handling <1 and crossing 0 cases is tricky, easiest solution is to default to clamping. this.defaultClamp = true; this.base = 10; this.log = (x) => log2(this.base, this.domain, x); this.pow = (x) => pow(this.base, this.domain, x); } toDomain(d) { return d; } transform(x) { const [min, max] = findMinMax(this.domain); if (min >= 0 !== max >= 0) return NaN; return min >= 0 ? Math.log(x) : -Math.log(-x); } transformInvert(x) { const [min, max] = findMinMax(this.domain); if (min >= 0 !== max >= 0) return NaN; return min >= 0 ? Math.exp(x) : -Math.exp(-x); } niceDomain(_ticks, domain = this.domain) { if (domain.length < 2) return []; const { base } = this; const [d0, d1] = domain; const roundStart = d0 > d1 ? Math.ceil : Math.floor; const roundStop = d0 > d1 ? Math.floor : Math.ceil; const n0 = pow(base, domain, roundStart(log2(base, domain, d0))); const n1 = pow(base, domain, roundStop(log2(base, domain, d1))); return [n0, n1]; } ticks({ interval, tickCount = ContinuousScale.defaultTickCount }, domain = this.domain, visibleRange) { if (!domain || domain.length < 2 || tickCount < 1) { return []; } const base = this.base; const [d0, d1] = domain; const start2 = Math.min(d0, d1); const stop = Math.max(d0, d1); let p0 = this.log(start2); let p1 = this.log(stop); if (interval) { const inBounds = (tick) => tick >= start2 && tick <= stop; const step = Math.min(Math.abs(interval), Math.abs(p1 - p0)); const ticks2 = range(p0, p1, step).map(this.pow).filter(inBounds); if (!isDenseInterval(ticks2.length, this.getPixelRange())) { return ticks2; } } if (!isInteger(base) || p1 - p0 >= tickCount) { return createTicks(p0, p1, Math.min(p1 - p0, tickCount)).map(this.pow); } let ticks = []; const isPositive = start2 > 0; p0 = Math.floor(p0) - 1; p1 = Math.round(p1) + 1; const availableSpacing = findRangeExtent(this.range) / tickCount; let lastTickPosition = Infinity; for (let p = p0; p <= p1; p++) { const nextMagnitudeTickPosition = this.convert(this.pow(p + 1)); for (let k = 1; k < base; k++) { const q = isPositive ? k : base - k + 1; const t = this.pow(p) * q; const tickPosition = this.convert(t); const prevSpacing = Math.abs(lastTickPosition - tickPosition); const nextSpacing = Math.abs(tickPosition - nextMagnitudeTickPosition); const fits = prevSpacing >= availableSpacing && nextSpacing >= availableSpacing; if (t >= start2 && t <= stop && (k === 1 || fits || ticks.length === 0)) { ticks.push(t); lastTickPosition = tickPosition; } } } ticks = filterVisibleTicks(ticks, isPositive, visibleRange); return ticks; } tickFormatter({ specifier }) { return specifier != null ? numberFormat(specifier) : String; } datumFormatter(params) { return this.tickFormatter(params); } }; } }); // packages/ag-charts-community/src/scene/util/quadtree.ts var QuadtreeNearest, QuadtreeSubdivisions, QuadtreeNode, QuadtreeNodeNearest; var init_quadtree = __esm({ "packages/ag-charts-community/src/scene/util/quadtree.ts"() { "use strict"; init_nearest(); init_bbox(); QuadtreeNearest = class { constructor(capacity, maxdepth, boundary) { this.root = new QuadtreeNodeNearest(capacity, maxdepth, boundary); } clear(boundary) { this.root.clear(boundary); } addValue(hitTester, value) { const elem = { hitTester, value, distanceSquared: (x, y) => { return hitTester.distanceSquared(x, y); } }; this.root.addElem(elem); } find(x, y) { const arg = { best: { nearest: void 0, distanceSquared: Infinity } }; this.root.find(x, y, arg); return arg.best; } }; QuadtreeSubdivisions = class { constructor(nw, ne, sw, se) { this.nw = nw; this.ne = ne; this.sw = sw; this.se = se; } addElem(elem) { this.nw.addElem(elem); this.ne.addElem(elem); this.sw.addElem(elem); this.se.addElem(elem); } find(x, y, arg) { this.nw.find(x, y, arg); this.ne.find(x, y, arg); this.sw.find(x, y, arg); this.se.find(x, y, arg); } }; QuadtreeNode = class { constructor(capacity, maxdepth, boundary) { this.capacity = capacity; this.maxdepth = maxdepth; this.boundary = boundary ?? BBox.NaN; this.elems = []; this.subdivisions = void 0; } clear(boundary) { this.elems.length = 0; this.boundary = boundary; this.subdivisions = void 0; } addElem(e) { if (this.addCondition(e)) { if (this.subdivisions === void 0) { if (this.maxdepth === 0 || this.elems.length < this.capacity) { this.elems.push(e); } else { this.subdivide(e); } } else { this.subdivisions.addElem(e); } } } find(x, y, arg) { if (this.findCondition(x, y, arg)) { if (this.subdivisions === void 0) { this.findAction(x, y, arg); } else { this.subdivisions.find(x, y, arg); } } } subdivide(newElem) { this.subdivisions = this.makeSubdivisions(); for (const e of this.elems) { this.subdivisions.addElem(e); } this.subdivisions.addElem(newElem); this.elems.length = 0; } makeSubdivisions() { const { x, y, width: width2, height: height2 } = this.boundary; const { capacity } = this; const depth = this.maxdepth - 1; const halfWidth = width2 / 2; const halfHeight = height2 / 2; const nwBoundary = new BBox(x, y, halfWidth, halfHeight); const neBoundary = new BBox(x + halfWidth, y, halfWidth, halfHeight); const swBoundary = new BBox(x, y + halfHeight, halfWidth, halfHeight); const seBoundary = new BBox(x + halfWidth, y + halfHeight, halfWidth, halfHeight); return new QuadtreeSubdivisions( this.child(capacity, depth, nwBoundary), this.child(capacity, depth, neBoundary), this.child(capacity, depth, swBoundary), this.child(capacity, depth, seBoundary) ); } }; QuadtreeNodeNearest = class _QuadtreeNodeNearest extends QuadtreeNode { addCondition(e) { const { x, y } = e.hitTester.midPoint; return this.boundary.containsPoint(x, y); } findCondition(x, y, arg) { const { best } = arg; return best.distanceSquared !== 0 && this.boundary.distanceSquared(x, y) < best.distanceSquared; } findAction(x, y, arg) { const other = nearestSquared(x, y, this.elems, arg.best.distanceSquared); if (other.nearest !== void 0 && other.distanceSquared < arg.best.distanceSquared) { arg.best = other; } } child(capacity, depth, boundary) { return new _QuadtreeNodeNearest(capacity, depth, boundary); } }; } }); // packages/ag-charts-community/src/scale/linearScale.ts var LinearScale; var init_linearScale = __esm({ "packages/ag-charts-community/src/scale/linearScale.ts"() { "use strict"; init_format_util(); init_ticks(); init_continuousScale(); LinearScale = class _LinearScale extends ContinuousScale { constructor() { super([0, 1], [0, 1]); this.type = "number"; } static getTickStep(start2, stop, ticks) { const { interval, tickCount = ContinuousScale.defaultTickCount, minTickCount, maxTickCount } = ticks; return interval ?? tickStep(start2, stop, tickCount, minTickCount, maxTickCount); } toDomain(d) { return d; } ticks({ interval, tickCount = ContinuousScale.defaultTickCount, minTickCount, maxTickCount }, domain = this.domain, visibleRange) { if (!domain || domain.length < 2 || tickCount < 1 || !domain.every(isFinite)) { return []; } const [d0, d1] = domain; if (interval) { const step = Math.abs(interval); if (!isDenseInterval((d1 - d0) / step, this.getPixelRange())) { return range(d0, d1, step); } } return createTicks(d0, d1, tickCount, minTickCount, maxTickCount, visibleRange); } niceDomain(ticks, domain = this.domain) { if (domain.length < 2) return []; const { tickCount = ContinuousScale.defaultTickCount } = ticks; let [start2, stop] = domain; if (tickCount === 1) { [start2, stop] = niceTicksDomain(start2, stop); } else if (tickCount > 1) { const roundStart = start2 > stop ? Math.ceil : Math.floor; const roundStop = start2 > stop ? Math.floor : Math.ceil; const maxAttempts = 4; for (let i = 0; i < maxAttempts; i++) { const prev0 = start2; const prev1 = stop; const step = _LinearScale.getTickStep(start2, stop, ticks); const [d0, d1] = domain; start2 = roundStart(d0 / step) * step; stop = roundStop(d1 / step) * step; if (start2 === prev0 && stop === prev1) break; } } return [start2, stop]; } tickFormatter({ ticks: specifiedTicks, fractionDigits, specifier }) { return specifier != null ? tickFormat(specifiedTicks, specifier) : (x) => formatValue(x, fractionDigits); } datumFormatter({ ticks: specifiedTicks, fractionDigits, specifier }) { return specifier != null ? tickFormat(specifiedTicks, specifier) : (x) => formatValue(x, fractionDigits + 1); } }; } }); // packages/ag-charts-community/src/util/extent.ts function extent(values) { if (values.length === 0) { return null; } let min = Infinity; let max = -Infinity; for (const n of values) { const v = n instanceof Date ? n.getTime() : n; if (typeof v !== "number") continue; if (v < min) { min = v; } if (v > max) { max = v; } } const result = [min, max]; return result.every(isFinite) ? result : null; } function normalisedExtentWithMetadata(d, min, max) { let clipped = false; if (d.length > 2) { d = extent(d) ?? [NaN, NaN]; } if (!isNaN(min)) { clipped || (clipped = min > d[0]); d = [min, d[1]]; } if (!isNaN(max)) { clipped || (clipped = max < d[1]); d = [d[0], max]; } if (d[0] > d[1]) { d = []; } return { extent: d, clipped }; } var init_extent = __esm({ "packages/ag-charts-community/src/util/extent.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/axis/numberAxis.ts var NumberAxis; var init_numberAxis = __esm({ "packages/ag-charts-community/src/chart/axis/numberAxis.ts"() { "use strict"; init_linearScale(); init_default(); init_extent(); init_validation2(); init_cartesianAxis(); NumberAxis = class extends CartesianAxis { constructor(moduleCtx, scale2 = new LinearScale()) { super(moduleCtx, scale2); this.min = NaN; this.max = NaN; } normaliseDataDomain(d) { const { min, max } = this; const { extent: extent3, clipped } = normalisedExtentWithMetadata(d, min, max); return { domain: extent3, clipped }; } }; NumberAxis.className = "NumberAxis"; NumberAxis.type = "number"; __decorateClass([ Validate(AND(NUMBER_OR_NAN, LESS_THAN("max"))), Default(NaN) ], NumberAxis.prototype, "min", 2); __decorateClass([ Validate(AND(NUMBER_OR_NAN, GREATER_THAN("min"))), Default(NaN) ], NumberAxis.prototype, "max", 2); } }); // packages/ag-charts-community/src/chart/axis/timeAxis.ts var TimeAxis; var init_timeAxis = __esm({ "packages/ag-charts-community/src/chart/axis/timeAxis.ts"() { "use strict"; init_timeScale(); init_extent(); init_validation2(); init_cartesianAxis(); TimeAxis = class extends CartesianAxis { constructor(moduleCtx) { super(moduleCtx, new TimeScale()); this.min = void 0; this.max = void 0; } normaliseDataDomain(d) { let { min, max } = this; let clipped = false; if (typeof min === "number") { min = new Date(min); } if (typeof max === "number") { max = new Date(max); } if (d.length > 2) { d = extent(d)?.map((x) => new Date(x)) ?? []; } if (min instanceof Date) { clipped || (clipped = min > d[0]); d = [min, d[1]]; } if (max instanceof Date) { clipped || (clipped = max < d[1]); d = [d[0], max]; } if (d[0] > d[1]) { d = []; } return { domain: d, clipped }; } }; TimeAxis.className = "TimeAxis"; TimeAxis.type = "time"; __decorateClass([ Validate(AND(DATE_OR_DATETIME_MS, LESS_THAN("max")), { optional: true }) ], TimeAxis.prototype, "min", 2); __decorateClass([ Validate(AND(DATE_OR_DATETIME_MS, GREATER_THAN("min")), { optional: true }) ], TimeAxis.prototype, "max", 2); } }); // packages/ag-charts-community/src/chart/series/dataModelSeries.ts var DataModelSeries; var init_dataModelSeries = __esm({ "packages/ag-charts-community/src/chart/series/dataModelSeries.ts"() { "use strict"; init_continuousScale(); init_number(); init_series(); DataModelSeries = class extends Series { constructor() { super(...arguments); this.clipFocusBox = true; } getScaleInformation({ xScale, yScale }) { const isContinuousX = ContinuousScale.is(xScale); const isContinuousY = ContinuousScale.is(yScale); return { isContinuousX, isContinuousY, xScaleType: xScale?.type, yScaleType: yScale?.type }; } getModulePropertyDefinitions() { const xScale = this.axes["x" /* X */]?.scale; const yScale = this.axes["y" /* Y */]?.scale; return this.moduleMap.mapModules((mod2) => mod2.getPropertyDefinitions(this.getScaleInformation({ xScale, yScale }))).flat(); } // Request data, but with message dispatching to series-options (modules). async requestDataModel(dataController, data, opts) { opts.props.push(...this.getModulePropertyDefinitions()); const { dataModel, processedData } = await dataController.request(this.id, data ?? [], opts); this.dataModel = dataModel; this.processedData = processedData; this.dispatch("data-processed", { dataModel, processedData }); return { dataModel, processedData }; } isProcessedDataAnimatable() { const validationResults = this.processedData?.reduced?.animationValidation; if (!validationResults) { return true; } const { orderedKeys, uniqueKeys } = validationResults; return orderedKeys && uniqueKeys; } checkProcessedDataAnimatable() { if (!this.isProcessedDataAnimatable()) { this.ctx.animationManager.skipCurrentBatch(); } } pickFocus(opts) { const nodeData = this.getNodeData(); if (nodeData === void 0 || nodeData.length === 0) { return; } const datumIndex = this.computeFocusDatumIndex(opts, nodeData); if (datumIndex === void 0) { return; } const { clipFocusBox } = this; const datum = nodeData[datumIndex]; const derivedOpts = { ...opts, datumIndex }; const bounds = this.computeFocusBounds(derivedOpts); if (bounds !== void 0) { return { bounds, clipFocusBox, datum, datumIndex }; } } computeFocusDatumIndex(opts, nodeData) { const isDatumEnabled = (datumIndex2) => { const { missing = false, enabled = true, focusable = true } = nodeData[datumIndex2]; return !missing && enabled && focusable; }; const searchBackward = (datumIndex2, delta4) => { while (datumIndex2 >= 0 && !isDatumEnabled(datumIndex2)) { datumIndex2 += delta4; } return datumIndex2 === -1 ? void 0 : datumIndex2; }; const searchForward = (datumIndex2, delta4) => { while (datumIndex2 < nodeData.length && !isDatumEnabled(datumIndex2)) { datumIndex2 += delta4; } return datumIndex2 === nodeData.length ? void 0 : datumIndex2; }; let datumIndex; const clampedIndex = clamp(0, opts.datumIndex, nodeData.length - 1); if (opts.datumIndexDelta < 0) { datumIndex = searchBackward(clampedIndex, opts.datumIndexDelta); } else if (opts.datumIndexDelta > 0) { datumIndex = searchForward(clampedIndex, opts.datumIndexDelta); } else { datumIndex = searchForward(clampedIndex, 1) ?? searchBackward(clampedIndex, -1); } if (datumIndex === void 0) { if (opts.datumIndexDelta === 0) { return; } else { return opts.datumIndex - opts.datumIndexDelta; } } else { return datumIndex; } } }; } }); // packages/ag-charts-community/src/chart/series/seriesProperties.ts var SeriesItemHighlightStyle, SeriesHighlightStyle, TextHighlightStyle, HighlightProperties, HighlightStyle, SeriesProperties; var init_seriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/seriesProperties.ts"() { "use strict"; init_properties(); init_validation2(); SeriesItemHighlightStyle = class extends BaseProperties { constructor() { super(...arguments); this.fill = "rgba(255,255,255, 0.33)"; this.stroke = `rgba(0, 0, 0, 0.4)`; this.strokeWidth = 2; } }; __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], SeriesItemHighlightStyle.prototype, "fill", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], SeriesItemHighlightStyle.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], SeriesItemHighlightStyle.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], SeriesItemHighlightStyle.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], SeriesItemHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH, { optional: true }) ], SeriesItemHighlightStyle.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], SeriesItemHighlightStyle.prototype, "lineDashOffset", 2); SeriesHighlightStyle = class extends BaseProperties { }; __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], SeriesHighlightStyle.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], SeriesHighlightStyle.prototype, "dimOpacity", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], SeriesHighlightStyle.prototype, "enabled", 2); TextHighlightStyle = class extends BaseProperties { constructor() { super(...arguments); this.color = "black"; } }; __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], TextHighlightStyle.prototype, "color", 2); HighlightProperties = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; } }; __decorateClass([ Validate(BOOLEAN, { optional: true }) ], HighlightProperties.prototype, "enabled", 2); HighlightStyle = class extends BaseProperties { constructor() { super(...arguments); this.item = new SeriesItemHighlightStyle(); this.series = new SeriesHighlightStyle(); this.text = new TextHighlightStyle(); } }; __decorateClass([ Validate(OBJECT) ], HighlightStyle.prototype, "item", 2); __decorateClass([ Validate(OBJECT) ], HighlightStyle.prototype, "series", 2); __decorateClass([ Validate(OBJECT) ], HighlightStyle.prototype, "text", 2); SeriesProperties = class extends BaseProperties { constructor() { super(...arguments); this.visible = true; this.focusPriority = Infinity; this.showInLegend = true; this.cursor = "default"; this.nodeClickRange = "exact"; this.highlight = new HighlightProperties(); this.highlightStyle = new HighlightStyle(); } }; __decorateClass([ Validate(STRING, { optional: true }) ], SeriesProperties.prototype, "id", 2); __decorateClass([ Validate(BOOLEAN) ], SeriesProperties.prototype, "visible", 2); __decorateClass([ Validate(REAL_NUMBER, { optional: true }) ], SeriesProperties.prototype, "focusPriority", 2); __decorateClass([ Validate(BOOLEAN) ], SeriesProperties.prototype, "showInLegend", 2); __decorateClass([ Validate(STRING) ], SeriesProperties.prototype, "cursor", 2); __decorateClass([ Validate(INTERACTION_RANGE) ], SeriesProperties.prototype, "nodeClickRange", 2); __decorateClass([ Validate(OBJECT) ], SeriesProperties.prototype, "highlight", 2); __decorateClass([ Validate(OBJECT) ], SeriesProperties.prototype, "highlightStyle", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/cartesianSeries.ts function axisExtent(axis) { let min; let max; if (axis instanceof NumberAxis && (Number.isFinite(axis.min) || Number.isFinite(axis.max))) { min = Number.isFinite(axis.min) ? axis.min : void 0; max = Number.isFinite(axis.max) ? axis.max : void 0; } else if (axis instanceof TimeAxis && (axis.min != null || axis.max != null)) { ({ min, max } = axis); } if (min == null && max == null) return; min ?? (min = -Infinity); max ?? (max = Infinity); return [min, max]; } function clippedRangeIndices(length2, range4, xValue) { const range0 = range4[0].valueOf(); const range1 = range4[1].valueOf(); const xMinIndex = findMinIndex(0, length2 - 1, (index) => { const x = xValue(index)?.valueOf(); return !Number.isFinite(x) || x >= range0; }); let xMaxIndex = findMaxIndex(0, length2 - 1, (index) => { const x = xValue(index)?.valueOf(); return !Number.isFinite(x) || x <= range1; }); if (xMinIndex == null || xMaxIndex == null) return [0, 0]; xMaxIndex = Math.min(xMaxIndex + 1, length2); return [xMinIndex, xMaxIndex]; } var DEFAULT_CARTESIAN_DIRECTION_KEYS, DEFAULT_CARTESIAN_DIRECTION_NAMES, CartesianSeriesNodeEvent, CartesianSeriesProperties, RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD, CartesianSeries; var init_cartesianSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/cartesianSeries.ts"() { "use strict"; init_main(); init_resetMotion(); init_bandScale(); init_continuousScale(); init_logScale(); init_bbox(); init_group(); init_selection(); init_path(); init_text(); init_quadtree(); init_debug(); init_stateMachine(); init_validation2(); init_categoryAxis(); init_numberAxis(); init_timeAxis(); init_chartAxisDirection(); init_marker(); init_dataModelSeries(); init_series(); init_seriesProperties(); init_util(); DEFAULT_CARTESIAN_DIRECTION_KEYS = { ["x" /* X */]: ["xKey"], ["y" /* Y */]: ["yKey"] }; DEFAULT_CARTESIAN_DIRECTION_NAMES = { ["x" /* X */]: ["xName"], ["y" /* Y */]: ["yName"] }; CartesianSeriesNodeEvent = class extends SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.xKey = series.properties.xKey; this.yKey = series.properties.yKey; } }; CartesianSeriesProperties = class extends SeriesProperties { constructor() { super(...arguments); this.pickOutsideVisibleMinorAxis = false; } }; __decorateClass([ Validate(STRING, { optional: true }) ], CartesianSeriesProperties.prototype, "legendItemName", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], CartesianSeriesProperties.prototype, "pickOutsideVisibleMinorAxis", 2); RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD = 100; CartesianSeries = class extends DataModelSeries { constructor({ pathsPerSeries = ["path"], hasMarkers = false, hasHighlightedLabels = false, pathsZIndexSubOrderOffset = [], datumSelectionGarbageCollection = true, markerSelectionGarbageCollection = true, animationAlwaysUpdateSelections = false, animationResetFns, directionKeys, directionNames, ...otherOpts }) { super({ directionKeys, directionNames, canHaveAxes: true, ...otherOpts }); this.NodeEvent = CartesianSeriesNodeEvent; this.dataNodeGroup = this.contentGroup.appendChild( new Group({ name: `${this.id}-series-dataNodes`, zIndex: 0 }) ); this.markerGroup = this.contentGroup.appendChild( new Group({ name: `${this.id}-series-markers`, zIndex: 1 }) ); this.labelGroup = this.contentGroup.appendChild( new TranslatableGroup({ name: `${this.id}-series-labels` }) ); this.labelSelection = Selection.select(this.labelGroup, Text); this.highlightSelection = Selection.select( this.highlightNode, () => this.opts.hasMarkers ? new Marker() : this.nodeFactory() ); this.highlightLabelSelection = Selection.select(this.highlightLabel, Text); this.annotationSelections = /* @__PURE__ */ new Set(); this.debug = Debug.create(); if (!directionKeys || !directionNames) throw new Error(`Unable to initialise series type ${this.type}`); this.opts = { pathsPerSeries, hasMarkers, hasHighlightedLabels, pathsZIndexSubOrderOffset, directionKeys, directionNames, animationResetFns, animationAlwaysUpdateSelections, datumSelectionGarbageCollection, markerSelectionGarbageCollection }; this.paths = pathsPerSeries.map((path) => { return new Path({ name: `${this.id}-${path}` }); }); this.datumSelection = Selection.select( this.dataNodeGroup, () => this.nodeFactory(), datumSelectionGarbageCollection ); this.markerSelection = Selection.select(this.markerGroup, Marker, markerSelectionGarbageCollection); this.animationState = new StateMachine( "empty", { empty: { update: { target: "ready", action: (data) => this.animateEmptyUpdateReady(data) }, reset: "empty", skip: "ready", disable: "disabled" }, ready: { updateData: "waiting", clear: "clearing", highlight: (data) => this.animateReadyHighlight(data), highlightMarkers: (data) => this.animateReadyHighlightMarkers(data), resize: (data) => this.animateReadyResize(data), reset: "empty", skip: "ready", disable: "disabled" }, waiting: { update: { target: "ready", action: (data) => { if (this.ctx.animationManager.isSkipped()) { this.resetAllAnimation(data); } else { this.animateWaitingUpdateReady(data); } } }, reset: "empty", skip: "ready", disable: "disabled" }, disabled: { update: (data) => this.resetAllAnimation(data), reset: "empty" }, clearing: { update: { target: "empty", action: (data) => this.animateClearingUpdateEmpty(data) }, reset: "empty", skip: "ready" } }, () => this.checkProcessedDataAnimatable() ); } get contextNodeData() { return this._contextNodeData; } getNodeData() { return this.contextNodeData?.nodeData; } attachSeries(seriesContentNode, seriesNode, annotationNode) { super.attachSeries(seriesContentNode, seriesNode, annotationNode); this.attachPaths(this.paths, seriesNode, annotationNode); } detachSeries(seriesContentNode, seriesNode, annotationNode) { super.detachSeries(seriesContentNode, seriesNode, annotationNode); this.detachPaths(this.paths, seriesNode, annotationNode); } attachPaths(paths, _seriesNode, _annotationNode) { for (const path of paths) { this.contentGroup.appendChild(path); } } detachPaths(paths, _seriesNode, _annotationNode) { for (const path of paths) { this.contentGroup.removeChild(path); } } renderToOffscreenCanvas() { const nodeData = this.getNodeData(); return nodeData != null && nodeData.length > RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD; } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } else if (phase === "ready") { this.animationState.transition("skip"); } else if (phase === "disabled") { this.animationState.transition("disable"); } } addChartEventListeners() { this.destroyFns.push( this.ctx.chartEventManager.addListener("legend-item-click", (event) => this.onLegendItemClick(event)), this.ctx.chartEventManager.addListener( "legend-item-double-click", (event) => this.onLegendItemDoubleClick(event) ) ); } destroy() { super.destroy(); this._contextNodeData = void 0; } update({ seriesRect }) { const { visible, _contextNodeData: previousContextData } = this; const series = this.ctx.highlightManager?.getActiveHighlight()?.series; const seriesHighlighted = series === this; const resize = this.checkResize(seriesRect); const highlightItems = this.updateHighlightSelection(seriesHighlighted); this.updateSelections(visible); this.updateNodes(highlightItems, seriesHighlighted, visible); const animationData = this.getAnimationData(seriesRect, previousContextData); if (!animationData) return; if (resize) { this.animationState.transition("resize", animationData); } this.animationState.transition("update", animationData); } updateSelections(anySeriesItemEnabled) { var _a; const animationSkipUpdate = !this.opts.animationAlwaysUpdateSelections && this.ctx.animationManager.isSkipped(); if (!anySeriesItemEnabled && animationSkipUpdate) { return; } if (!this.nodeDataRefresh && !this.isPathOrSelectionDirty()) { return; } if (this.nodeDataRefresh) { this.nodeDataRefresh = false; this.debug(`CartesianSeries.updateSelections() - calling createNodeData() for`, this.id); this.markQuadtreeDirty(); this._contextNodeData = this.createNodeData(); const animationValid = this.isProcessedDataAnimatable(); if (this._contextNodeData) { (_a = this._contextNodeData).animationValid ?? (_a.animationValid = animationValid); } const { dataModel, processedData } = this; if (dataModel !== void 0 && processedData !== void 0) { this.dispatch("data-update", { dataModel, processedData }); } } this.updateSeriesSelections(); } updateSeriesSelections(seriesHighlighted) { const { datumSelection, labelSelection, markerSelection, paths } = this; const contextData = this._contextNodeData; if (!contextData) return; const { nodeData, labelData, itemId } = contextData; this.updatePaths({ seriesHighlighted, itemId, contextData, paths }); this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.labelSelection = this.updateLabelSelection({ labelData, labelSelection }) ?? labelSelection; if (this.opts.hasMarkers) { this.markerSelection = this.updateMarkerSelection({ nodeData, markerSelection }); } } updateNodes(highlightedItems, seriesHighlighted, anySeriesItemEnabled) { const { highlightSelection, highlightLabelSelection, opts: { hasMarkers, hasHighlightedLabels } } = this; const animationEnabled = !this.ctx.animationManager.isSkipped(); const visible = this.visible && this._contextNodeData != null && anySeriesItemEnabled; this.contentGroup.visible = animationEnabled || visible; this.highlightGroup.visible = (animationEnabled || visible) && seriesHighlighted; const opacity = this.getOpacity(); if (hasMarkers) { this.updateMarkerNodes({ markerSelection: highlightSelection, isHighlight: true }); this.animationState.transition("highlightMarkers", highlightSelection); } else { this.updateDatumNodes({ datumSelection: highlightSelection, isHighlight: true }); this.animationState.transition("highlight", highlightSelection); } if (hasHighlightedLabels) { this.updateLabelNodes({ labelSelection: highlightLabelSelection }); } const { dataNodeGroup, markerGroup, datumSelection, labelSelection, markerSelection, paths, labelGroup } = this; const { itemId } = this.contextNodeData ?? {}; dataNodeGroup.opacity = opacity; dataNodeGroup.visible = animationEnabled || visible; labelGroup.visible = visible; if (hasMarkers) { markerGroup.opacity = opacity; markerGroup.visible = visible; } if (labelGroup) { labelGroup.opacity = opacity; } this.updatePathNodes({ seriesHighlighted, itemId, paths, opacity, visible, animationEnabled }); if (!dataNodeGroup.visible) { return; } this.updateDatumNodes({ datumSelection, highlightedItems, isHighlight: false }); if (!this.usesPlacedLabels) { this.updateLabelNodes({ labelSelection }); } if (hasMarkers) { this.updateMarkerNodes({ markerSelection, isHighlight: false }); } } getHighlightLabelData(labelData, highlightedItem) { const labelItems = labelData.filter( (ld) => ld.datum === highlightedItem.datum && ld.itemId === highlightedItem.itemId ); return labelItems.length === 0 ? void 0 : labelItems; } getHighlightData(_nodeData, highlightedItem) { return highlightedItem ? [highlightedItem] : void 0; } updateHighlightSelection(seriesHighlighted) { const { highlightSelection, highlightLabelSelection, _contextNodeData: contextNodeData } = this; if (!contextNodeData) return; const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); const item = seriesHighlighted && highlightedDatum?.datum ? highlightedDatum : void 0; let labelItems; let highlightItems; if (item != null) { const labelsEnabled = this.isLabelEnabled(); const { labelData, nodeData } = contextNodeData; highlightItems = this.getHighlightData(nodeData, item); labelItems = labelsEnabled ? this.getHighlightLabelData(labelData, item) : void 0; } this.highlightSelection = this.updateHighlightSelectionItem({ items: highlightItems, highlightSelection }); this.highlightLabelSelection = this.updateHighlightSelectionLabel({ items: labelItems, highlightLabelSelection }); return highlightItems; } markQuadtreeDirty() { this.quadtree = void 0; } *datumNodesIter() { for (const { node } of this.datumSelection) { if (node.datum.missing === true) continue; yield node; } } getQuadTree() { if (this.quadtree === void 0) { const { width: width2, height: height2 } = this.ctx.scene.canvas; const canvasRect = new BBox(0, 0, width2, height2); this.quadtree = new QuadtreeNearest(100, 10, canvasRect); this.initQuadTree(this.quadtree); } return this.quadtree; } initQuadTree(_quadtree) { } pickNodeExactShape(point) { const result = super.pickNodeExactShape(point); if (result) { return result; } const { x, y } = point; const { opts: { hasMarkers } } = this; let match; const { dataNodeGroup, markerGroup } = this; match = dataNodeGroup.pickNode(x, y); if (!match && hasMarkers) { match = markerGroup?.pickNode(x, y); } if (match && match.datum.missing !== true) { return { datum: match.datum, distance: 0 }; } for (const mod2 of this.moduleMap.modules()) { const { datum } = mod2.pickNodeExact(point) ?? {}; if (datum == null) continue; if (datum?.missing === true) continue; return { datum, distance: 0 }; } } pickNodeClosestDatum(point) { const { x, y } = point; const { axes, _contextNodeData: contextNodeData } = this; if (!contextNodeData) return; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; const hitPoint = { x, y }; let minDistance = Infinity; let closestDatum; for (const datum of contextNodeData.nodeData) { const { point: { x: datumX = NaN, y: datumY = NaN } = {} } = datum; if (isNaN(datumX) || isNaN(datumY)) { continue; } const isInRange = xAxis?.inRange(datumX) && yAxis?.inRange(datumY); if (!isInRange) { continue; } const distance2 = Math.max((hitPoint.x - datumX) ** 2 + (hitPoint.y - datumY) ** 2, 0); if (distance2 < minDistance) { minDistance = distance2; closestDatum = datum; } } for (const mod2 of this.moduleMap.modules()) { const modPick = mod2.pickNodeNearest(point); if (modPick !== void 0 && modPick.distanceSquared < minDistance) { minDistance = modPick.distanceSquared; closestDatum = modPick.datum; break; } } if (closestDatum) { const distance2 = Math.max(Math.sqrt(minDistance) - (closestDatum.point?.size ?? 0), 0); return { datum: closestDatum, distance: distance2 }; } } pickNodeMainAxisFirst(point, requireCategoryAxis) { const { x, y } = point; const { axes, _contextNodeData: contextNodeData } = this; const { pickOutsideVisibleMinorAxis } = this.properties; if (!contextNodeData) return; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; const directions2 = [xAxis, yAxis].filter(CategoryAxis.is).map((a) => a.direction); if (requireCategoryAxis && directions2.length === 0) return; const [majorDirection = "x" /* X */] = directions2; const hitPointCoords = [x, y]; if (majorDirection !== "x" /* X */) hitPointCoords.reverse(); const minDistance = [Infinity, Infinity]; let closestDatum; for (const datum of contextNodeData.nodeData) { const { x: datumX = NaN, y: datumY = NaN } = datum.point ?? datum.midPoint ?? {}; if (isNaN(datumX) || isNaN(datumY) || datum.missing === true) continue; const visible = [xAxis?.inRange(datumX), yAxis?.inRange(datumY)]; if (majorDirection !== "x" /* X */) { visible.reverse(); } if (!visible[0] || !pickOutsideVisibleMinorAxis && !visible[1]) continue; const datumPoint = [datumX, datumY]; if (majorDirection !== "x" /* X */) { datumPoint.reverse(); } let newMinDistance = true; for (let i = 0; i < datumPoint.length; i++) { const dist = Math.abs(datumPoint[i] - hitPointCoords[i]); if (dist > minDistance[i]) { newMinDistance = false; break; } else if (dist < minDistance[i]) { minDistance[i] = dist; minDistance.fill(Infinity, i + 1, minDistance.length); } } if (newMinDistance) { closestDatum = datum; } } if (closestDatum) { let closestDistanceSquared = Math.max( minDistance[0] ** 2 + minDistance[1] ** 2 - (closestDatum.point?.size ?? 0), 0 ); for (const mod2 of this.moduleMap.modules()) { const modPick = mod2.pickNodeMainAxisFirst(point); if (modPick !== void 0 && modPick.distanceSquared < closestDistanceSquared) { closestDatum = modPick.datum; closestDistanceSquared = modPick.distanceSquared; break; } } return { datum: closestDatum, distance: Math.sqrt(closestDistanceSquared) }; } } isPathOrSelectionDirty() { return false; } shouldFlipXY() { return false; } // Workaround - it would be nice if this difference didn't exist keysOrValues(xKey) { const key = this.dataModel.resolveProcessedDataIndexById(this, xKey); return this.processedData?.keys[key]?.get(this.id) ?? this.processedData?.columns[key] ?? []; } visibleRange(axisKey, visibleRange, indices) { const xValues = this.keysOrValues(axisKey); const pixelSize = 0; return visibleRangeIndices(indices?.length ?? xValues.length, visibleRange, (topIndex) => { const datumIndex = indices?.[topIndex] ?? topIndex; return this.xCoordinateRange(xValues[datumIndex], pixelSize, datumIndex); }); } domainForVisibleRange(_direction, axisKeys, crossAxisKey, visibleRange, sorted, indices) { const { processedData, dataModel } = this; const [r0, r1] = visibleRange; const crossAxisValues = this.keysOrValues(crossAxisKey); if (sorted) { const crossAxisRange = this.visibleRange(crossAxisKey, visibleRange, indices); return dataModel.getDomainBetweenRange(this, axisKeys, crossAxisRange, processedData); } const allAxisValues = axisKeys.map((axisKey) => this.keysOrValues(axisKey)); let axisMin = Infinity; let axisMax = -Infinity; crossAxisValues.forEach((crossAxisValue, i) => { const [x0, x1] = this.xCoordinateRange(crossAxisValue, 0, i); if (x1 < r0 || x0 > r1) return; for (let j = 0; j < axisKeys.length; j++) { const axisValue = allAxisValues[j][i]; axisMin = Math.min(axisMin, axisValue); axisMax = Math.max(axisMax, axisValue); } }); if (axisMin > axisMax) return [NaN, NaN]; return [axisMin, axisMax]; } domainForClippedRange(direction, axisKeys, crossAxisKey, sorted) { const { processedData, dataModel, axes } = this; const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */; const crossAxisRange = axisExtent(axes[crossDirection]); if (!crossAxisRange) { return axisKeys.flatMap((axisKey) => dataModel.getDomain(this, axisKey, "value", processedData)); } const crossAxisValues = this.keysOrValues(crossAxisKey); if (sorted) { const crossRange = clippedRangeIndices( crossAxisValues.length, crossAxisRange, (index) => crossAxisValues[index] ); return dataModel.getDomainBetweenRange(this, axisKeys, crossRange, processedData); } const allAxisValues = axisKeys.map((axisKey) => this.keysOrValues(axisKey)); const range0 = crossAxisRange[0].valueOf(); const range1 = crossAxisRange[1].valueOf(); const axisValues = []; crossAxisValues.forEach((crossAxisValue, i) => { const c = crossAxisValue.valueOf(); if (c < range0 || c > range1) return; const values = allAxisValues.map((v) => v[i]); if (c >= range0) { axisValues.push(...values); } if (c <= range1) { axisValues.push(...values); } }); return axisValues; } countVisibleItems(crossAxisKey, axisKeys, xVisibleRange, yVisibleRange, minVisibleItems) { const { dataModel, processedData } = this; if (!dataModel || !processedData) return Infinity; const crossValues = this.keysOrValues(crossAxisKey); const allAxisValues = axisKeys.map((axisKey) => dataModel.resolveColumnById(this, axisKey, processedData)); const crossAxis = this.axes["x" /* X */]; const axis = this.axes["y" /* Y */]; const shouldFlipXY = this.shouldFlipXY(); const crossRange = crossAxis.range; const range4 = axis.range; const convert2 = (d, r, v) => { return d[0] + (v - r[0]) / (r[1] - r[0]) * (d[1] - d[0]); }; const crossMin = convert2(crossRange, crossAxis.visibleRange, xVisibleRange[0]); const crossMax = convert2(crossRange, crossAxis.visibleRange, xVisibleRange[1]); const axisMin = convert2(range4, axis.visibleRange, shouldFlipXY ? yVisibleRange[0] : yVisibleRange[1]); const axisMax = convert2(range4, axis.visibleRange, shouldFlipXY ? yVisibleRange[1] : yVisibleRange[0]); const startIndex = Math.round( (xVisibleRange[0] + (xVisibleRange[1] - xVisibleRange[0]) / 2) * crossValues.length ); const pixelSize = 0; return countExpandingSearch(0, crossValues.length - 1, startIndex, minVisibleItems, (index) => { let [x0, x1] = this.xCoordinateRange(crossValues[index], pixelSize, index); let [y0, y1] = this.yCoordinateRange( allAxisValues.map((axisValues) => axisValues[index]), pixelSize, index ); if (!isFiniteNumber(x0) || !isFiniteNumber(x1) || !isFiniteNumber(y0) || !isFiniteNumber(y1)) { return false; } if (shouldFlipXY) [x0, x1, y0, y1] = [y0, y1, x0, x1]; return x0 >= crossMin && x1 <= crossMax && y0 >= axisMin && y1 <= axisMax; }); } updateHighlightSelectionItem(opts) { const { opts: { hasMarkers } } = this; const { items, highlightSelection } = opts; const nodeData = items ?? []; if (hasMarkers) { const markerSelection = highlightSelection; return this.updateMarkerSelection({ nodeData, markerSelection }); } else { return this.updateDatumSelection({ nodeData, datumSelection: highlightSelection }); } } updateHighlightSelectionLabel(opts) { return this.updateLabelSelection({ labelData: opts.items ?? [], labelSelection: opts.highlightLabelSelection }); } updateDatumSelection(opts) { return opts.datumSelection; } updateDatumNodes(_opts) { } updateMarkerSelection(opts) { return opts.markerSelection; } updateMarkerNodes(_opts) { } updatePaths(opts) { opts.paths.forEach((p) => p.visible = false); } updatePathNodes(opts) { const { paths, opacity, visible } = opts; for (const path of paths) { path.opacity = opacity; path.visible = visible; } } resetPathAnimation(data) { const { path } = this.opts?.animationResetFns ?? {}; if (path) { data.paths.forEach((paths) => { resetMotion([paths], path); }); } } resetDatumAnimation(data) { const { datum } = this.opts?.animationResetFns ?? {}; if (datum) { resetMotion([data.datumSelection], datum); } } resetLabelAnimation(data) { const { label } = this.opts?.animationResetFns ?? {}; if (label) { resetMotion([data.labelSelection], label); } } resetMarkerAnimation(data) { const { marker } = this.opts?.animationResetFns ?? {}; if (marker && this.opts.hasMarkers) { resetMotion([data.markerSelection], marker); } } resetAllAnimation(data) { this.ctx.animationManager.stopByAnimationGroupId(this.id); this.resetPathAnimation(data); this.resetDatumAnimation(data); this.resetLabelAnimation(data); this.resetMarkerAnimation(data); if (data.contextData?.animationValid === false) { this.ctx.animationManager.skipCurrentBatch(); } } animateEmptyUpdateReady(data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(data); } animateWaitingUpdateReady(data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(data); } animateReadyHighlight(data) { const { datum } = this.opts?.animationResetFns ?? {}; if (datum) { resetMotion([data], datum); } } animateReadyHighlightMarkers(data) { const { marker } = this.opts?.animationResetFns ?? {}; if (marker) { resetMotion([data], marker); } } animateReadyResize(data) { this.resetAllAnimation(data); } animateClearingUpdateEmpty(data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(data); } getAnimationData(seriesRect, previousContextData) { const { _contextNodeData: contextData } = this; if (!contextData) return; const animationData = { datumSelection: this.datumSelection, markerSelection: this.markerSelection, labelSelection: this.labelSelection, annotationSelections: [...this.annotationSelections], contextData, previousContextData, paths: this.paths, seriesRect }; return animationData; } updateLabelSelection(opts) { return opts.labelSelection; } getScaling(scale2) { if (scale2 instanceof LogScale) { const { range: range4, domain } = scale2; return { type: "log", convert: (d) => scale2.convert(d), domain: [domain[0], domain[1]], range: [range4[0], range4[1]] }; } else if (scale2 instanceof ContinuousScale) { const { range: range4, domain } = scale2; return { type: "continuous", domain: [domain[0], domain[1]], range: [range4[0], range4[1]] }; } else if (scale2 instanceof BandScale) { const { domain } = scale2; return { type: "category", domain, inset: scale2.inset, step: scale2.step }; } } calculateScaling() { const result = {}; for (const direction of Object.values(ChartAxisDirection)) { const axis = this.axes[direction]; if (!axis) continue; const scalingResult = this.getScaling(axis.scale); if (scalingResult != null) { result[direction] = scalingResult; } } return result; } }; } }); // packages/ag-charts-community/src/chart/cartesianChart.ts var directions, _CartesianChart, CartesianChart; var init_cartesianChart = __esm({ "packages/ag-charts-community/src/chart/cartesianChart.ts"() { "use strict"; init_main(); init_fromToMotion(); init_continuousScale(); init_number(); init_categoryAxis(); init_chart(); init_cartesianSeries(); directions = ["top", "right", "bottom", "left"]; _CartesianChart = class _CartesianChart extends Chart { constructor(options, resources) { super(options, resources); // TODO should come from theme /** Integrated Charts feature state - not used in Standalone Charts. */ this.paired = true; this.lastUpdateClipRect = void 0; this.lastLayoutWidth = NaN; this.lastLayoutHeight = NaN; } onAxisChange(newValue, oldValue) { super.onAxisChange(newValue, oldValue); if (this.ctx != null) { this.ctx.zoomManager.updateAxes(newValue); } } destroySeries(series) { super.destroySeries(series); this.lastLayoutWidth = NaN; this.lastLayoutHeight = NaN; } getChartType() { return "cartesian"; } setRootClipRects(clipRect) { const { seriesRoot, annotationRoot } = this; seriesRoot.setClipRect(clipRect); annotationRoot.setClipRect(clipRect); } async processData() { await super.processData(); for (const axis of this.axes) { const syncedDomain = this.getSyncedDomain(axis); if (syncedDomain != null) { axis.setDomains(syncedDomain); } } this.ctx.updateService.dispatchProcessData({ series: { shouldFlipXY: this.shouldFlipXY() } }); } performLayout(ctx) { const { seriesRoot, annotationRoot } = this; const { clipSeries, seriesRect, visible } = this.updateAxes(ctx.layoutBox); this.seriesRoot.visible = visible; this.seriesRect = seriesRect; this.animationRect = ctx.layoutBox; const { x, y } = seriesRect; if (ctx.width !== this.lastLayoutWidth || ctx.height !== this.lastLayoutHeight) { for (const group of [seriesRoot, annotationRoot]) { group.translationX = Math.floor(x); group.translationY = Math.floor(y); } } else { const { translationX, translationY } = seriesRoot; staticFromToMotion( this.id, "seriesRect", this.ctx.animationManager, [seriesRoot, annotationRoot], { translationX, translationY }, { translationX: Math.floor(x), translationY: Math.floor(y) }, { phase: "update" } ); } this.lastLayoutWidth = ctx.width; this.lastLayoutHeight = ctx.height; const seriesPaddedRect = seriesRect.clone().grow(this.seriesArea.padding); const clipRect = this.seriesArea.clip || clipSeries ? seriesPaddedRect : void 0; const { lastUpdateClipRect } = this; this.lastUpdateClipRect = clipRect; if (this.ctx.animationManager.isActive() && lastUpdateClipRect != null) { this.ctx.animationManager.animate({ id: this.id, groupId: "clip-rect", phase: "update", from: lastUpdateClipRect, to: seriesPaddedRect, onUpdate: (interpolatedClipRect) => this.setRootClipRects(interpolatedClipRect), onComplete: () => this.setRootClipRects(clipRect) }); } else { this.setRootClipRects(clipRect); } this.ctx.layoutManager.emitLayoutComplete(ctx, { axes: this.axes.map((axis) => axis.getLayoutState()), series: { visible, rect: seriesRect, paddedRect: seriesPaddedRect }, clipSeries }); } updateAxes(layoutBox) { const { clipSeries, seriesRect, overflows } = this.resolveAxesLayout(layoutBox); for (const axis of this.axes) { axis.update(); axis.setCrossLinesVisible(!overflows); this.clipAxis(axis, seriesRect, layoutBox); } return { clipSeries, seriesRect, visible: !overflows }; } // Iteratively try to resolve axis widths - since X axis width affects Y axis range, // and vice-versa, we need to iteratively try and find a fit for the axes and their // ticks/labels. resolveAxesLayout(layoutBox) { let newState; let prevState; let iterations = 0; const maxIterations = 10; do { prevState = newState ?? this.getDefaultState(); newState = this.updateAxesPass(new Map(prevState.axisAreaWidths), layoutBox.clone()); if (iterations++ > maxIterations) { logger_exports.warn("Max iterations reached. Unable to stabilize axes layout."); break; } } while (!this.isLayoutStable(newState, prevState)); this.lastAreaWidths = newState.axisAreaWidths; return newState; } updateAxesPass(axisAreaWidths, axisAreaBound) { const axisWidths = /* @__PURE__ */ new Map(); const primaryTickCounts = {}; let overflows = false; let clipSeries = false; for (const dir of directions) { const padding = this.seriesArea.padding[dir]; const axis = this.axes.findLast((a) => a.position === dir); if (axis) { axis.seriesAreaPadding = padding; } else { axisAreaBound.shrink(padding, dir); } } const totalWidth = (axisAreaWidths.get("left") ?? 0) + (axisAreaWidths.get("right") ?? 0); const totalHeight = (axisAreaWidths.get("top") ?? 0) + (axisAreaWidths.get("bottom") ?? 0); const crossLinePadding = this.buildCrossLinePadding(axisAreaWidths); if (axisAreaBound.width <= totalWidth + crossLinePadding.hPadding || axisAreaBound.height <= totalHeight + crossLinePadding.vPadding) { overflows = true; } else { axisAreaBound.shrink(crossLinePadding); } const seriesRect = axisAreaBound.clone().shrink(Object.fromEntries(axisAreaWidths)); for (const axis of this.axes) { const { position = "left", direction } = axis; this.sizeAxis(axis, seriesRect, position); const isVertical = direction === "y" /* Y */; const { primaryTickCount, bbox } = axis.calculateLayout( axis.nice ? primaryTickCounts[direction] : void 0 ); primaryTickCounts[direction] ?? (primaryTickCounts[direction] = primaryTickCount); clipSeries || (clipSeries = axis.dataDomain.clipped || axis.visibleRange[0] > 0 || axis.visibleRange[1] < 1); axisWidths.set(axis.id, Math.ceil(axis.thickness ?? (isVertical ? bbox?.width : bbox?.height) ?? 0)); } const axisGroups = Object.entries(groupBy(this.axes, (axis) => axis.position ?? "left")); const { width: width2, height: height2, pixelRatio } = this.ctx.scene; const newAxisAreaWidths = /* @__PURE__ */ new Map(); const axisOffsets = /* @__PURE__ */ new Map(); for (const [position, axes] of axisGroups) { const isVertical = position === "left" || position === "right"; let currentOffset = isVertical ? height2 % pixelRatio : width2 % pixelRatio; let totalAxisWidth = 0; for (const axis of axes) { axisOffsets.set(axis.id, currentOffset); const axisThickness = axisWidths.get(axis.id) ?? 0; totalAxisWidth = Math.max(totalAxisWidth, currentOffset + axisThickness); if (axis.layoutConstraints.stacked) { currentOffset += axisThickness + _CartesianChart.AxesPadding; } } newAxisAreaWidths.set(position, Math.ceil(totalAxisWidth)); } for (const [position, axes] of axisGroups) { this.positionAxes({ axes, position, axisWidths, axisOffsets, axisAreaWidths: newAxisAreaWidths, axisBound: axisAreaBound, seriesRect }); } return { clipSeries, seriesRect, axisAreaWidths: newAxisAreaWidths, overflows }; } buildCrossLinePadding(axisAreaSize) { const crossLinePadding = { top: 0, right: 0, bottom: 0, left: 0, hPadding: 0, vPadding: 0 }; this.axes.forEach((axis) => { axis.crossLines?.forEach((crossLine) => { crossLine.calculatePadding?.(crossLinePadding); }); }); for (const [side, padding = 0] of Object.entries(crossLinePadding)) { crossLinePadding[side] = Math.max(padding - (axisAreaSize.get(side) ?? 0), 0); } crossLinePadding.hPadding = crossLinePadding.left + crossLinePadding.right; crossLinePadding.vPadding = crossLinePadding.top + crossLinePadding.bottom; return crossLinePadding; } clampToOutsideSeriesRect(seriesRect, value, dimension, direction) { const bound = dimension === "x" ? seriesRect.x : seriesRect.y; const size = dimension === "x" ? seriesRect.width : seriesRect.height; return direction === 1 ? Math.min(value, bound + size) : Math.max(value, bound); } getSyncedDomain(axis) { const syncModule = this.modulesManager.getModule("sync"); if (!syncModule?.enabled) return; const syncedDomain = syncModule.getSyncedDomain(axis); if (syncedDomain && axis.dataDomain.domain.length) { let shouldUpdate; const { domain } = axis.scale; if (ContinuousScale.is(axis.scale)) { const [min, max] = findMinMax(syncedDomain); shouldUpdate = min !== domain[0] || max !== domain[1]; } else { shouldUpdate = !arraysEqual(syncedDomain, domain); } if (shouldUpdate && !this.skipSync) { syncModule.updateSiblings(); } } return syncedDomain; } sizeAxis(axis, seriesRect, position) { const isCategory = axis instanceof CategoryAxis; const isLeftRight = position === "left" || position === "right"; const { width: width2, height: height2 } = seriesRect; const maxEnd = isLeftRight ? height2 : width2; let start2 = 0; let end2 = maxEnd; let { min, max } = this.ctx.zoomManager.getAxisZoom(axis.id); const { width: axisWidth, unit, align: align2 } = axis.layoutConstraints; if (unit === "px") { end2 = start2 + axisWidth; } else { end2 = end2 * axisWidth / 100; } if (align2 === "end") { start2 = maxEnd - (end2 - start2); end2 = maxEnd; } if (isLeftRight) { if (isCategory) { [min, max] = [1 - max, 1 - min]; } else { [start2, end2] = [end2, start2]; } } axis.range = [start2, end2]; axis.visibleRange = [min, max]; axis.gridLength = isLeftRight ? width2 : height2; } positionAxes(opts) { const { axes, axisBound, axisWidths, axisOffsets, axisAreaWidths, seriesRect, position } = opts; const axisAreaWidth = axisAreaWidths.get(position) ?? 0; let mainDimension = "x"; let minorDimension = "y"; let direction = 1; if (position === "top" || position === "bottom") { mainDimension = "y"; minorDimension = "x"; } let axisBoundMainOffset = axisBound[mainDimension]; if (position === "right" || position === "bottom") { direction = -1; axisBoundMainOffset += mainDimension === "x" ? axisBound.width : axisBound.height; } for (const axis of axes) { const minorOffset = axisAreaWidths.get(minorDimension === "x" ? "left" : "top") ?? 0; const axisThickness = axisWidths.get(axis.id) ?? 0; const axisOffset = axisOffsets.get(axis.id) ?? 0; axis.gridPadding = axisAreaWidth - axisOffset - axisThickness; axis.translation[minorDimension] = axisBound[minorDimension] + minorOffset; axis.translation[mainDimension] = this.clampToOutsideSeriesRect( seriesRect, axisBoundMainOffset + direction * (axisOffset + axisThickness), mainDimension, direction ); } } shouldFlipXY() { return this.series.every((series) => series instanceof CartesianSeries && series.shouldFlipXY()); } getDefaultState() { const axisAreaWidths = /* @__PURE__ */ new Map(); if (this.lastAreaWidths) { for (const { position = "left" } of this.axes) { const areaWidth = this.lastAreaWidths.get(position); if (areaWidth != null) { axisAreaWidths.set(position, areaWidth); } } } return { axisAreaWidths, clipSeries: false, overflows: false }; } isLayoutStable(newState, prevState) { if (prevState.overflows !== newState.overflows || prevState.clipSeries !== newState.clipSeries) { return false; } for (const key of newState.axisAreaWidths.keys()) { if (!prevState.axisAreaWidths.has(key)) { return false; } } for (const [p, w] of prevState.axisAreaWidths.entries()) { const otherW = newState.axisAreaWidths.get(p); if ((w != null || otherW != null) && w !== otherW) { return false; } } return true; } clipAxis(axis, seriesRect, layoutBBox) { const gridLinePadding = Math.ceil(axis.gridLine?.width ?? 0); const axisLinePadding = Math.ceil(axis.line?.width ?? 0); let { width: width2, height: height2 } = seriesRect; width2 += axis.direction === "x" /* X */ ? gridLinePadding : axisLinePadding; height2 += axis.direction === "y" /* Y */ ? gridLinePadding : axisLinePadding; axis.clipGrid(seriesRect.x, seriesRect.y, width2, height2); switch (axis.position) { case "left": case "right": axis.clipTickLines( layoutBBox.x, seriesRect.y - gridLinePadding, layoutBBox.width + gridLinePadding, seriesRect.height + gridLinePadding * 2 ); break; case "top": case "bottom": axis.clipTickLines( seriesRect.x - gridLinePadding, layoutBBox.y, seriesRect.width + gridLinePadding * 2, layoutBBox.height + gridLinePadding ); const { label, labelNodes, scale: scale2 } = axis; if (ContinuousScale.is(scale2) && label.enabled && label.avoidCollisions && labelNodes.length > 1) { const sortedLabels = labelNodes.toSorted((a, b) => a.translationY - b.translationY); const lastLabel = sortedLabels.at(-1); const lastLabelBBox = lastLabel.getBBox(); const lastLabelInBounds = seriesRect.x + lastLabelBBox.y + lastLabelBBox.height <= layoutBBox.x + layoutBBox.width + this.padding.right; lastLabel.visible = lastLabelInBounds; if (lastLabelInBounds || axis.visibleRange[0] > 0 || axis.visibleRange[1] < 1) { sortedLabels[0].visible = true; } else { const firstLabelBBox = sortedLabels[0].getBBox(); sortedLabels[0].visible = firstLabelBBox.y >= 0; } } break; } } }; _CartesianChart.className = "CartesianChart"; _CartesianChart.type = "cartesian"; _CartesianChart.AxesPadding = 15; CartesianChart = _CartesianChart; } }); // packages/ag-charts-community/src/chart/cartesianChartModule.ts var CartesianChartModule; var init_cartesianChartModule = __esm({ "packages/ag-charts-community/src/chart/cartesianChartModule.ts"() { "use strict"; init_cartesianChart(); init_types(); CartesianChartModule = { type: "chart", name: "cartesian", detect: isAgCartesianChartOptions, create(options, resources) { return new CartesianChart(options, resources); } }; } }); // packages/ag-charts-community/src/chart/chartProxy.ts var debug2, _AgChartInstanceProxy, AgChartInstanceProxy; var init_chartProxy = __esm({ "packages/ag-charts-community/src/chart/chartProxy.ts"() { "use strict"; init_module(); init_debug(); init_json(); init_proxy(); debug2 = Debug.create(true, "opts"); _AgChartInstanceProxy = class _AgChartInstanceProxy { constructor(chart, factoryApi, licenseManager) { this.factoryApi = factoryApi; this.licenseManager = licenseManager; this.chart = chart; } async update(options) { return debug2.group("AgChartInstance.update()", async () => { this.factoryApi.update(options, this); await this.chart.waitForUpdate(); }); } async updateDelta(deltaOptions) { return debug2.group("AgChartInstance.updateDelta()", async () => { this.factoryApi.updateUserDelta(this, deltaOptions); await this.chart.waitForUpdate(); }); } getOptions() { const options = deepClone(this.chart.getOptions()); for (const key of Object.keys(options)) { if (key.startsWith("_")) { delete options[key]; } } return options; } waitForUpdate() { return this.chart.waitForUpdate(); } async download(opts) { const clone2 = await this.prepareResizedChart(this, opts); try { clone2.chart.download(opts?.fileName, opts?.fileFormat); } finally { clone2.destroy(); } } async __toSVG(opts) { const clone2 = await this.prepareResizedChart(this, { width: 600, height: 300, ...opts }); try { return clone2.chart.toSVG(); } finally { clone2.destroy(); } } async getImageDataURL(opts) { const clone2 = await this.prepareResizedChart(this, opts); try { return clone2.chart.getCanvasDataURL(opts?.fileFormat); } finally { clone2.destroy(); } } getState() { return this.factoryApi.caretaker.save(...this.getEnabledOriginators()); } async setState(state) { const originators = this.getEnabledOriginators(); if (!originators.includes(this.chart.ctx.legendManager)) { await this.setStateOriginators(state, originators); return; } await this.setStateOriginators( state, originators.filter((originator) => originator !== this.chart.ctx.zoomManager) ); await this.setStateOriginators(state, [this.chart.ctx.zoomManager]); } resetAnimations() { this.chart.resetAnimations(); } skipAnimations() { this.chart.skipAnimations(); } destroy() { if (this.releaseChart) { this.releaseChart(); this.releaseChart = void 0; } else if (this.chart) { this.chart.publicApi = void 0; this.chart.destroy(); } this.chart = null; } async prepareResizedChart(proxy, opts = {}) { const { chart } = proxy; const width2 = opts.width ?? chart.width ?? chart.ctx.scene.canvas.width; const height2 = opts.height ?? chart.height ?? chart.ctx.scene.canvas.height; const state = proxy.getState(); const isEnterprise = moduleRegistry.hasEnterpriseModules(); const processedOverrides = { ...chart.chartOptions.processedOverrides, container: document.createElement("div"), width: width2, height: height2 }; if (opts.width != null && opts.height != null) { processedOverrides.overrideDevicePixelRatio = 1; } const userOptions = chart.getOptions(); if (isEnterprise) { processedOverrides.animation = { enabled: false }; if (this.licenseManager?.isDisplayWatermark()) { processedOverrides.foreground = { text: this.licenseManager.getWatermarkMessage(), image: { url: `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjU4IiBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMjU4IDQwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjUuNzc5IDI4LjY1N0gxMy4zNTlMMTEuMTczIDM0LjAxMkg1LjY3Mjk3TDE3LjE4MiA3LjA1OTk5SDIxLjk1M0wzMy40NjIgMzQuMDEySDI3Ljk2MkwyNS43NzYgMjguNjU3SDI1Ljc3OVpNMjQuMDY4IDI0LjM5N0wxOS41ODggMTMuNDM0TDE1LjEwNyAyNC4zOTdIMjQuMDY4Wk02Mi4wOTIgMTguODIzSDQ5LjgxN1YyMy4wODZINTYuNzc1QzU2LjU1NSAyNS4yMjIgNTUuNzU1IDI2LjkyNyA1NC4zNzIgMjguMjAyQzUyLjk4OSAyOS40NzYgNTEuMTY2IDMwLjExNSA0OC45MDkgMzAuMTE1QzQ3LjYyMiAzMC4xMTUgNDYuNDUgMjkuODg1IDQ1LjM5MyAyOS40MjNDNDQuMzU4MyAyOC45NzgxIDQzLjQzMjYgMjguMzEzOCA0Mi42OCAyNy40NzZDNDEuOTI3IDI2LjYzOSA0MS4zNDQgMjUuNjMxIDQwLjkzMSAyNC40NTNDNDAuNTE5IDIzLjI3NSA0MC4zMTEgMjEuOTcgNDAuMzExIDIwLjUzN0M0MC4zMTEgMTkuMTA1IDQwLjUxNiAxNy44IDQwLjkzMSAxNi42MjFDNDEuMzQ0IDE1LjQ0MyA0MS45MjcgMTQuNDM2IDQyLjY4IDEzLjU5OEM0My40Mzc2IDEyLjc1NzcgNDQuMzY5NiAxMi4wOTMyIDQ1LjQxMSAxMS42NTFDNDYuNDc4IDExLjE4OSA0Ny42NTYgMTAuOTYgNDguOTQ2IDEwLjk2QzUxLjYxMiAxMC45NiA1My42MzcgMTEuNjAyIDU1LjAyIDEyLjg4NUw1OC4zIDkuNjA0OTlDNTUuODE3IDcuNjY5OTkgNTIuNjc2IDYuNjk5OTkgNDguODcyIDYuNjk5OTlDNDYuNzYgNi42OTk5OSA0NC44NTMgNy4wMzQ5OSA0My4xNTQgNy43MDA5OUM0MS40NTUgOC4zNjc5OSAzOS45OTggOS4zMDM5OSAzOC43ODMgMTAuNTA0QzM3LjU2NyAxMS43MDcgMzYuNjM0IDEzLjE1OCAzNS45NzcgMTQuODU3QzM1LjMxOSAxNi41NTYgMzQuOTk0IDE4LjQ1MSAzNC45OTQgMjAuNTRDMzQuOTk0IDIyLjYzIDM1LjMyOSAyNC40OTQgMzUuOTk1IDI2LjIwNUMzNi42NjIgMjcuOTE2IDM3LjYwNSAyOS4zNzQgMzguODE3IDMwLjU3N0M0MC4wMzIgMzEuNzggNDEuNDg2IDMyLjcxMyA0My4xODggMzMuMzgzQzQ0Ljg4OCAzNC4wNDkgNDYuNzgyIDM0LjM4NCA0OC44NzIgMzQuMzg0QzUwLjk2MSAzNC4zODQgNTIuNzUgMzQuMDQ5IDU0LjM5IDMzLjM4M0M1Ni4wMzEgMzIuNzE2IDU3LjQyNiAzMS43OCA1OC41NzkgMzAuNTc3QzU5LjczMyAyOS4zNzQgNjAuNjE5IDI3LjkxNiA2MS4yMzkgMjYuMjA1QzYxLjg2IDI0LjQ5NCA2Mi4xNyAyMi42MDUgNjIuMTcgMjAuNTRDNjIuMTY5NiAxOS45Njg4IDYyLjE0NDUgMTkuMzk4IDYyLjA5NSAxOC44MjlMNjIuMDkyIDE4LjgyM1pNMTUxLjgxIDE2Ljk4MUMxNTMuNDEgMTQuNjA5IDE1Ny40MTkgMTQuMzU4IDE1OS4wMjIgMTQuMzU4VjE4LjkxQzE1Ni45NTcgMTguOTEgMTU0Ljk4NSAxOC45OTYgMTUzLjc1NyAxOS44OTJDMTUyLjUyOSAyMC43OTIgMTUxLjkxOSAyMS45ODIgMTUxLjkxOSAyMy40NjRWMzMuOTlIMTQ2Ljk2NFYxNC4zNThIMTUxLjczNkwxNTEuODEgMTYuOTgxWk0xNDMuMDExIDE0LjM2MVYzNC4wMzFIMTM4LjI0TDEzOC4xMzEgMzEuMDQ1QzEzNy40NjYgMzIuMDc2IDEzNi41NTEgMzIuOTIxOSAxMzUuNDcxIDMzLjUwNEMxMzQuMzc2IDM0LjA5OSAxMzMuMDY4IDM0LjM5NiAxMzEuNTM2IDM0LjM5NkMxMzAuMiAzNC4zOTYgMTI4Ljk2MyAzNC4xNTIgMTI3LjgyMiAzMy42NjhDMTI2LjcgMzMuMTk2NCAxMjUuNjg5IDMyLjQ5NSAxMjQuODU1IDMxLjYwOUMxMjQuMDE4IDMwLjcyMiAxMjMuMzU0IDI5LjY2MiAxMjIuODcxIDI4LjQyMkMxMjIuMzg0IDI3LjE4NSAxMjIuMTQyIDI1LjgxMSAxMjIuMTQyIDI0LjMwNEMxMjIuMTQyIDIyLjc5OCAxMjIuMzg0IDIxLjM3OCAxMjIuODcxIDIwLjExNkMxMjMuMzU3IDE4Ljg1NCAxMjQuMDE4IDE3Ljc3MiAxMjQuODU1IDE2Ljg3M0MxMjUuNjg4IDE1Ljk3NjQgMTI2LjY5OCAxNS4yNjM2IDEyNy44MjIgMTQuNzhDMTI4Ljk2MyAxNC4yODEgMTMwLjIwMyAxNC4wMzMgMTMxLjUzNiAxNC4wMzNDMTMzLjA0MyAxNC4wMzMgMTM0LjMzIDE0LjMxOCAxMzUuMzk3IDE0Ljg4OEMxMzYuNDYyIDE1LjQ1ODkgMTM3LjM3NSAxNi4yNzggMTM4LjA1NyAxNy4yNzZWMTQuMzYxSDE0My4wMTFaTTEzMi42MzEgMzAuMTMzQzEzNC4yNTYgMzAuMTMzIDEzNS41NjcgMjkuNTk0IDEzNi41NjUgMjguNTEyQzEzNy41NjEgMjcuNDMgMTM4LjA2IDI1Ljk5MSAxMzguMDYgMjQuMTk2QzEzOC4wNiAyMi40MDEgMTM3LjU2MSAyMC45OSAxMzYuNTY1IDE5Ljg5OUMxMzUuNTcgMTguODA3IDEzNC4yNTkgMTguMjU4IDEzMi42MzEgMTguMjU4QzEzMS4wMDMgMTguMjU4IDEyOS43MjkgMTguODA0IDEyOC43MzQgMTkuODk5QzEyNy43MzggMjAuOTkzIDEyNy4yMzkgMjIuNDM4IDEyNy4yMzkgMjQuMjMzQzEyNy4yMzkgMjYuMDI4IDEyNy43MzUgMjcuNDMzIDEyOC43MzQgMjguNTE1QzEyOS43MjkgMjkuNTk0IDEzMS4wMjggMzAuMTM2IDEzMi42MzEgMzAuMTM2VjMwLjEzM1pNOTMuNjk4IDI3Ljg3NkM5My41Nzk1IDI4LjAwMjUgOTMuNDU2NCAyOC4xMjQ2IDkzLjMyOSAyOC4yNDJDOTEuOTQ3IDI5LjUxNiA5MC4xMjMgMzAuMTU1IDg3Ljg2NiAzMC4xNTVDODYuNTggMzAuMTU1IDg1LjQwOCAyOS45MjYgODQuMzUgMjkuNDY0QzgzLjMxNTUgMjkuMDE4OSA4Mi4zODk4IDI4LjM1NDYgODEuNjM3IDI3LjUxN0M4MC44ODQgMjYuNjc5IDgwLjMwMSAyNS42NzIgNzkuODg5IDI0LjQ5NEM3OS40NzYgMjMuMzE1IDc5LjI2OSAyMi4wMSA3OS4yNjkgMjAuNTc4Qzc5LjI2OSAxOS4xNDUgNzkuNDczIDE3Ljg0IDc5Ljg4OSAxNi42NjJDODAuMzAxIDE1LjQ4NCA4MC44ODQgMTQuNDc2IDgxLjYzNyAxMy42MzlDODIuMzk0OSAxMi43OTg3IDgzLjMyNzMgMTIuMTM0MiA4NC4zNjkgMTEuNjkyQzg1LjQzNiAxMS4yMyA4Ni42MTQgMTEgODcuOTAzIDExQzkwLjU3IDExIDkyLjU5NSAxMS42NDIgOTMuOTc3IDEyLjkyNkw5Ny4yNTggOS42NDQ5OUM5NC43NzQgNy43MTA5OSA5MS42MzMgNi43Mzk5OSA4Ny44MjkgNi43Mzk5OUM4NS43MTggNi43Mzk5OSA4My44MTEgNy4wNzQ5OSA4Mi4xMTIgNy43NDE5OUM4MC40MTMgOC40MDc5OSA3OC45NTYgOS4zNDQ5OSA3Ny43NCAxMC41NDVDNzYuNTI1IDExLjc0NyA3NS41OTIgMTMuMTk5IDc0LjkzNCAxNC44OThDNzQuMjc3IDE2LjU5NyA3My45NTEgMTguNDkxIDczLjk1MSAyMC41ODFDNzMuOTUxIDIyLjY3IDc0LjI4NiAyNC41MzQgNzQuOTUzIDI2LjI0NUM3NS42MTkgMjcuOTU3IDc2LjU2MiAyOS40MTQgNzcuNzc0IDMwLjYxN0M3OC45OSAzMS44MiA4MC40NDQgMzIuNzUzIDgyLjE0NiAzMy40MjNDODMuODQ1IDM0LjA5IDg1LjczOSAzNC40MjQgODcuODI5IDM0LjQyNEM4OS45MTkgMzQuNDI0IDkxLjcwOCAzNC4wOSA5My4zNDggMzMuNDIzQzk0LjcxOCAzMi44NjUgOTUuOTE4IDMyLjEyMSA5Ni45NDggMzEuMTkxQzk3LjE0OSAzMS4wMDggOTcuMzQ4IDMwLjgxNSA5Ny41MzcgMzAuNjJMOTMuNzAxIDI3Ljg4NUw5My42OTggMjcuODc2Wk0xMTAuODAyIDE0LjAxNUMxMDkuMTk5IDE0LjAxNSAxMDYuODM2IDE0LjQ3MSAxMDUuNjExIDE2LjE1OEwxMDUuNTM3IDYuMDE1OTlIMTAwLjc2NVYzMy45MzlIMTA1LjcyVjIyLjY0MUMxMDUuNzcxIDIxLjQ2MDcgMTA2LjI4OCAyMC4zNDg4IDEwNy4xNTcgMTkuNTQ4OUMxMDguMDI3IDE4Ljc0OTEgMTA5LjE3OCAxOC4zMjY2IDExMC4zNTggMTguMzc0QzExMy4zOTcgMTguMzc0IDExNC4yNjggMjEuMTU5IDExNC4yNjggMjIuNjQxVjMzLjkzOUgxMTkuMjIzVjIxLjA1OUMxMTkuMjIzIDIxLjA1OSAxMTkuMTQyIDE0LjAxNSAxMTAuODAyIDE0LjAxNVpNMTczLjc2MyAxNC4zNThIMTY5Ljk5OVY4LjcxNDk5SDE2NS4wNDhWMTQuMzU4SDE2MS4yODRWMTguOTE2SDE2NS4wNDhWMzQuMDAzSDE2OS45OTlWMTguOTE2SDE3My43NjNWMTQuMzU4Wk0xOTAuNzg3IDI1LjI2MkMxOTAuMTI5IDI0LjUwMTQgMTg5LjMwNyAyMy44OTk0IDE4OC4zODQgMjMuNTAxQzE4Ny40ODggMjMuMTE3IDE4Ni4zMzEgMjIuNzMyIDE4NC45NDggMjIuMzY0QzE4NC4xNjUgMjIuMTQzOSAxODMuMzkgMjEuODk3OCAxODIuNjIzIDIxLjYyNkMxODIuMTYzIDIxLjQ2MjEgMTgxLjc0MSAyMS4yMDY2IDE4MS4zODMgMjAuODc1QzE4MS4yMzUgMjAuNzQyMSAxODEuMTE4IDIwLjU3ODkgMTgxLjAzOSAyMC4zOTY0QzE4MC45NjEgMjAuMjE0IDE4MC45MjIgMjAuMDE2NiAxODAuOTI3IDE5LjgxOEMxODAuOTI3IDE5LjI3MiAxODEuMTU2IDE4Ljg0NCAxODEuNjI1IDE4LjUxQzE4Mi4xMjEgMTguMTU2IDE4Mi44NjIgMTcuOTc2IDE4My44MjYgMTcuOTc2QzE4NC43OSAxNy45NzYgMTg1LjU4NyAxOC4yMDkgMTg2LjE0OCAxOC42NjhDMTg2LjcwNiAxOS4xMjQgMTg3LjAwNyAxOS43MjUgMTg3LjA3MiAyMC41TDE4Ny4wOTQgMjAuNzgySDE5MS42MzNMMTkxLjYxNyAyMC40NkMxOTEuNTIxIDE4LjQ4NSAxOTAuNzcxIDE2LjkgMTg5LjM4NSAxNS43NUMxODguMDEyIDE0LjYxMiAxODYuMTg1IDE0LjAzMyAxODMuOTYyIDE0LjAzM0MxODIuNDc3IDE0LjAzMyAxODEuMTQxIDE0LjI4NyAxNzkuOTk0IDE0Ljc4NkMxNzguODMxIDE1LjI5MSAxNzcuOTI2IDE1Ljk5NSAxNzcuMjk2IDE2Ljg4MkMxNzYuNjczIDE3Ljc0NTUgMTc2LjMzOCAxOC43ODQgMTc2LjM0MSAxOS44NDlDMTc2LjM0MSAyMS4xNjcgMTc2LjY5OCAyMi4yNDkgMTc3LjM5OSAyMy4wNjRDMTc4LjA2IDIzLjg0MzIgMTc4Ljg5OCAyNC40NTM0IDE3OS44NDIgMjQuODQ0QzE4MC43NDQgMjUuMjE2IDE4MS45MjggMjUuNjA3IDE4My4zNjEgMjZDMTg0LjgwNiAyNi40MSAxODUuODcyIDI2Ljc4NSAxODYuNTMgMjcuMTIzQzE4Ny4xIDI3LjQxNCAxODcuMzc5IDI3Ljg0NSAxODcuMzc5IDI4LjQ0NEMxODcuMzc5IDI5LjA0MiAxODcuMTIyIDI5LjQ2NyAxODYuNTk1IDI5LjgzOUMxODYuMDQzIDMwLjIyNiAxODUuMjM3IDMwLjQyNSAxODQuMjAxIDMwLjQyNUMxODMuMTY2IDMwLjQyNSAxODIuMzk0IDMwLjE3NCAxODEuNzQ5IDI5LjY3NEMxODEuMTEzIDI5LjE4MSAxODAuNzcyIDI4LjU4OSAxODAuNzEgMjcuODY0TDE4MC42ODUgMjcuNTgySDE3Ni4wMTNMMTc2LjAyNSAyNy45MDFDMTc2LjA2NyAyOS4wOTU1IDE3Ni40NzIgMzAuMjQ4NyAxNzcuMTg4IDMxLjIwNkMxNzcuOTA3IDMyLjE4IDE3OC44OTMgMzIuOTU4IDE4MC4xMTggMzMuNTE5QzE4MS4zMzYgMzQuMDc3IDE4Mi43MzIgMzQuMzYyIDE4NC4yNjYgMzQuMzYyQzE4NS44MDEgMzQuMzYyIDE4Ny4xMDkgMzQuMTA4IDE4OC4yMzggMzMuNjA5QzE4OS4zNzYgMzMuMTA0IDE5MC4yNzIgMzIuMzk0IDE5MC45MDEgMzEuNDk0QzE5MS41MzQgMzAuNTkyIDE5MS44NTMgMjkuNTU0IDE5MS44NTMgMjguNDAzQzE5MS44MjggMjcuMTEgMTkxLjQ2NiAyNi4wNTMgMTkwLjc3NyAyNS4yNjJIMTkwLjc4N1oiIGZpbGw9IiM5QjlCOUIiLz4KPHBhdGggZD0iTTI0MS45ODIgMjUuNjU4MlYxNy43MTE3SDIyOC40NDFMMjIwLjQ5NCAyNS42NTgySDI0MS45ODJaIiBmaWxsPSIjOUI5QjlCIi8+CjxwYXRoIGQ9Ik0yNTcuMjM5IDUuOTUwODFIMjQwLjI2NUwyMzIuMjU1IDEzLjg5NzNIMjU3LjIzOVY1Ljk1MDgxWiIgZmlsbD0iIzlCOUI5QiIvPgo8cGF0aCBkPSJNMjEyLjYxMSAzMy42MDQ4TDIxNi42OCAyOS41MzYxSDIzMC40MTJWMzcuNDgyN0gyMTIuNjExVjMzLjYwNDhaIiBmaWxsPSIjOUI5QjlCIi8+CjxwYXRoIGQ9Ik0yMTUuNTk5IDIxLjc4MDNIMjI0LjM3MkwyMzIuMzgyIDEzLjgzMzdIMjE1LjU5OVYyMS43ODAzWiIgZmlsbD0iIzlCOUI5QiIvPgo8cGF0aCBkPSJNMjA2IDMzLjYwNDdIMjEyLjYxMUwyMjAuNDk0IDI1LjY1ODJIMjA2VjMzLjYwNDdaIiBmaWxsPSIjOUI5QjlCIi8+CjxwYXRoIGQ9Ik0yNDAuMjY1IDUuOTUwODFMMjM2LjE5NyAxMC4wMTk0SDIxMC4yNTlWMi4wNzI4OEgyNDAuMjY1VjUuOTUwODFaIiBmaWxsPSIjOUI5QjlCIi8+Cjwvc3ZnPgo=`, width: 170, height: 25, right: 25, bottom: 50, opacity: 0.7 } }; } } const specialOverrides = { ...chart.chartOptions.specialOverrides }; const optionsMetadata = { ...chart.chartOptions.optionMetadata }; const cloneProxy = this.factoryApi.create(userOptions, processedOverrides, specialOverrides, optionsMetadata); await cloneProxy.setState(state); cloneProxy.chart.ctx.zoomManager.updateZoom("chartProxy", chart.ctx.zoomManager.getZoom()); cloneProxy.chart.ctx.legendManager.clearData(); cloneProxy.chart.ctx.legendManager.update(chart.ctx.legendManager.getData()); chart.series.forEach((series, index) => { if (!series.visible) { cloneProxy.chart.series[index].visible = false; } }); const legendPages = []; for (const legend of chart.modulesManager.legends()) { legendPages.push(legend.legend.pagination?.currentPage ?? 0); } for (const legend of cloneProxy.chart.modulesManager.legends()) { const page = legendPages.shift() ?? 0; if (!legend.legend.pagination) continue; legend.legend.pagination.setPage(page); } cloneProxy.chart.update(0 /* FULL */, { forceNodeDataRefresh: true }); await cloneProxy.waitForUpdate(); return cloneProxy; } getEnabledOriginators() { const { chartOptions: { processedOptions, optionMetadata }, ctx: { annotationManager, chartTypeOriginator, zoomManager, legendManager } } = this.chart; const originators = []; if ("annotations" in processedOptions && processedOptions.annotations?.enabled) { originators.push(annotationManager); } const isFinancialChart = optionMetadata.presetType === "price-volume"; if (isFinancialChart) { originators.push(chartTypeOriginator); } if (processedOptions.navigator?.enabled || processedOptions.zoom?.enabled) { originators.push(zoomManager); } if ("legend" in this.chart) { originators.push(legendManager); } return originators; } async setStateOriginators(state, originators) { this.factoryApi.caretaker.restore(state, ...originators); this.chart.ctx.updateService.update(2 /* PROCESS_DATA */, { forceNodeDataRefresh: true }); await this.chart.waitForUpdate(); } }; _AgChartInstanceProxy.chartInstances = /* @__PURE__ */ new WeakMap(); __decorateClass([ ActionOnSet({ oldValue(chart) { if (!chart.destroyed) { chart.publicApi = void 0; } _AgChartInstanceProxy.chartInstances.delete(chart); }, newValue(chart) { if (!chart) return; chart.publicApi = this; _AgChartInstanceProxy.chartInstances.set(chart, this); } }) ], _AgChartInstanceProxy.prototype, "chart", 2); AgChartInstanceProxy = _AgChartInstanceProxy; } }); // packages/ag-charts-community/src/locale/locale.ts var Locale; var init_locale = __esm({ "packages/ag-charts-community/src/locale/locale.ts"() { "use strict"; init_module(); init_proxy(); init_validation2(); Locale = class extends BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.localeText = void 0; } }; __decorateClass([ ObserveChanges((target) => { target.ctx.localeManager.setLocaleText(target.localeText); }), Validate(PLAIN_OBJECT, { optional: true }) ], Locale.prototype, "localeText", 2); __decorateClass([ ObserveChanges((target) => { target.ctx.localeManager.setLocaleTextFormatter(target.getLocaleText); }), Validate(FUNCTION, { optional: true }) ], Locale.prototype, "getLocaleText", 2); } }); // packages/ag-charts-community/src/locale/localeModule.ts var LocaleModule; var init_localeModule = __esm({ "packages/ag-charts-community/src/locale/localeModule.ts"() { "use strict"; init_locale(); LocaleModule = { type: "root", optionsKey: "locale", packageType: "community", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Locale(ctx) }; } }); // packages/ag-charts-community/src/scale/groupedCategoryScale.ts var GroupedCategoryScale; var init_groupedCategoryScale = __esm({ "packages/ag-charts-community/src/scale/groupedCategoryScale.ts"() { "use strict"; init_categoryScale(); GroupedCategoryScale = class extends CategoryScale { getIndex(value) { return super.getIndex(value) ?? this.getMatchIndex(value); } getMatchIndex(value) { const key = JSON.stringify(value); const match = this._domain.find((d) => JSON.stringify(d) === key); if (match != null) { return super.getIndex(match); } } }; } }); // packages/ag-charts-community/src/util/memo.ts function memo(params, fnGenerator) { const serialisedParams = JSON.stringify(params, null, 0); if (!memorizedFns.has(fnGenerator)) { memorizedFns.set(fnGenerator, /* @__PURE__ */ new Map()); } if (!memorizedFns.get(fnGenerator)?.has(serialisedParams)) { memorizedFns.get(fnGenerator)?.set(serialisedParams, fnGenerator(params)); } return memorizedFns.get(fnGenerator)?.get(serialisedParams); } function simpleMemorize(fn) { const primitveCache = /* @__PURE__ */ new Map(); const paramsToKeys = (...params) => { return params.map((v) => { if (typeof v === "object") return v; if (typeof v === "symbol") return v; if (!primitveCache.has(v)) { primitveCache.set(v, { v }); } return primitveCache.get(v); }); }; const empty = {}; const cache = /* @__PURE__ */ new WeakMap(); return (...p) => { const keys = p.length === 0 ? [empty] : paramsToKeys(...p); let currentCache = cache; for (const key of keys.slice(0, -1)) { if (!currentCache.has(key)) { currentCache.set(key, /* @__PURE__ */ new WeakMap()); } currentCache = currentCache.get(key); } const finalKey = keys.at(-1); let cachedValue = currentCache.get(finalKey); if (!cachedValue) { cachedValue = fn(...p); currentCache.set(finalKey, cachedValue); } return cachedValue; }; } var memorizedFns; var init_memo = __esm({ "packages/ag-charts-community/src/util/memo.ts"() { "use strict"; memorizedFns = /* @__PURE__ */ new WeakMap(); } }); // packages/ag-charts-community/src/chart/data/aggregateFunctions.ts function sumValues(values, accumulator = [0, 0]) { for (const value of values) { if (typeof value !== "number") { continue; } if (value < 0) { accumulator[0] += value; } if (value > 0) { accumulator[1] += value; } } return accumulator; } function sum(id, matchGroupId) { const result = { id, matchGroupIds: [matchGroupId], type: "aggregate", aggregateFunction: (values) => sumValues(values) }; return result; } function groupSum(id, matchGroupId) { return { id, type: "aggregate", matchGroupIds: matchGroupId ? [matchGroupId] : void 0, aggregateFunction: (values) => sumValues(values), groupAggregateFunction: (next, acc = [0, 0]) => { acc[0] += next?.[0] ?? 0; acc[1] += next?.[1] ?? 0; return acc; }, round: true }; } function range2(id, matchGroupId) { const result = { id, matchGroupIds: [matchGroupId], type: "aggregate", aggregateFunction: (values) => ContinuousDomain.extendDomain(values) }; return result; } function groupCount(id) { return { id, type: "aggregate", aggregateFunction: () => [0, 1], groupAggregateFunction: (next, acc = [0, 0]) => { acc[0] += next?.[0] ?? 0; acc[1] += next?.[1] ?? 0; return acc; } }; } function groupAverage(id, matchGroupId) { const def = { id, matchGroupIds: matchGroupId ? [matchGroupId] : void 0, type: "aggregate", aggregateFunction: (values) => sumValues(values), groupAggregateFunction: (next, acc = [0, 0, -1]) => { acc[0] += next?.[0] ?? 0; acc[1] += next?.[1] ?? 0; acc[2]++; return acc; }, finalFunction: (acc = [0, 0, 0]) => { const result = acc[0] + acc[1]; if (result >= 0) { return [0, result / acc[2]]; } return [result / acc[2], 0]; }, round: true }; return def; } function area(id, aggFn, matchGroupId) { const result = { id, matchGroupIds: matchGroupId ? [matchGroupId] : void 0, type: "aggregate", aggregateFunction: (values, keyRange = []) => { const keyWidth = keyRange[1] - keyRange[0]; return aggFn.aggregateFunction(values).map((v) => v / keyWidth); }, round: true }; if (aggFn.groupAggregateFunction) { result.groupAggregateFunction = aggFn.groupAggregateFunction; } return result; } function accumulatedValue(onlyPositive) { return () => { let value = 0; return (datum) => { if (!isFiniteNumber(datum)) { return datum; } value += onlyPositive ? Math.max(0, datum) : datum; return value; }; }; } function trailingAccumulatedValue() { return () => { let value = 0; return (datum) => { if (!isFiniteNumber(datum)) { return datum; } const trailingValue = value; value += datum; return trailingValue; }; }; } var init_aggregateFunctions = __esm({ "packages/ag-charts-community/src/chart/data/aggregateFunctions.ts"() { "use strict"; init_main(); init_dataDomain(); } }); // packages/ag-charts-community/src/chart/data/processors.ts function basicContinuousCheckDatumValidation(value) { return value != null && isContinuous(value); } function basicDiscreteCheckDatumValidation(value) { return value != null; } function getValidationFn(scaleType) { switch (scaleType) { case "number": case "log": case "ordinal-time": case "time": case "color": return basicContinuousCheckDatumValidation; default: return basicDiscreteCheckDatumValidation; } } function getValueType(scaleType) { switch (scaleType) { case "number": case "log": case "time": case "color": return "range"; default: return "category"; } } function keyProperty(propName, scaleType, opts = {}) { const result = { property: propName, type: "key", valueType: getValueType(scaleType), validation: getValidationFn(scaleType), ...opts }; return result; } function valueProperty(propName, scaleType, opts = {}) { const result = { property: propName, type: "value", valueType: getValueType(scaleType), validation: getValidationFn(scaleType), ...opts }; return result; } function rowCountProperty(propName, opts = {}) { const result = { property: propName, type: "value", valueType: "range", missingValue: 1, processor: () => () => 1, ...opts }; return result; } function rangedValueProperty(propName, opts = {}) { const { min = -Infinity, max = Infinity, ...defOpts } = opts; return { type: "value", property: propName, valueType: "range", validation: basicContinuousCheckDatumValidation, processor: () => (datum) => isFiniteNumber(datum) ? clamp(min, datum, max) : datum, ...defOpts }; } function accumulativeValueProperty(propName, scaleType, opts = {}) { const { onlyPositive, ...defOpts } = opts; const result = { ...valueProperty(propName, scaleType, defOpts), processor: accumulatedValue(onlyPositive) }; return result; } function trailingAccumulatedValueProperty(propName, scaleType, opts = {}) { const result = { ...valueProperty(propName, scaleType, opts), processor: trailingAccumulatedValue() }; return result; } function groupAccumulativeValueProperty(propName, mode, sum2, opts, scaleType) { return [ valueProperty(propName, scaleType, opts), accumulateGroup(opts.groupId, mode, sum2, opts.separateNegative), ...opts.rangeId != null ? [range2(opts.rangeId, opts.groupId)] : [] ]; } function groupStackValueProperty(propName, scaleType, opts) { return [valueProperty(propName, scaleType, opts), accumulateStack(opts.groupId)]; } function normaliseFnBuilder({ normaliseTo }) { const normalise2 = (val, extent3) => { if (extent3 === 0) return null; const result = (val ?? 0) * normaliseTo / extent3; if (result >= 0) { return Math.min(normaliseTo, result); } return Math.max(-normaliseTo, result); }; return () => () => (columns, valueIndexes, dataGroup) => { const extent3 = normaliseFindExtent(columns, valueIndexes, dataGroup); for (const valueIdx of valueIndexes) { for (const datumIndex of dataGroup.datumIndices[valueIdx]) { const column = columns[valueIdx]; const value = column[datumIndex]; if (value == null) { column[datumIndex] = void 0; continue; } column[datumIndex] = // eslint-disable-next-line sonarjs/no-nested-functions typeof value === "number" ? normalise2(value, extent3) : value.map((v) => normalise2(v, extent3)); } } }; } function normaliseFindExtent(columns, valueIndexes, dataGroup) { const valuesExtent = [0, 0]; for (const valueIdx of valueIndexes) { const column = columns[valueIdx]; for (const datumIndex of dataGroup.datumIndices[valueIdx]) { const value = column[datumIndex]; if (value == null) continue; const valueExtent = typeof value === "number" ? value : Math.max(...value.map((v) => v ?? 0)); const valIdx = valueExtent < 0 ? 0 : 1; if (valIdx === 0) { valuesExtent[valIdx] = Math.min(valuesExtent[valIdx], valueExtent); } else { valuesExtent[valIdx] = Math.max(valuesExtent[valIdx], valueExtent); } } } return Math.max(Math.abs(valuesExtent[0]), valuesExtent[1]); } function normaliseGroupTo(matchGroupIds, normaliseTo) { return { type: "group-value-processor", matchGroupIds, adjust: memo({ normaliseTo }, normaliseFnBuilder) }; } function normalisePropertyFnBuilder({ normaliseTo, zeroDomain, rangeMin, rangeMax }) { const normaliseSpan = normaliseTo[1] - normaliseTo[0]; const normalise2 = (val, start2, span) => { const result = normaliseTo[0] + (val - start2) / span * normaliseSpan; if (span === 0) { return zeroDomain; } else if (result >= normaliseTo[1]) { return normaliseTo[1]; } else if (result < normaliseTo[0]) { return normaliseTo[0]; } return result; }; return () => (pData, pIdx) => { let [start2, end2] = pData.domain.values[pIdx]; if (rangeMin != null) start2 = rangeMin; if (rangeMax != null) end2 = rangeMax; const span = end2 - start2; pData.domain.values[pIdx] = [normaliseTo[0], normaliseTo[1]]; const column = pData.columns[pIdx]; for (let datumIndex = 0; datumIndex < column.length; datumIndex += 1) { column[datumIndex] = normalise2(column[datumIndex], start2, span); } }; } function normalisePropertyTo(property, normaliseTo, zeroDomain, rangeMin, rangeMax) { return { type: "property-value-processor", property, adjust: memo({ normaliseTo, rangeMin, rangeMax, zeroDomain }, normalisePropertyFnBuilder) }; } function animationValidation(valueKeyIds) { return { type: "processor", property: "animationValidation", calculate(result) { const { keys: keysDefs, values: valuesDef } = result.defs; const { input: { count }, domain: { keys: domainKeys, values: domainValues }, keys, columns } = result; let validation = ANIMATION_VALIDATION_UNIQUE_KEYS | ANIMATION_VALIDATION_ORDERED_KEYS; if (count !== 0) { for (let i = 0; validation !== 0 && i < keysDefs.length; i++) { for (const scope of keysDefs[i].scopes) { validation &= animationValidationProcessKey( count, keysDefs[i], domainKeys[i], keys[i].get(scope) ); } } for (let i = 0; validation !== 0 && i < valuesDef.length; i++) { const value = valuesDef[i]; if (!valueKeyIds?.includes(value.id)) continue; validation &= animationValidationProcessKey(count, value, domainValues[i], columns[i]); } } return { uniqueKeys: (validation & ANIMATION_VALIDATION_UNIQUE_KEYS) !== 0, orderedKeys: (validation & ANIMATION_VALIDATION_ORDERED_KEYS) !== 0 }; } }; } function buildGroupAccFn({ mode, separateNegative }) { return () => () => (columns, valueIndexes, dataGroup) => { const acc = [0, 0]; for (const valueIdx of valueIndexes) { for (const datumIndex of dataGroup.datumIndices[valueIdx] ?? []) { const column = columns[valueIdx]; const currentVal = column[datumIndex]; const accIndex = isNegative(currentVal) && separateNegative ? 0 : 1; if (!isFiniteNumber(currentVal)) continue; if (mode === "normal") acc[accIndex] += currentVal; column[datumIndex] = acc[accIndex]; if (mode === "trailing") acc[accIndex] += currentVal; } } }; } function buildGroupWindowAccFn({ mode, sum: sum2 }) { return () => { const lastValues = []; let firstRow = true; return () => { return (columns, valueIndexes, dataGroup) => { let acc = 0; for (const valueIdx of valueIndexes) { const column = columns[valueIdx]; for (const datumIndex of dataGroup.datumIndices[valueIdx] ?? []) { const currentVal = column[datumIndex]; const lastValue = firstRow && sum2 === "current" ? 0 : lastValues[valueIdx]; lastValues[valueIdx] = currentVal; const sumValue = sum2 === "current" ? currentVal : lastValue; if (!isFiniteNumber(currentVal) || !isFiniteNumber(lastValue)) { column[datumIndex] = acc; continue; } if (mode === "normal") { acc += sumValue; } column[datumIndex] = acc; if (mode === "trailing") { acc += sumValue; } } } firstRow = false; }; }; }; } function accumulateGroup(matchGroupId, mode, sum2, separateNegative = false) { let adjust; if (mode.startsWith("window")) { const modeParam = mode.endsWith("-trailing") ? "trailing" : "normal"; adjust = memo({ mode: modeParam, sum: sum2 }, buildGroupWindowAccFn); } else { adjust = memo({ mode, separateNegative }, buildGroupAccFn); } return { type: "group-value-processor", matchGroupIds: [matchGroupId], adjust }; } function groupStackAccFn() { return () => (columns, valueIndexes, dataGroup) => { const acc = new Float64Array(valueIndexes.length); let stackCount = 0; for (const valueIdx of valueIndexes) { const column = columns[valueIdx]; for (const datumIndex of dataGroup.datumIndices[valueIdx] ?? []) { const currentValue = column[datumIndex]; acc[stackCount] = Number.isFinite(currentValue) ? currentValue : NaN; stackCount += 1; column[datumIndex] = acc.subarray(0, stackCount); } } }; } function accumulateStack(matchGroupId) { return { type: "group-value-processor", matchGroupIds: [matchGroupId], adjust: groupStackAccFn }; } function valueIdentifier(value) { return value.id ?? value.property; } function valueIndices(id, previousData, processedData) { const properties = /* @__PURE__ */ new Map(); const previousValues = previousData.defs.values; for (let previousIndex = 0; previousIndex < previousValues.length; previousIndex += 1) { const previousValue = previousValues[previousIndex]; if (previousValue.scopes?.includes(id) === false) continue; const valueId = valueIdentifier(previousValue); if (properties.has(valueId)) return; properties.set(valueId, previousIndex); } const indices = []; const nextValues = processedData.defs.values; for (let nextIndex = 0; nextIndex < nextValues.length; nextIndex += 1) { const nextValue = nextValues[nextIndex]; if (nextValue.scopes?.includes(id) === false) continue; const valueId = valueIdentifier(nextValue); const previousIndex = properties.get(valueId); if (previousIndex == null) return; properties.delete(valueId); indices.push({ previousIndex, nextIndex }); } if (properties.size !== 0) return; return indices; } function columnsEqual(previousColumns, nextColumns, indices, previousDatumIndex, nextDatumIndex) { for (const { previousIndex, nextIndex } of indices) { const previousColumn = previousColumns[previousIndex]; const nextColumn = nextColumns[nextIndex]; const previousValue = previousColumn[previousDatumIndex]; const nextValue = nextColumn[nextDatumIndex]; if (previousValue !== nextValue) { return false; } } return true; } function diff(id, previousData, updateMovedData = true) { return { type: "processor", property: "diff", calculate(processedData, previousValue) { const moved = /* @__PURE__ */ new Map(); const added = /* @__PURE__ */ new Map(); const updated = /* @__PURE__ */ new Map(); const removed = /* @__PURE__ */ new Map(); const previousKeys = previousData.keys; const keys = processedData.keys; const previousColumns = previousData.columns; const columns = processedData.columns; const indices = valueIndices(id, previousData, processedData); if (indices == null) return previousValue; const length2 = Math.max(previousData.input.count, processedData.input.count); for (let i = 0; i < length2; i++) { const hasPreviousDatum = i < previousData.input.count; const hasDatum = i < processedData.input.count; const prevKeys = hasPreviousDatum ? datumKeys(previousKeys, id, i) : void 0; const prevId = prevKeys != null ? createDatumId(prevKeys) : ""; const dKeys = hasDatum ? datumKeys(keys, id, i) : void 0; const datumId = dKeys != null ? createDatumId(dKeys) : ""; if (hasDatum && hasPreviousDatum && prevId === datumId) { if (!columnsEqual(previousColumns, columns, indices, i, i)) { updated.set(datumId, i); } continue; } const removedIndex = removed.get(datumId); if (removedIndex != null) { if (updateMovedData || !columnsEqual(previousColumns, columns, indices, removedIndex, i)) { updated.set(datumId, i); moved.set(datumId, i); } removed.delete(datumId); } else if (hasDatum) { added.set(datumId, i); } const addedIndex = added.get(prevId); if (addedIndex != null) { if (updateMovedData || !columnsEqual(previousColumns, columns, indices, addedIndex, i)) { updated.set(prevId, i); moved.set(prevId, i); } added.delete(prevId); } else if (hasPreviousDatum) { updated.delete(prevId); removed.set(prevId, i); } } const changed = added.size > 0 || updated.size > 0 || removed.size > 0; const value = { changed, added: new Set(added.keys()), updated: new Set(updated.keys()), removed: new Set(removed.keys()), moved: new Set(moved.keys()) }; return { ...previousValue, [id]: value }; } }; } function createDatumId(keys, ...extraKeys) { let result; if (isArray(keys)) { result = keys.map((key) => transformIntegratedCategoryValue(key)).join("___"); } else { result = transformIntegratedCategoryValue(keys); } const primitiveType = typeof result === "string" || typeof result === "number" || typeof result === "boolean" || result instanceof Date; if (primitiveType && extraKeys.length > 0) { result += `___${extraKeys.join("___")}`; } return result; } var SMALLEST_KEY_INTERVAL, LARGEST_KEY_INTERVAL, SORT_DOMAIN_GROUPS, ANIMATION_VALIDATION_UNIQUE_KEYS, ANIMATION_VALIDATION_ORDERED_KEYS, animationValidationProcessKey; var init_processors = __esm({ "packages/ag-charts-community/src/chart/data/processors.ts"() { "use strict"; init_main(); init_memo(); init_number(); init_value(); init_aggregateFunctions(); init_dataModel(); SMALLEST_KEY_INTERVAL = { type: "reducer", property: "smallestKeyInterval", initialValue: Infinity, reducer: () => { let prevX = NaN; return (smallestSoFar = Infinity, keys) => { const nextX = typeof keys[0] === "number" ? keys[0] : Number(keys[0]); const interval = Math.abs(nextX - prevX); prevX = nextX; if (!isNaN(interval) && interval > 0 && interval < smallestSoFar) { return interval; } return smallestSoFar; }; } }; LARGEST_KEY_INTERVAL = { type: "reducer", property: "largestKeyInterval", initialValue: -Infinity, reducer: () => { let prevX = NaN; return (largestSoFar = -Infinity, keys) => { const nextX = typeof keys[0] === "number" ? keys[0] : Number(keys[0]); const interval = Math.abs(nextX - prevX); prevX = nextX; if (!isNaN(interval) && interval > 0 && interval > largestSoFar) { return interval; } return largestSoFar; }; } }; SORT_DOMAIN_GROUPS = { type: "processor", property: "sortedGroupDomain", calculate: ({ domain: { groups } }) => groups?.slice().sort((a, b) => { for (let i = 0; i < a.length; i++) { const result = a[i] - b[i]; if (result !== 0) { return result; } } return 0; }) }; ANIMATION_VALIDATION_UNIQUE_KEYS = 1; ANIMATION_VALIDATION_ORDERED_KEYS = 2; animationValidationProcessKey = (count, def, keyValues, column) => { let validation = ANIMATION_VALIDATION_UNIQUE_KEYS | ANIMATION_VALIDATION_ORDERED_KEYS; if (def.valueType === "category") { if (keyValues.length !== count) validation &= ~ANIMATION_VALIDATION_UNIQUE_KEYS; return validation; } let lastValue = column[0]?.valueOf(); for (let d = 1; validation !== 0 && d < column.length; d++) { const keyValue = column[d]?.valueOf(); if (!Number.isFinite(keyValue) || lastValue > keyValue) validation &= ~ANIMATION_VALIDATION_ORDERED_KEYS; if (Number.isFinite(keyValue) && lastValue === keyValue) validation &= ~ANIMATION_VALIDATION_UNIQUE_KEYS; lastValue = keyValue; } return validation; }; } }); // packages/ag-charts-community/src/chart/axis/tree.ts function ticksToTree(ticks) { const maxDepth = ticks.reduce((depth, tick) => depth < tick.length ? tick.length : depth, 0); const root = new TreeNode(); for (let i = 0; i < ticks.length; i++) { const tick = ticks[i]; while (tick.length < maxDepth) { tick.push(""); } root.insertTick(tick, i); } return root; } function moveSubtree(wm, wp, shift) { const subtrees = wp.index - wm.index; const ratio2 = shift / subtrees; wp.change -= ratio2; wp.shift += shift; wm.change += ratio2; wp.prelim += shift; wp.mod += shift; } function ancestor(vim, v, defaultAncestor) { return v.getSiblings().indexOf(vim.ancestor) >= 0 ? vim.ancestor : defaultAncestor; } function executeShifts({ children }) { let shift = 0; let change = 0; for (let i = children.length - 1; i >= 0; i--) { const w = children[i]; w.prelim += shift; w.mod += shift; change += w.change; shift += w.shift + change; } } function apportion(v, defaultAncestor) { const w = v.getLeftSibling(); if (w) { let vop = v; let vip = v; let vim = w; let vom = vip.getLeftmostSibling(); let sip = vip.mod; let sop = vop.mod; let sim = vim.mod; let som = vom.mod; while (vim.nextRight() && vip.nextLeft()) { vim = vim.nextRight(); vip = vip.nextLeft(); vom = vom.nextLeft(); vop = vop.nextRight(); vop.ancestor = v; const shift = vim.prelim + sim - (vip.prelim + sip) + 1; if (shift > 0) { moveSubtree(ancestor(vim, v, defaultAncestor), v, shift); sip += shift; sop += shift; } sim += vim.mod; sip += vip.mod; som += vom.mod; sop += vop.mod; } if (vim.nextRight() && !vop.nextRight()) { vop.mod += sim - sop; } else { if (vip.nextLeft() && !vom.nextLeft()) { vom.mod += sip - som; } defaultAncestor = v; } } return defaultAncestor; } function firstWalk(node) { const { children } = node; if (children.length) { let [defaultAncestor] = children; for (const child of children) { firstWalk(child); defaultAncestor = apportion(child, defaultAncestor); } executeShifts(node); const midpoint = (children[0].prelim + children.at(-1).prelim) / 2; const leftSibling = node.getLeftSibling(); if (leftSibling) { node.prelim = leftSibling.prelim + 1; node.mod = node.prelim - midpoint; } else { node.prelim = midpoint; } } else { const leftSibling = node.getLeftSibling(); node.prelim = leftSibling ? leftSibling.prelim + 1 : 0; } } function secondWalk(v, m, layout) { v.x = v.prelim + m; v.y = v.depth; layout.insertNode(v); for (const w of v.children) { secondWalk(w, m + v.mod, layout); } } function thirdWalk(v) { const { children } = v; let leafCount = 0; for (const w of children) { thirdWalk(w); if (w.children.length) { leafCount += w.leafCount; } else { leafCount++; } } v.leafCount = leafCount; if (children.length) { v.subtreeLeft = children[0].subtreeLeft; v.subtreeRight = children[children.length - 1].subtreeRight; v.x = (v.subtreeLeft + v.subtreeRight) / 2; } else { v.subtreeLeft = v.x; v.subtreeRight = v.x; } } function treeLayout(ticks) { const layout = new TreeLayout(); const root = ticksToTree(ticks); firstWalk(root); secondWalk(root, -root.prelim, layout); thirdWalk(root); return layout; } var Dimensions, TreeNode, TreeLayout; var init_tree = __esm({ "packages/ag-charts-community/src/chart/axis/tree.ts"() { "use strict"; Dimensions = class { constructor() { this.top = Infinity; this.right = -Infinity; this.bottom = -Infinity; this.left = Infinity; } update(x, y) { if (x > this.right) { this.right = x; } if (x < this.left) { this.left = x; } if (y > this.bottom) { this.bottom = y; } if (y < this.top) { this.top = y; } } }; TreeNode = class _TreeNode { constructor(label = "", parent, refId) { this.label = label; this.parent = parent; this.refId = refId; this.x = 0; this.y = 0; this.subtreeLeft = NaN; this.subtreeRight = NaN; this.children = []; this.leafCount = 0; this.prelim = 0; this.mod = 0; this.ancestor = this; this.change = 0; this.shift = 0; this.index = 0; // screenX is meant to be recomputed from (layout) x when the tree is resized (without performing another layout) this.screenX = 0; this.depth = parent ? parent.depth + 1 : 0; } insertTick(tick, index) { let root = this; for (let i = 0; i < tick.length; i++) { const pathPart = tick[i]; const isNotLeaf = i !== tick.length - 1; const { children } = root; const existingNode = children.find((child) => child.label === pathPart); if (existingNode && isNotLeaf) { root = existingNode; } else { const node = new _TreeNode(pathPart, root, index); node.index = children.length; children.push(node); if (isNotLeaf) { root = node; } } } } getLeftSibling() { return this.index > 0 ? this.parent?.children[this.index - 1] : void 0; } getLeftmostSibling() { return this.index > 0 ? this.parent?.children[0] : void 0; } // traverse the left contour of a subtree, return the successor of v on this contour nextLeft() { return this.children[0]; } // traverse the right contour of a subtree, return the successor of v on this contour nextRight() { return this.children.at(-1); } getSiblings() { return this.parent?.children.filter((_, i) => i !== this.index) ?? []; } }; TreeLayout = class { constructor() { this.dimensions = new Dimensions(); this.nodes = []; this.depth = 0; } insertNode(node) { if (this.depth < node.depth) { this.depth = node.depth; } this.dimensions.update(node.x, node.y); this.nodes.push(node); } scalingX(width2, flip) { let scalingX = 1; if (width2 > 0) { const { left, right } = this.dimensions; scalingX = width2 / (right - left); } if (flip) { scalingX *= -1; } return scalingX; } }; } }); // packages/ag-charts-community/src/chart/axis/groupedCategoryAxis.ts var DepthLabelProperties, DepthTickProperties, DepthProperties, GroupedCategoryAxis; var init_groupedCategoryAxis = __esm({ "packages/ag-charts-community/src/chart/axis/groupedCategoryAxis.ts"() { "use strict"; init_main(); init_groupedCategoryScale(); init_bbox(); init_text(); init_transformable(); init_angle(); init_extent(); init_number(); init_properties(); init_tempUtils(); init_textMeasurer(); init_validation2(); init_processors(); init_label(); init_categoryAxis(); init_tree(); DepthLabelProperties = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; } }; __decorateClass([ Validate(BOOLEAN) ], DepthLabelProperties.prototype, "enabled", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], DepthLabelProperties.prototype, "avoidCollisions", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], DepthLabelProperties.prototype, "color", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], DepthLabelProperties.prototype, "spacing", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], DepthLabelProperties.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], DepthLabelProperties.prototype, "fontWeight", 2); __decorateClass([ Validate(NUMBER.restrict({ min: 1 }), { optional: true }) ], DepthLabelProperties.prototype, "fontSize", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DepthLabelProperties.prototype, "fontFamily", 2); DepthTickProperties = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; } }; __decorateClass([ Validate(BOOLEAN) ], DepthTickProperties.prototype, "enabled", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], DepthTickProperties.prototype, "width", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], DepthTickProperties.prototype, "stroke", 2); DepthProperties = class extends BaseProperties { constructor() { super(...arguments); this.label = new DepthLabelProperties(); this.tick = new DepthTickProperties(); } }; __decorateClass([ Validate(OBJECT) ], DepthProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], DepthProperties.prototype, "tick", 2); GroupedCategoryAxis = class extends CategoryAxis { constructor(moduleCtx) { super(moduleCtx, new GroupedCategoryScale()); // Label scale (labels are positioned between ticks, tick count = label count + 1). // We don't call is `labelScale` for consistency with other axes. this.tickScale = new GroupedCategoryScale(); this.depthOptions = new PropertiesArray(DepthProperties); this.includeInvisibleDomains = true; this.tickScale.paddingInner = 1; this.tickScale.paddingOuter = 0; } resizeTickTree() { if (!this.tickTreeLayout) return; const { nodes } = this.tickTreeLayout; const { range: range4, step, inset, bandwidth } = this.scale; const width2 = Math.abs(range4[1] - range4[0]) - step; const scalingX = this.tickTreeLayout.scalingX(width2, range4[0] > range4[1]); const shiftX = inset + bandwidth / 2; let offsetX = 0; for (const node of nodes) { const screenX = node.x * scalingX; if (offsetX > screenX) { offsetX = screenX; } node.screenX = screenX + shiftX; } for (const node of nodes) { node.screenX -= offsetX; } } getDepthOptionsMap(maxDepth) { const optionsMap = []; const { depthOptions, label } = this; for (let i = 0; i < maxDepth; i++) { optionsMap.push( depthOptions[i]?.label.enabled ?? label.enabled ? { enabled: true, spacing: depthOptions[i]?.label.spacing ?? label.spacing, lineHeight: TextUtils.getLineHeight(depthOptions[i]?.label.fontSize ?? label.fontSize ?? 10), avoidCollisions: depthOptions[i]?.label.avoidCollisions ?? label.avoidCollisions } : { enabled: false, spacing: 0, lineHeight: 0, avoidCollisions: false } ); } return optionsMap; } updateCategoryLabels() { if (!this.computedLayout) return; this.tickLabelGroupSelection.update(this.computedLayout.tickLabelLayout).each((node, datum) => node.setProperties(datum)); } updateAxisLine() { if (!this.computedLayout) return; this.lineNode.visible = this.line.enabled; this.lineNode.stroke = this.line.stroke; this.lineNode.strokeWidth = this.line.width; } computeLayout() { this.updateDirection(); this.updateScale(); this.resizeTickTree(); if (!this.tickTreeLayout?.depth) { return { bbox: BBox.zero, separatorLayout: [], tickLabelLayout: [] }; } const { step } = this.scale; const { title, label, range: range4, depthOptions } = this; const { depth: maxDepth, nodes: treeLabels } = this.tickTreeLayout; const keepEvery = Math.ceil(label.fontSize / step); const rotation = toRadians(this.rotation); const isHorizontal = this.position === "top" || this.position === "bottom"; const sideFlag = label.getSideFlag(); const tickLabelLayout = []; const labelBBoxes = /* @__PURE__ */ new Map(); const tempText2 = new TransformableText(); const { defaultRotation, configuredRotation } = calculateLabelRotation({ rotation: label.rotation, parallel: label.parallel, regularFlipRotation: normalizeAngle360(rotation - Math.PI / 2), parallelFlipRotation: normalizeAngle360(rotation) }); const labelRotation = defaultRotation + configuredRotation; const optionsMap = this.getDepthOptionsMap(maxDepth); const setLabelProps = (datum, index) => { const depth = maxDepth - datum.depth; if (!optionsMap[depth]?.enabled || index % keepEvery !== 0 || !inRange(datum.screenX, range4)) { return false; } const text3 = this.formatTick(datum.label, index - 1); const labelStyles = this.getLabelStyles({ value: text3, depth }, depthOptions[depth]?.label); tempText2.setProperties({ ...labelStyles, text: text3, textAlign: "center", textBaseline: label.parallel ? "hanging" : "bottom", rotation: 0, translationX: 0, translationY: datum.screenX }); return true; }; let maxLeafLabelWidth = 0; const depthLines = {}; treeLabels.forEach((datum, index) => { const depth = maxDepth - datum.depth; const nodeLines = countLines(datum.label); depthLines[depth] ?? (depthLines[depth] = 1); if (depthLines[depth] < nodeLines) { depthLines[depth] = nodeLines; } const isVisible = setLabelProps(datum, index); if (!isVisible || !tempText2.getBBox()) return; labelBBoxes.set(index, tempText2.getBBox()); if (!datum.leafCount) { tempText2.rotation = labelRotation; const { width: width3 } = tempText2.getBBox(); if (maxLeafLabelWidth < width3) { maxLeafLabelWidth = width3; } } }); const idGenerator = createIdsGenerator(); const labelX = sideFlag * optionsMap[0].spacing; const separatorData = /* @__PURE__ */ new Map(); const nestedPadding = (d) => { let v = maxLeafLabelWidth; for (let i = 1; i <= d; i++) { v += optionsMap[i].spacing; if (label.mirrored || i !== d) { v += depthLines[i] * optionsMap[i].lineHeight; } } return v; }; treeLabels.forEach((datum, index) => { if (index === 0) return; const visible = setLabelProps(datum, index); const isLeaf = !datum.children.length; const depth = maxDepth - datum.depth; if (datum.parent) { const separatorX = isLeaf ? datum.x : datum.x - (datum.leafCount - 1) / 2; if (!separatorData.has(separatorX)) { const tickOptions = this.depthOptions[depth]?.tick; let v = maxLeafLabelWidth; for (let i = 0; i <= depth; i++) { v += optionsMap[i].spacing; if (i !== 0) { v += depthLines[i] * optionsMap[i].lineHeight; } } separatorData.set(separatorX, { tickSize: v, tickStroke: tickOptions?.stroke, tickWidth: tickOptions?.enabled !== false ? tickOptions?.width : 0 }); } } if (!visible) return; tempText2.x = labelX; tempText2.y = 0; if (isLeaf) { const { width: width3 } = labelBBoxes.get(index); const angleRatio = getAngleRatioRadians(labelRotation); tempText2.rotation = labelRotation; tempText2.textAlign = "end"; tempText2.textBaseline = "middle"; tempText2.rotationCenterX = labelX - width3 / 2; tempText2.translationX = (optionsMap[depth].spacing - width3) / 2 * angleRatio * sideFlag; if (label.mirrored) { tempText2.translationX += width3; } } else { tempText2.rotation = isHorizontal ? defaultRotation : -Math.PI / 2; tempText2.rotationCenterX = labelX; tempText2.translationX = sideFlag * nestedPadding(depth); } if (optionsMap[depth].avoidCollisions) { const availableRange = isLeaf ? step : datum.leafCount * step; if (tempText2.getBBox().height > availableRange) { labelBBoxes.delete(index); return; } } const { text: text3 = "" } = tempText2; tickLabelLayout.push({ text: text3, visible: true, range: this.scale.range, tickId: idGenerator(text3), fill: tempText2.fill, fontFamily: tempText2.fontFamily, fontSize: tempText2.fontSize, fontStyle: tempText2.fontStyle, fontWeight: tempText2.fontWeight, rotation: tempText2.rotation, rotationCenterX: tempText2.rotationCenterX, textAlign: tempText2.textAlign, textBaseline: tempText2.textBaseline, translationX: tempText2.translationX, translationY: tempText2.translationY, x: tempText2.x, y: tempText2.y }); labelBBoxes.set(index, Transformable.toCanvas(tempText2)); }); const { enabled, stroke: stroke3, width: width2 } = this.line; this.lineNode.datum = { x: 0, y1: range4[0], y2: range4[1] }; this.lineNode.setProperties({ stroke: stroke3, strokeWidth: enabled ? width2 : 0 }); const separatorLayout = [...separatorData.values()]; separatorLayout.push(separatorLayout[0]); const axisBoxes = [this.lineNode.getBBox(), new BBox(0, 0, separatorLayout[0].tickSize * sideFlag, 0)]; if (title.enabled) { this.updateTitle(false, separatorLayout[0].tickSize); axisBoxes.push(title.caption.node.getBBox()); } const mergedBBox = BBox.merge(iterate(labelBBoxes.values(), axisBoxes)); return { bbox: this.getTransformBox(mergedBBox), separatorLayout, tickLabelLayout }; } /** * Creates/removes/updates the scene graph nodes that constitute the axis. * Supposed to be called _manually_ after changing _any_ of the axis properties. * This allows to bulk set axis properties before updating the nodes. * The node changes made by this method are rendered on the next animation frame. * We could schedule this method call automatically on the next animation frame * when any of the axis properties change (the way we do when properties of scene graph's * nodes change), but this will mean that we first wait for the next animation * frame to make changes to the nodes of the axis, then wait for another animation * frame to render those changes. It's nice to have everything update automatically, * but this extra level of async indirection will not just introduce an unwanted delay, * it will also make it harder to reason about the program. */ update() { if (!this.computedLayout) return; const { tickScale, gridLine, gridLength } = this; const { separatorLayout } = this.computedLayout; const ticksData = tickScale.ticks({ nice: false, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity }).map((tick, index) => ({ ...separatorLayout[index], tick, tickId: createDatumId(tick, index), tickLabel: tick.filter(Boolean).join(" - "), translationY: Math.round(tickScale.convert(tick)) })); this.gridLineGroupSelection.update(gridLine.enabled && gridLength ? ticksData : []); this.tickLineGroupSelection.update(this.tick.enabled ? ticksData : []); this.updatePosition(); this.updateCategoryLabels(); this.updateAxisLine(); this.updateGridLines(); this.updateTickLines(); this.updateTitle(); this.resetSelectionNodes(); } calculateLayout() { const { separatorLayout, tickLabelLayout, bbox } = this.computeLayout(); this.computedLayout = { separatorLayout, tickLabelLayout }; return { bbox, primaryTickCount: void 0, niceDomain: this.scale.domain }; } /** * The length of the grid. The grid is only visible in case of a non-zero value. */ onGridVisibilityChange() { this.gridLineGroupSelection.clear(); this.tickLabelGroupSelection.clear(); } updateScale() { super.updateScale(); this.tickScale.range = this.scale.range; this.scale.paddingOuter = this.scale.paddingInner / 2; } processData() { const { direction } = this; const flatDomains = this.boundSeries.filter((s) => s.visible).flatMap((series) => series.getDomain(direction)); this.dataDomain = { domain: extent(flatDomains) ?? this.filterDuplicateArrays(flatDomains), clipped: false }; if (this.isReversed()) { this.dataDomain.domain.reverse(); } const domain = this.dataDomain.domain.map( (datum) => ( // Handle integrated charts data when provided as an object toArray(isObject(datum) && "value" in datum ? datum.value : datum) ) ); this.tickTreeLayout = treeLayout(domain); const orderedDomain = []; for (const node of this.tickTreeLayout.nodes) { if (node.leafCount || node.refId == null) continue; orderedDomain.push(this.dataDomain.domain[node.refId]); } this.scale.domain = sortBasedOnArray(this.dataDomain.domain, orderedDomain); this.tickScale.domain = domain.concat([[""]]); return { animatable: true }; } updateGridLines() { if (!this.gridLength) return; const { width: width2, style } = this.gridLine; const lineSize = this.gridLength * -this.label.getSideFlag(); this.gridLineGroupSelection.each((line, datum, index) => { const { stroke: stroke3, lineDash } = style[index % style.length]; const y = datum.translationY; line.visible = this.inRange(y); line.x1 = 0; line.x2 = lineSize; line.y = y; line.stroke = stroke3; line.strokeWidth = width2; line.lineDash = lineDash; }); } filterDuplicateArrays(array2) { const seen = /* @__PURE__ */ new Set(); return array2.filter((item) => { const key = isArray(item) ? JSON.stringify(item) : item; if (seen.has(key)) return false; seen.add(key); return true; }); } }; GroupedCategoryAxis.className = "GroupedCategoryAxis"; GroupedCategoryAxis.type = "grouped-category"; __decorateClass([ Validate(OBJECT_ARRAY) ], GroupedCategoryAxis.prototype, "depthOptions", 2); } }); // packages/ag-charts-community/src/chart/axis/logAxis.ts var NON_ZERO_NUMBER, LogAxis; var init_logAxis = __esm({ "packages/ag-charts-community/src/chart/axis/logAxis.ts"() { "use strict"; init_main(); init_logScale(); init_default(); init_extent(); init_validation2(); init_numberAxis(); NON_ZERO_NUMBER = predicateWithMessage((value) => isNumber(value) && value !== 0, "a non-zero number"); LogAxis = class extends NumberAxis { constructor(moduleCtx) { super(moduleCtx, new LogScale()); this.min = NaN; this.max = NaN; } normaliseDataDomain(d) { const { min, max } = this; const { extent: extent3, clipped } = normalisedExtentWithMetadata(d, min, max); if (extent3[0] < 0 && extent3[1] > 0 || d[0] < 0 && d[1] > 0) { logger_exports.warn( `The log axis domain crosses zero, the chart data cannot be rendered. See log axis documentation for more information.` ); return { domain: [], clipped }; } else if (extent3[0] === 0 || extent3[1] === 0 || d[0] === 0 || d[1] === 0) { logger_exports.warn( `The log axis domain contains a value of 0, the chart data cannot be rendered. See log axis documentation for more information.` ); return { domain: [], clipped }; } return { domain: extent3, clipped }; } set base(value) { this.scale.base = value; } get base() { return this.scale.base; } defaultDatumFormatter(datum, _fractionDigits) { return String(datum); } defaultLabelFormatter(datum, _fractionDigits) { return String(datum); } }; LogAxis.className = "LogAxis"; LogAxis.type = "log"; __decorateClass([ Validate(AND(NUMBER_OR_NAN, NON_ZERO_NUMBER, LESS_THAN("max"))), Default(NaN) ], LogAxis.prototype, "min", 2); __decorateClass([ Validate(AND(NUMBER_OR_NAN, NON_ZERO_NUMBER, GREATER_THAN("min"))), Default(NaN) ], LogAxis.prototype, "max", 2); } }); // packages/ag-charts-community/src/scene/util/corner.ts var drawCorner; var init_corner = __esm({ "packages/ag-charts-community/src/scene/util/corner.ts"() { "use strict"; drawCorner = (path, { x0, y0, x1, y1, cx, cy }, cornerRadius, move) => { if (move) { path.moveTo(x0, y0); } if (x0 !== x1 || y0 !== y1) { const r0 = Math.atan2(y0 - cy, x0 - cx); const r1 = Math.atan2(y1 - cy, x1 - cx); path.arc(cx, cy, cornerRadius, r0, r1); } else { path.lineTo(x0, y0); } }; } }); // packages/ag-charts-community/src/scene/shape/rect.ts var epsilon, cornerEdges, clippedRoundRect, Rect; var init_rect = __esm({ "packages/ag-charts-community/src/scene/shape/rect.ts"() { "use strict"; init_bbox(); init_extendedPath2D(); init_corner(); init_path(); init_shape(); epsilon = 1e-6; cornerEdges = (leadingEdge, trailingEdge, leadingInset, trailingInset, cornerRadius) => { let leadingClipped = false; let trailingClipped = false; let leading0 = trailingInset - Math.sqrt(Math.max(cornerRadius ** 2 - leadingInset ** 2, 0)); let leading1 = 0; let trailing0 = 0; let trailing1 = leadingInset - Math.sqrt(Math.max(cornerRadius ** 2 - trailingInset ** 2, 0)); if (leading0 > leadingEdge) { leadingClipped = true; leading0 = leadingEdge; leading1 = leadingInset - Math.sqrt(Math.max(cornerRadius ** 2 - (trailingInset - leadingEdge) ** 2)); } else if (leading0 < epsilon) { leading0 = 0; } if (trailing1 > trailingEdge) { trailingClipped = true; trailing0 = trailingInset - Math.sqrt(Math.max(cornerRadius ** 2 - (leadingInset - trailingEdge) ** 2)); trailing1 = trailingEdge; } else if (trailing1 < epsilon) { trailing1 = 0; } return { leading0, leading1, trailing0, trailing1, leadingClipped, trailingClipped }; }; clippedRoundRect = (path, x, y, width2, height2, cornerRadii, clipBBox) => { let { topLeft: topLeftCornerRadius, topRight: topRightCornerRadius, bottomRight: bottomRightCornerRadius, bottomLeft: bottomLeftCornerRadius } = cornerRadii; const maxVerticalCornerRadius = Math.max( topLeftCornerRadius + bottomLeftCornerRadius, topRightCornerRadius + bottomRightCornerRadius ); const maxHorizontalCornerRadius = Math.max( topLeftCornerRadius + topRightCornerRadius, bottomLeftCornerRadius + bottomRightCornerRadius ); if (maxVerticalCornerRadius <= 0 && maxHorizontalCornerRadius <= 0) { if (clipBBox == null) { path.rect(x, y, width2, height2); } else { path.rect(clipBBox.x, clipBBox.y, clipBBox.width, clipBBox.height); } return; } else if (clipBBox == null && topLeftCornerRadius === topRightCornerRadius && topLeftCornerRadius === bottomRightCornerRadius && topLeftCornerRadius === bottomLeftCornerRadius) { path.roundRect(x, y, width2, height2, topLeftCornerRadius); return; } if (width2 < 0) { x += width2; width2 = Math.abs(width2); } if (height2 < 0) { y += height2; height2 = Math.abs(height2); } if (width2 <= 0 || height2 <= 0) return; if (clipBBox == null) { clipBBox = new BBox(x, y, width2, height2); } else { const x0 = Math.max(x, clipBBox.x); const x1 = Math.min(x + width2, clipBBox.x + clipBBox.width); const y0 = Math.max(y, clipBBox.y); const y1 = Math.min(y + height2, clipBBox.y + clipBBox.height); clipBBox = new BBox(x0, y0, x1 - x0, y1 - y0); } const borderScale = Math.max(maxVerticalCornerRadius / height2, maxHorizontalCornerRadius / width2, 1); if (borderScale > 1) { topLeftCornerRadius /= borderScale; topRightCornerRadius /= borderScale; bottomRightCornerRadius /= borderScale; bottomLeftCornerRadius /= borderScale; } let drawTopLeftCorner = true; let drawTopRightCorner = true; let drawBottomRightCorner = true; let drawBottomLeftCorner = true; let topLeftCorner; let topRightCorner; let bottomRightCorner; let bottomLeftCorner; if (drawTopLeftCorner) { const nodes = cornerEdges( clipBBox.height, clipBBox.width, Math.max(x + topLeftCornerRadius - clipBBox.x, 0), Math.max(y + topLeftCornerRadius - clipBBox.y, 0), topLeftCornerRadius ); if (nodes.leadingClipped) drawBottomLeftCorner = false; if (nodes.trailingClipped) drawTopRightCorner = false; const x0 = Math.max(clipBBox.x + nodes.leading1, clipBBox.x); const y0 = Math.max(clipBBox.y + nodes.leading0, clipBBox.y); const x1 = Math.max(clipBBox.x + nodes.trailing1, clipBBox.x); const y1 = Math.max(clipBBox.y + nodes.trailing0, clipBBox.y); const cx = x + topLeftCornerRadius; const cy = y + topLeftCornerRadius; topLeftCorner = { x0, y0, x1, y1, cx, cy }; } if (drawTopRightCorner) { const nodes = cornerEdges( clipBBox.width, clipBBox.height, Math.max(y + topRightCornerRadius - clipBBox.y, 0), Math.max(clipBBox.x + clipBBox.width - (x + width2 - topRightCornerRadius), 0), topRightCornerRadius ); if (nodes.leadingClipped) drawTopLeftCorner = false; if (nodes.trailingClipped) drawBottomRightCorner = false; const x0 = Math.min(clipBBox.x + clipBBox.width - nodes.leading0, clipBBox.x + clipBBox.width); const y0 = Math.max(clipBBox.y + nodes.leading1, clipBBox.y); const x1 = Math.min(clipBBox.x + clipBBox.width - nodes.trailing0, clipBBox.x + clipBBox.width); const y1 = Math.max(clipBBox.y + nodes.trailing1, clipBBox.y); const cx = x + width2 - topRightCornerRadius; const cy = y + topRightCornerRadius; topRightCorner = { x0, y0, x1, y1, cx, cy }; } if (drawBottomRightCorner) { const nodes = cornerEdges( clipBBox.height, clipBBox.width, Math.max(clipBBox.x + clipBBox.width - (x + width2 - bottomRightCornerRadius), 0), Math.max(clipBBox.y + clipBBox.height - (y + height2 - bottomRightCornerRadius), 0), bottomRightCornerRadius ); if (nodes.leadingClipped) drawTopRightCorner = false; if (nodes.trailingClipped) drawBottomLeftCorner = false; const x0 = Math.min(clipBBox.x + clipBBox.width - nodes.leading1, clipBBox.x + clipBBox.width); const y0 = Math.min(clipBBox.y + clipBBox.height - nodes.leading0, clipBBox.y + clipBBox.height); const x1 = Math.min(clipBBox.x + clipBBox.width - nodes.trailing1, clipBBox.x + clipBBox.width); const y1 = Math.min(clipBBox.y + clipBBox.height - nodes.trailing0, clipBBox.y + clipBBox.height); const cx = x + width2 - bottomRightCornerRadius; const cy = y + height2 - bottomRightCornerRadius; bottomRightCorner = { x0, y0, x1, y1, cx, cy }; } if (drawBottomLeftCorner) { const nodes = cornerEdges( clipBBox.width, clipBBox.height, Math.max(clipBBox.y + clipBBox.height - (y + height2 - bottomLeftCornerRadius), 0), Math.max(x + bottomLeftCornerRadius - clipBBox.x, 0), bottomLeftCornerRadius ); if (nodes.leadingClipped) drawBottomRightCorner = false; if (nodes.trailingClipped) drawTopLeftCorner = false; const x0 = Math.max(clipBBox.x + nodes.leading0, clipBBox.x); const y0 = Math.min(clipBBox.y + clipBBox.height - nodes.leading1, clipBBox.y + clipBBox.height); const x1 = Math.max(clipBBox.x + nodes.trailing0, clipBBox.x); const y1 = Math.min(clipBBox.y + clipBBox.height - nodes.trailing1, clipBBox.y + clipBBox.height); const cx = x + bottomLeftCornerRadius; const cy = y + height2 - bottomLeftCornerRadius; bottomLeftCorner = { x0, y0, x1, y1, cx, cy }; } let didMove = false; if (drawTopLeftCorner && topLeftCorner != null) { drawCorner(path, topLeftCorner, topLeftCornerRadius, !didMove); didMove || (didMove = true); } if (drawTopRightCorner && topRightCorner != null) { drawCorner(path, topRightCorner, topRightCornerRadius, !didMove); didMove || (didMove = true); } if (drawBottomRightCorner && bottomRightCorner != null) { drawCorner(path, bottomRightCorner, bottomRightCornerRadius, !didMove); didMove || (didMove = true); } if (drawBottomLeftCorner && bottomLeftCorner != null) { drawCorner(path, bottomLeftCorner, bottomLeftCornerRadius, !didMove); } path.closePath(); }; Rect = class extends Path { constructor() { super(...arguments); this.borderPath = new ExtendedPath2D(); this.x = 0; this.y = 0; this.width = 10; this.height = 10; this.topLeftCornerRadius = 0; this.topRightCornerRadius = 0; this.bottomRightCornerRadius = 0; this.bottomLeftCornerRadius = 0; this.clipBBox = void 0; this.crisp = false; this.lastUpdatePathStrokeWidth = Shape.defaultStyles.strokeWidth; this.effectiveStrokeWidth = Shape.defaultStyles.strokeWidth; this.hittester = super.isPointInPath.bind(this); this.distanceCalculator = super.distanceSquaredTransformedPoint.bind(this); /** * When the rectangle's width or height is less than a pixel * and crisp mode is on, the rectangle will still fit into the pixel, * but will be less opaque to make an effect of holding less space. */ this.microPixelEffectOpacity = 1; } set cornerRadius(cornerRadius) { this.topLeftCornerRadius = cornerRadius; this.topRightCornerRadius = cornerRadius; this.bottomRightCornerRadius = cornerRadius; this.bottomLeftCornerRadius = cornerRadius; } isDirtyPath() { return this.lastUpdatePathStrokeWidth !== this.strokeWidth || Boolean(this.path.isDirty() || this.borderPath.isDirty()); } updatePath() { const { path, borderPath, crisp, topLeftCornerRadius: topLeft, topRightCornerRadius: topRight, bottomRightCornerRadius: bottomRight, bottomLeftCornerRadius: bottomLeft } = this; let { x, y, width: w, height: h, strokeWidth, clipBBox } = this; const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1; const pixelSize = 1 / pixelRatio; let microPixelEffectOpacity = 1; path.clear(true); borderPath.clear(true); if (crisp) { if (w <= pixelSize) { microPixelEffectOpacity *= w / pixelSize; } if (h <= pixelSize) { microPixelEffectOpacity *= h / pixelSize; } w = this.align(x, w); h = this.align(y, h); x = this.align(x); y = this.align(y); clipBBox = clipBBox != null ? new BBox( this.align(clipBBox.x), this.align(clipBBox.y), this.align(clipBBox.x, clipBBox.width), this.align(clipBBox.y, clipBBox.height) ) : void 0; } if (strokeWidth) { if (w < pixelSize) { const lx = x + pixelSize / 2; borderPath.moveTo(lx, y); borderPath.lineTo(lx, y + h); strokeWidth = pixelSize; this.borderClipPath = void 0; } else if (h < pixelSize) { const ly = y + pixelSize / 2; borderPath.moveTo(x, ly); borderPath.lineTo(x + w, ly); strokeWidth = pixelSize; this.borderClipPath = void 0; } else if (strokeWidth < w && strokeWidth < h) { const halfStrokeWidth = strokeWidth / 2; x += halfStrokeWidth; y += halfStrokeWidth; w -= strokeWidth; h -= strokeWidth; const adjustedClipBBox = clipBBox?.clone().shrink(halfStrokeWidth); const cornerRadii = { topLeft: topLeft > 0 ? topLeft - strokeWidth : 0, topRight: topRight > 0 ? topRight - strokeWidth : 0, bottomRight: bottomRight > 0 ? bottomRight - strokeWidth : 0, bottomLeft: bottomLeft > 0 ? bottomLeft - strokeWidth : 0 }; this.borderClipPath = void 0; if (w > 0 && h > 0 && (adjustedClipBBox == null || adjustedClipBBox?.width > 0 && adjustedClipBBox?.height > 0)) { clippedRoundRect(path, x, y, w, h, cornerRadii, adjustedClipBBox); clippedRoundRect(borderPath, x, y, w, h, cornerRadii, adjustedClipBBox); } } else { this.borderClipPath = this.borderClipPath ?? new ExtendedPath2D(); this.borderClipPath.clear(true); this.borderClipPath.rect(x, y, w, h); borderPath.rect(x, y, w, h); } } else { const cornerRadii = { topLeft, topRight, bottomRight, bottomLeft }; this.borderClipPath = void 0; clippedRoundRect(path, x, y, w, h, cornerRadii, clipBBox); } if ([topLeft, topRight, bottomRight, bottomLeft].every((r) => r === 0)) { const bbox = this.getBBox(); this.hittester = bbox.containsPoint.bind(bbox); this.distanceSquared = (hitX, hitY) => this.getBBox().distanceSquared(hitX, hitY); } else { this.hittester = super.isPointInPath; this.distanceCalculator = super.distanceSquaredTransformedPoint; } this.effectiveStrokeWidth = strokeWidth; this.lastUpdatePathStrokeWidth = strokeWidth; this.microPixelEffectOpacity = microPixelEffectOpacity; } computeBBox() { const { x, y, width: width2, height: height2, clipBBox } = this; return clipBBox?.clone() ?? new BBox(x, y, width2, height2); } isPointInPath(x, y) { return this.hittester(x, y); } get midPoint() { return { x: this.x + this.width / 2, y: this.y + this.height / 2 }; } distanceSquared(x, y) { return this.distanceCalculator(x, y); } applyFillAlpha(ctx) { const { fillOpacity, microPixelEffectOpacity, opacity } = this; ctx.globalAlpha *= opacity * fillOpacity * microPixelEffectOpacity; } renderStroke(ctx) { const { stroke: stroke3, effectiveStrokeWidth } = this; if (stroke3 && effectiveStrokeWidth) { const { globalAlpha } = ctx; const { strokeOpacity, lineDash, lineDashOffset, lineCap, lineJoin, borderPath, borderClipPath, opacity, microPixelEffectOpacity } = this; if (borderClipPath) { ctx.clip(borderClipPath.getPath2D()); } this.applyStroke(ctx); ctx.globalAlpha *= opacity * strokeOpacity * microPixelEffectOpacity; ctx.lineWidth = effectiveStrokeWidth; if (lineDash) { ctx.setLineDash(lineDash); } if (lineDashOffset) { ctx.lineDashOffset = lineDashOffset; } if (lineCap) { ctx.lineCap = lineCap; } if (lineJoin) { ctx.lineJoin = lineJoin; } ctx.stroke(borderPath.getPath2D()); ctx.globalAlpha = globalAlpha; } } }; Rect.className = "Rect"; __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "x", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "y", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "width", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "height", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "topLeftCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "topRightCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "bottomRightCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "bottomLeftCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "clipBBox", 2); __decorateClass([ ScenePathChangeDetection() ], Rect.prototype, "crisp", 2); } }); // packages/ag-charts-community/src/chart/background/background.ts var Background; var init_background = __esm({ "packages/ag-charts-community/src/chart/background/background.ts"() { "use strict"; init_module(); init_group(); init_rect(); init_text(); init_proxy(); init_validation2(); Background = class extends BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.rectNode = new Rect(); this.textNode = new Text(); this.fill = "white"; this.node = this.createNode(); this.node.append([this.rectNode, this.textNode]); this.visible = true; this.destroyFns.push( ctx.scene.attachNode(this.node), ctx.layoutManager.addListener("layout:complete", (e) => this.onLayoutComplete(e)) ); } createNode() { return new Group({ name: "background", zIndex: 0 /* CHART_BACKGROUND */ }); } onLayoutComplete(e) { const { width: width2, height: height2 } = e.chart; this.rectNode.width = width2; this.rectNode.height = height2; } }; __decorateClass([ Validate(BOOLEAN), ProxyPropertyOnWrite("node", "visible") ], Background.prototype, "visible", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }), ProxyPropertyOnWrite("rectNode", "fill") ], Background.prototype, "fill", 2); __decorateClass([ Validate(OBJECT, { optional: true }) ], Background.prototype, "image", 2); __decorateClass([ Validate(STRING, { optional: true }), ProxyPropertyOnWrite("textNode") ], Background.prototype, "text", 2); } }); // packages/ag-charts-community/src/chart/background/backgroundModule.ts var BackgroundModule; var init_backgroundModule = __esm({ "packages/ag-charts-community/src/chart/background/backgroundModule.ts"() { "use strict"; init_background(); BackgroundModule = { type: "root", optionsKey: "background", packageType: "community", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Background(ctx) }; } }); // packages/ag-charts-community/src/chart/gridLayout.ts function gridLayout({ orientation, bboxes, maxHeight, maxWidth, itemPaddingY = 0, itemPaddingX = 0, forceResult = false }) { const horizontal = orientation === "horizontal"; const primary = { max: horizontal ? maxWidth : maxHeight, fn: horizontal ? (b) => b.width : (b) => b.height, padding: horizontal ? itemPaddingX : itemPaddingY }; const secondary = { max: horizontal ? maxHeight : maxWidth, fn: horizontal ? (b) => b.height : (b) => b.width, padding: horizontal ? itemPaddingY : itemPaddingX }; let processedBBoxCount = 0; const rawPages = []; while (processedBBoxCount < bboxes.length) { const unprocessedBBoxes = bboxes.slice(processedBBoxCount); const result = processBBoxes(unprocessedBBoxes, processedBBoxCount, primary, secondary, forceResult); if (!result) { return; } processedBBoxCount += result.processedBBoxCount; rawPages.push(result.pageIndices); } return buildPages(rawPages, orientation, bboxes, itemPaddingY, itemPaddingX); } function processBBoxes(bboxes, indexOffset, primary, secondary, forceResult) { const minGuess = 1; let startingGuess = estimateStartingGuess(bboxes, primary); if (startingGuess < minGuess) { if (!forceResult) { return; } startingGuess = minGuess; } let guess = startingGuess; while (guess >= minGuess) { const pageIndices = calculatePage(bboxes, indexOffset, guess, primary, secondary, forceResult); if (pageIndices == null && guess <= minGuess) { return; } if (pageIndices == null) { guess--; continue; } if (typeof pageIndices === "number") { if (pageIndices <= minGuess) { return; } guess = pageIndices < guess && pageIndices > minGuess ? pageIndices : guess; guess--; continue; } const processedBBoxCount = pageIndices.length * pageIndices[0].length; return { processedBBoxCount, pageIndices }; } } function calculatePage(bboxes, indexOffset, primaryCount, primary, secondary, forceResult) { const result = []; let sumSecondary = 0; let currentMaxSecondary = 0; let currentPrimaryIndices = []; const maxPrimaryValues = []; for (let bboxIndex = 0; bboxIndex < bboxes.length; bboxIndex++) { const primaryValueIdx = (bboxIndex + primaryCount) % primaryCount; if (primaryValueIdx === 0) { sumSecondary += currentMaxSecondary; currentMaxSecondary = 0; if (currentPrimaryIndices.length > 0) { result.push(currentPrimaryIndices); } currentPrimaryIndices = []; } const primaryValue = primary.fn(bboxes[bboxIndex]) + primary.padding; maxPrimaryValues[primaryValueIdx] = Math.max(maxPrimaryValues[primaryValueIdx] ?? 0, primaryValue); currentMaxSecondary = Math.max(currentMaxSecondary, secondary.fn(bboxes[bboxIndex]) + secondary.padding); const currentSecondaryDimension = sumSecondary + currentMaxSecondary; const returnResult = !forceResult || result.length > 0; if (currentSecondaryDimension > secondary.max && returnResult) { currentPrimaryIndices = []; break; } const sumPrimary = maxPrimaryValues.reduce((sum2, next) => sum2 + next, 0); if (sumPrimary > primary.max && !forceResult) { if (maxPrimaryValues.length < primaryCount) { return maxPrimaryValues.length; } return; } currentPrimaryIndices.push(bboxIndex + indexOffset); } if (currentPrimaryIndices.length > 0) { result.push(currentPrimaryIndices); } return result.length > 0 ? result : void 0; } function buildPages(rawPages, orientation, bboxes, itemPaddingY, itemPaddingX) { let maxPageWidth = 0; let maxPageHeight = 0; const pages = rawPages.map((indices) => { if (orientation === "horizontal") { indices = transpose(indices); } let endIndex = 0; const columns = indices.map((colIndices) => { const colBBoxes = colIndices.map((bboxIndex) => { endIndex = Math.max(bboxIndex, endIndex); return bboxes[bboxIndex]; }); let columnHeight = 0; let columnWidth = 0; colBBoxes.forEach((bbox) => { columnHeight += bbox.height + itemPaddingY; columnWidth = Math.max(columnWidth, bbox.width + itemPaddingX); }); return { indices: colIndices, bboxes: colBBoxes, columnHeight: Math.ceil(columnHeight), columnWidth: Math.ceil(columnWidth) }; }); let pageWidth = 0; let pageHeight = 0; columns.forEach((column) => { pageWidth += column.columnWidth; pageHeight = Math.max(pageHeight, column.columnHeight); }); maxPageWidth = Math.max(pageWidth, maxPageWidth); maxPageHeight = Math.max(pageHeight, maxPageHeight); return { columns, startIndex: indices[0][0], endIndex, pageWidth, pageHeight }; }); return { pages, maxPageWidth, maxPageHeight }; } function transpose(data) { const result = []; for (const _ of data[0]) { result.push([]); } data.forEach((innerData, dataIdx) => { innerData.forEach((item, itemIdx) => { result[itemIdx][dataIdx] = item; }); }); return result; } function estimateStartingGuess(bboxes, primary) { const n = bboxes.length; let primarySum = 0; for (let bboxIndex = 0; bboxIndex < n; bboxIndex++) { primarySum += primary.fn(bboxes[bboxIndex]) + primary.padding; if (primarySum > primary.max) { const ratio2 = n / bboxIndex; if (ratio2 < 2) { return Math.ceil(n / 2); } return bboxIndex; } } return n; } var init_gridLayout = __esm({ "packages/ag-charts-community/src/chart/gridLayout.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/pagination/pagination.ts var PaginationLabel, PaginationMarkerStyle, PaginationMarker, Pagination; var init_pagination = __esm({ "packages/ag-charts-community/src/chart/pagination/pagination.ts"() { "use strict"; init_group(); init_text(); init_transformable(); init_id(); init_number(); init_properties(); init_proxy(); init_validation2(); init_marker(); PaginationLabel = class extends BaseProperties { constructor() { super(...arguments); this.color = "black"; this.fontStyle = void 0; this.fontWeight = void 0; this.fontSize = 12; this.fontFamily = "Verdana, sans-serif"; } }; __decorateClass([ Validate(COLOR_STRING) ], PaginationLabel.prototype, "color", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], PaginationLabel.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], PaginationLabel.prototype, "fontWeight", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PaginationLabel.prototype, "fontSize", 2); __decorateClass([ Validate(STRING) ], PaginationLabel.prototype, "fontFamily", 2); PaginationMarkerStyle = class extends BaseProperties { constructor() { super(...arguments); this.size = 15; this.fill = void 0; this.fillOpacity = void 0; this.stroke = void 0; this.strokeWidth = 1; this.strokeOpacity = 1; } }; __decorateClass([ Validate(POSITIVE_NUMBER) ], PaginationMarkerStyle.prototype, "size", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], PaginationMarkerStyle.prototype, "fill", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], PaginationMarkerStyle.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], PaginationMarkerStyle.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PaginationMarkerStyle.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO) ], PaginationMarkerStyle.prototype, "strokeOpacity", 2); PaginationMarker = class extends BaseProperties { constructor(parent) { super(); this.parent = parent; this.shape = "triangle"; this.size = 15; this.padding = 8; } }; __decorateClass([ ActionOnSet({ changeValue() { if (this.parent.marker === this) { this.parent.onMarkerShapeChange(); } } }) ], PaginationMarker.prototype, "shape", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PaginationMarker.prototype, "size", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PaginationMarker.prototype, "padding", 2); Pagination = class extends BaseProperties { constructor(chartUpdateCallback, pageUpdateCallback) { super(); this.chartUpdateCallback = chartUpdateCallback; this.pageUpdateCallback = pageUpdateCallback; this.id = createId(this); this.marker = new PaginationMarker(this); this.activeStyle = new PaginationMarkerStyle(); this.inactiveStyle = new PaginationMarkerStyle(); this.highlightStyle = new PaginationMarkerStyle(); this.label = new PaginationLabel(); this.group = new TranslatableGroup({ name: "pagination" }); this.labelNode = new Text(); this.totalPages = 0; this.currentPage = 0; this.translationX = 0; this.translationY = 0; this.nextButtonDisabled = false; this.previousButtonDisabled = false; this._visible = true; this._enabled = true; this._orientation = "vertical"; this.nextButton = new Marker(); this.previousButton = new Marker(); this.labelNode.setProperties({ textBaseline: "middle", fontSize: 12, fontFamily: "Verdana, sans-serif", fill: "black", y: 1 }); this.group.append([this.nextButton, this.previousButton, this.labelNode]); this.update(); this.updateMarkers(); } set visible(value) { this._visible = value; this.updateGroupVisibility(); } get visible() { return this._visible; } set enabled(value) { this._enabled = value; this.updateGroupVisibility(); } get enabled() { return this._enabled; } updateGroupVisibility() { this.group.visible = this.enabled && this.visible; } set orientation(value) { this._orientation = value; switch (value) { case "horizontal": { this.previousButton.rotation = -Math.PI / 2; this.nextButton.rotation = Math.PI / 2; break; } case "vertical": default: { this.previousButton.rotation = 0; this.nextButton.rotation = Math.PI; } } } get orientation() { return this._orientation; } update() { this.updateLabel(); this.updatePositions(); this.enableOrDisableButtons(); } updatePositions() { this.group.translationX = this.translationX; this.group.translationY = this.translationY; this.updateLabelPosition(); this.updateNextButtonPosition(); } updateLabelPosition() { const { size: markerSize, padding: markerPadding } = this.marker; this.nextButton.size = markerSize; this.previousButton.size = markerSize; this.labelNode.x = markerSize / 2 + markerPadding; } updateNextButtonPosition() { const labelBBox = this.labelNode.getBBox(); this.nextButton.translationX = labelBBox.width + (this.marker.size / 2 + this.marker.padding) * 2; } updateLabel() { const { currentPage, totalPages: pages, labelNode, label: { color, fontStyle, fontWeight, fontSize, fontFamily } } = this; labelNode.text = `${currentPage + 1} / ${pages}`; labelNode.fill = color; labelNode.fontStyle = fontStyle; labelNode.fontWeight = fontWeight; labelNode.fontSize = fontSize; labelNode.fontFamily = fontFamily; } updateMarkers() { const { nextButton, previousButton, nextButtonDisabled, previousButtonDisabled, activeStyle, inactiveStyle, highlightStyle, highlightActive } = this; const buttonStyle = (button, disabled) => { if (disabled) { return inactiveStyle; } else if (button === highlightActive) { return highlightStyle; } return activeStyle; }; this.updateMarker(nextButton, buttonStyle("next", nextButtonDisabled)); this.updateMarker(previousButton, buttonStyle("previous", previousButtonDisabled)); } updateMarker(marker, style) { const { shape, size } = this.marker; marker.shape = shape; marker.size = size; marker.fill = style.fill; marker.fillOpacity = style.fillOpacity ?? 1; marker.stroke = style.stroke; marker.strokeWidth = style.strokeWidth; marker.strokeOpacity = style.strokeOpacity; } enableOrDisableButtons() { const { currentPage, totalPages } = this; const zeroPagesToDisplay = totalPages === 0; const onLastPage = currentPage === totalPages - 1; const onFirstPage = currentPage === 0; this.nextButtonDisabled = onLastPage || zeroPagesToDisplay; this.previousButtonDisabled = onFirstPage || zeroPagesToDisplay; } setPage(pageNumber) { pageNumber = clamp(0, pageNumber, Math.max(0, this.totalPages - 1)); if (this.currentPage !== pageNumber) { this.currentPage = pageNumber; this.onPaginationChanged(); } } getCursor(node) { return { previous: this.previousButtonDisabled, next: this.nextButtonDisabled }[node] ? void 0 : "pointer"; } onClick(event, node) { event.preventDefault(); if (node === "next" && !this.nextButtonDisabled) { this.incrementPage(); this.onPaginationChanged(); } else if (node === "previous" && !this.previousButtonDisabled) { this.decrementPage(); this.onPaginationChanged(); } } onMouseHover(node) { this.highlightActive = node; this.updateMarkers(); this.chartUpdateCallback(6 /* SCENE_RENDER */); } onPaginationChanged() { this.pageUpdateCallback(this.currentPage); } incrementPage() { this.currentPage = Math.min(this.currentPage + 1, this.totalPages - 1); } decrementPage() { this.currentPage = Math.max(this.currentPage - 1, 0); } onMarkerShapeChange() { this.updatePositions(); this.updateMarkers(); this.chartUpdateCallback(6 /* SCENE_RENDER */); } attachPagination(node) { node.append(this.group); } getBBox() { return this.group.getBBox(); } computeCSSBounds() { const prev = Transformable.toCanvas(this.previousButton); const next = Transformable.toCanvas(this.nextButton); return { prev, next }; } }; Pagination.className = "Pagination"; __decorateClass([ Validate(OBJECT) ], Pagination.prototype, "marker", 2); __decorateClass([ Validate(OBJECT) ], Pagination.prototype, "activeStyle", 2); __decorateClass([ Validate(OBJECT) ], Pagination.prototype, "inactiveStyle", 2); __decorateClass([ Validate(OBJECT) ], Pagination.prototype, "highlightStyle", 2); __decorateClass([ Validate(OBJECT) ], Pagination.prototype, "label", 2); } }); // packages/ag-charts-community/src/scene/util/changeDetectableProperties.ts var ChangeDetectableProperties; var init_changeDetectableProperties = __esm({ "packages/ag-charts-community/src/scene/util/changeDetectableProperties.ts"() { "use strict"; init_properties(); ChangeDetectableProperties = class extends BaseProperties { constructor() { super(...arguments); this._dirty = true; } markDirty() { this._dirty = true; } markClean(_opts) { this._dirty = false; } isDirty() { return this._dirty; } }; } }); // packages/ag-charts-community/src/chart/marker/util.ts function isSupportedMarkerShape(shape) { return typeof shape === "string" && MARKER_SUPPORTED_SHAPES.has(shape); } var MARKER_SUPPORTED_SHAPES; var init_util2 = __esm({ "packages/ag-charts-community/src/chart/marker/util.ts"() { "use strict"; MARKER_SUPPORTED_SHAPES = /* @__PURE__ */ new Set([ "circle", "cross", "diamond", "heart", "pin", "plus", "square", "star", "triangle" ]); } }); // packages/ag-charts-community/src/chart/series/seriesMarker.ts var MARKER_SHAPE, SeriesMarker; var init_seriesMarker = __esm({ "packages/ag-charts-community/src/chart/series/seriesMarker.ts"() { "use strict"; init_changeDetectable(); init_changeDetectableProperties(); init_validation2(); init_util2(); MARKER_SHAPE = predicateWithMessage( (value) => isSupportedMarkerShape(value) || typeof value === "function", `a marker shape keyword such as 'circle', 'diamond' or 'square' or an object extending the Marker class` ); SeriesMarker = class extends ChangeDetectableProperties { constructor() { super(...arguments); this.enabled = true; this.shape = "circle"; this.size = 6; this.fillOpacity = 1; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; } getStyle() { const { size, shape, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this; return { size, shape, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset }; } getDiameter() { return this.size + this.strokeWidth; } }; __decorateClass([ Validate(BOOLEAN), SceneChangeDetection() ], SeriesMarker.prototype, "enabled", 2); __decorateClass([ Validate(MARKER_SHAPE), SceneChangeDetection() ], SeriesMarker.prototype, "shape", 2); __decorateClass([ Validate(POSITIVE_NUMBER), SceneChangeDetection() ], SeriesMarker.prototype, "size", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }), SceneChangeDetection() ], SeriesMarker.prototype, "fill", 2); __decorateClass([ Validate(RATIO), SceneChangeDetection() ], SeriesMarker.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }), SceneChangeDetection() ], SeriesMarker.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER), SceneChangeDetection() ], SeriesMarker.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO), SceneChangeDetection() ], SeriesMarker.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], SeriesMarker.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], SeriesMarker.prototype, "lineDashOffset", 2); __decorateClass([ Validate(FUNCTION, { optional: true }), SceneChangeDetection() ], SeriesMarker.prototype, "itemStyler", 2); } }); // packages/ag-charts-community/src/chart/series/shapeUtil.ts function applyShapeStyle(shape, style, overrides) { shape.fill = overrides?.fill ?? style.fill; shape.fillOpacity = overrides?.fillOpacity ?? style.fillOpacity ?? 1; shape.stroke = overrides?.stroke ?? style.stroke; shape.strokeOpacity = overrides?.strokeOpacity ?? style.strokeOpacity ?? 1; shape.strokeWidth = overrides?.strokeWidth ?? style.strokeWidth ?? 0; shape.lineDash = overrides?.lineDash ?? style.lineDash; shape.lineDashOffset = overrides?.lineDashOffset ?? style.lineDashOffset ?? 0; } var init_shapeUtil = __esm({ "packages/ag-charts-community/src/chart/series/shapeUtil.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/legend/legendDOMProxy.ts var LegendDOMProxy; var init_legendDOMProxy = __esm({ "packages/ag-charts-community/src/chart/legend/legendDOMProxy.ts"() { "use strict"; init_core(); init_transformable(); init_destroy(); LegendDOMProxy = class { constructor(ctx, idPrefix) { this.idPrefix = idPrefix; this.dirty = true; this.destroyFns = new DestroyFns(); this.itemList = ctx.proxyInteractionService.createProxyContainer({ type: "list", domManagerId: `${idPrefix}-toolbar`, classList: ["ag-charts-proxy-legend-toolbar"], ariaLabel: { id: "ariaLabelLegend" } }); this.paginationGroup = ctx.proxyInteractionService.createProxyContainer({ type: "group", domManagerId: `${idPrefix}-pagination`, classList: ["ag-charts-proxy-legend-pagination"], ariaLabel: { id: "ariaLabelLegendPagination" }, ariaOrientation: "horizontal" }); this.itemDescription = createElement("p"); this.itemDescription.style.display = "none"; this.itemDescription.id = `${idPrefix}-ariaDescription`; this.itemDescription.textContent = this.getItemAriaDescription(ctx.localeManager); this.itemList.getElement().append(this.itemDescription); } destroy() { this.destroyFns.destroy(); } initLegendList(params) { if (!this.dirty) return; const { ctx, itemSelection, datumReader, itemListener } = params; const lm = ctx.localeManager; const count = itemSelection.length; itemSelection.each((markerLabel, datum, index) => { markerLabel.proxyButton?.destroy(); markerLabel.proxyButton = ctx.proxyInteractionService.createProxyElement({ type: "listswitch", textContent: this.getItemAriaText(lm, datumReader.getItemLabel(datum), index, count), ariaChecked: !!markerLabel.datum.enabled, ariaDescribedBy: this.itemDescription.id, parent: this.itemList }); const button = markerLabel.proxyButton; button.addListener("click", (ev) => itemListener.onClick(ev.sourceEvent, markerLabel.datum, button)); button.addListener("dblclick", (ev) => itemListener.onDoubleClick(ev.sourceEvent, markerLabel.datum)); button.addListener("mouseenter", (ev) => itemListener.onHover(ev.sourceEvent, markerLabel)); button.addListener("mouseleave", () => itemListener.onLeave()); button.addListener("contextmenu", (ev) => itemListener.onContextClick(ev.sourceEvent, markerLabel)); button.addListener("blur", () => itemListener.onLeave()); button.addListener("focus", (ev) => itemListener.onHover(ev.sourceEvent, markerLabel)); button.addListener("drag-start", () => { }); }); this.dirty = false; } update(params) { if (params.visible) { this.initLegendList(params); this.updateItemProxyButtons(params); this.updatePaginationProxyButtons(params, true); } this.updateVisibility(params.visible); } updateVisibility(visible) { this.itemList.setHidden(!visible); this.paginationGroup.setHidden(!visible); } updateItemProxyButtons({ itemSelection, group, pagination, interactive }) { const groupBBox = Transformable.toCanvas(group); this.itemList.setBounds(groupBBox); const maxHeight = Math.max(...itemSelection.nodes().map((l) => l.getBBox().height)); itemSelection.each((l, _datum) => { if (l.proxyButton) { const visible = l.pageIndex === pagination.currentPage; const { x, y, height: height2, width: width2 } = Transformable.toCanvas(l); const margin = (maxHeight - height2) / 2; const bbox = { x: x - groupBBox.x, y: y - margin - groupBBox.y, height: maxHeight, width: width2 }; l.proxyButton.setCursor("pointer"); l.proxyButton.setEnabled(interactive && visible); l.proxyButton.setBounds(bbox); } }); } updatePaginationProxyButtons(params, init) { const { pagination } = params; this.paginationGroup.setHidden(!pagination.visible); if (init && "ctx" in params) { const { ctx, oldPages, newPages } = params; const oldNeedsButtons = (oldPages?.length ?? newPages.length) > 1; const newNeedsButtons = newPages.length > 1; if (oldNeedsButtons !== newNeedsButtons) { if (newNeedsButtons) { this.prevButton = ctx.proxyInteractionService.createProxyElement({ type: "button", id: `${this.idPrefix}-prev-page`, textContent: { id: "ariaLabelLegendPagePrevious" }, tabIndex: 0, parent: this.paginationGroup }); this.prevButton.addListener("click", (ev) => this.onPageButton(params, ev, "previous")); this.prevButton.addListener("mouseenter", () => pagination.onMouseHover("previous")); this.prevButton.addListener("mouseleave", () => pagination.onMouseHover(void 0)); this.nextButton ?? (this.nextButton = ctx.proxyInteractionService.createProxyElement({ type: "button", id: `${this.idPrefix}-next-page`, textContent: { id: "ariaLabelLegendPageNext" }, tabIndex: 0, parent: this.paginationGroup })); this.nextButton.addListener("click", (ev) => this.onPageButton(params, ev, "next")); this.nextButton.addListener("mouseenter", () => pagination.onMouseHover("next")); this.nextButton.addListener("mouseleave", () => pagination.onMouseHover(void 0)); } else { this.nextButton?.destroy(); this.prevButton?.destroy(); this.nextButton = void 0; this.prevButton = void 0; } } } const { prev, next } = pagination.computeCSSBounds(); this.prevButton?.setBounds(prev); this.nextButton?.setBounds(next); this.prevButton?.setEnabled(pagination.currentPage !== 0); this.nextButton?.setEnabled(pagination.currentPage !== pagination.totalPages - 1); this.nextButton?.setCursor(pagination.getCursor("next")); this.prevButton?.setCursor(pagination.getCursor("previous")); } onPageButton(params, ev, node) { params.pagination.onClick(ev.sourceEvent, node); this.updatePaginationProxyButtons(params, false); } onDataUpdate(oldData, newData) { this.dirty = oldData.length !== newData.length || oldData.some((_v, index, _a) => { const [newValue, oldValue] = [newData[index], oldData[index]]; return newValue.id !== oldValue.id; }); } onLocaleChanged(localeManager, itemSelection, datumReader) { const count = itemSelection.length; itemSelection.each(({ proxyButton }, datum, index) => { const button = proxyButton?.getElement(); if (button != null) { const label = datumReader.getItemLabel(datum); button.textContent = this.getItemAriaText(localeManager, label, index, count); } }); this.itemDescription.textContent = this.getItemAriaDescription(localeManager); } onPageChange(params) { this.updateItemProxyButtons(params); this.updatePaginationProxyButtons(params, false); } getItemAriaText(localeManager, label, index, count) { if (index >= 0 && label) { index++; return localeManager.t("ariaLabelLegendItem", { label, index, count }); } return localeManager.t("ariaLabelLegendItemUnknown"); } getItemAriaDescription(localeManager) { return localeManager.t("ariaDescriptionLegendItem"); } }; } }); // packages/ag-charts-community/src/chart/legend/legendEvent.ts function makeLegendItemEvent(type, itemId, seriesId, event) { const result = { defaultPrevented: false, apiEvent: { type, itemId, seriesId, event, preventDefault: () => result.defaultPrevented = true } }; return result; } var init_legendEvent = __esm({ "packages/ag-charts-community/src/chart/legend/legendEvent.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/legend/legendMarkerLabel.ts var LegendMarkerLabel; var init_legendMarkerLabel = __esm({ "packages/ag-charts-community/src/chart/legend/legendMarkerLabel.ts"() { "use strict"; init_changeDetectable(); init_group(); init_line(); init_text(); init_transformable(); init_proxy(); init_marker(); LegendMarkerLabel = class extends Translatable(Group) { constructor() { super({ name: "markerLabelGroup" }); this.symbolsGroup = this.appendChild( new Group({ name: "legend-markerLabel-symbols" }) ); this.label = this.appendChild(new Text()); this.enabled = true; this.pageIndex = NaN; this.spacing = 0; this.length = 0; this.isCustomMarker = false; this.marker = this.symbolsGroup.appendChild(new Marker({ zIndex: 1 })); this.line = this.symbolsGroup.appendChild(new Line({ zIndex: 0 })); const { label, line, symbolsGroup } = this; line.visible = false; symbolsGroup.renderToOffscreenCanvas = true; symbolsGroup.optimizeForInfrequentRedraws = true; label.textBaseline = "middle"; label.fontSize = 12; label.fontFamily = "Verdana, sans-serif"; label.fill = "black"; label.y = 1; } destroy() { super.destroy(); this.proxyButton?.destroy(); } setEnabled(enabled) { this.enabled = enabled; this.refreshVisibilities(); } refreshVisibilities() { const opacity = this.enabled ? 1 : 0.5; this.label.opacity = opacity; this.opacity = opacity; } layout() { const { marker, line, length: length2, isCustomMarker } = this; let centerTranslateX = 0; let centerTranslateY = 0; if (marker.visible) { const { size } = marker; const anchor = Marker.anchor(marker.shape); centerTranslateX = (anchor.x - 0.5) * size + length2 / 2; centerTranslateY = (anchor.y - 0.5) * size; if (isCustomMarker) { marker.x = 0; marker.y = 0; marker.translationX = centerTranslateX; marker.translationY = centerTranslateY; } else { marker.x = centerTranslateX; marker.y = centerTranslateY; marker.translationX = 0; marker.translationY = 0; } } if (line.visible) { line.x1 = 0; line.x2 = length2; line.y1 = 0; line.y2 = 0; } } preRender(renderCtx) { const out = super.preRender(renderCtx); this.layout(); return out; } layoutLabel() { const { length: length2, spacing } = this; this.label.x = length2 + spacing; } computeBBox() { this.layout(); return super.computeBBox(); } }; LegendMarkerLabel.className = "MarkerLabel"; __decorateClass([ ProxyPropertyOnWrite("label") ], LegendMarkerLabel.prototype, "text", 2); __decorateClass([ ProxyPropertyOnWrite("label") ], LegendMarkerLabel.prototype, "fontStyle", 2); __decorateClass([ ProxyPropertyOnWrite("label") ], LegendMarkerLabel.prototype, "fontWeight", 2); __decorateClass([ ProxyPropertyOnWrite("label") ], LegendMarkerLabel.prototype, "fontSize", 2); __decorateClass([ ProxyPropertyOnWrite("label") ], LegendMarkerLabel.prototype, "fontFamily", 2); __decorateClass([ ProxyPropertyOnWrite("label", "fill") ], LegendMarkerLabel.prototype, "color", 2); __decorateClass([ ObserveChanges((target) => target.layoutLabel()) ], LegendMarkerLabel.prototype, "spacing", 2); __decorateClass([ ObserveChanges((target) => target.layoutLabel()) ], LegendMarkerLabel.prototype, "length", 2); __decorateClass([ SceneChangeDetection() ], LegendMarkerLabel.prototype, "isCustomMarker", 2); } }); // packages/ag-charts-community/src/chart/legend/legend.ts var LegendLabel, LegendMarker, LegendLine, LegendItem, LegendListeners, ID_LEGEND_VISIBILITY, ID_LEGEND_OTHER_SERIES, Legend; var init_legend = __esm({ "packages/ag-charts-community/src/chart/legend/legend.ts"() { "use strict"; init_main(); init_bbox(); init_group(); init_selection(); init_transformable(); init_id(); init_number(); init_object(); init_properties(); init_proxy(); init_textMeasurer(); init_textWrapper(); init_validation2(); init_gridLayout(); init_marker(); init_pagination(); init_seriesMarker(); init_shapeUtil(); init_legendDOMProxy(); init_legendEvent(); init_legendMarkerLabel(); LegendLabel = class extends BaseProperties { constructor() { super(...arguments); this.maxLength = void 0; this.color = "black"; this.fontStyle = void 0; this.fontWeight = void 0; this.fontSize = 12; this.fontFamily = "Verdana, sans-serif"; } }; __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], LegendLabel.prototype, "maxLength", 2); __decorateClass([ Validate(COLOR_STRING) ], LegendLabel.prototype, "color", 2); __decorateClass([ Validate(FONT_STYLE, { optional: true }) ], LegendLabel.prototype, "fontStyle", 2); __decorateClass([ Validate(FONT_WEIGHT, { optional: true }) ], LegendLabel.prototype, "fontWeight", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LegendLabel.prototype, "fontSize", 2); __decorateClass([ Validate(STRING) ], LegendLabel.prototype, "fontFamily", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], LegendLabel.prototype, "formatter", 2); LegendMarker = class extends BaseProperties { constructor() { super(...arguments); this.shape = void 0; this.size = 15; this.padding = 8; } }; __decorateClass([ Validate(MARKER_SHAPE, { optional: true }) ], LegendMarker.prototype, "shape", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LegendMarker.prototype, "size", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LegendMarker.prototype, "padding", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], LegendMarker.prototype, "strokeWidth", 2); __decorateClass([ Validate(BOOLEAN) ], LegendMarker.prototype, "enabled", 2); LegendLine = class extends BaseProperties { }; __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], LegendLine.prototype, "strokeWidth", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], LegendLine.prototype, "length", 2); LegendItem = class extends BaseProperties { constructor() { super(...arguments); this.paddingX = 16; this.paddingY = 8; this.showSeriesStroke = false; this.marker = new LegendMarker(); this.label = new LegendLabel(); this.line = new LegendLine(); } }; __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], LegendItem.prototype, "maxWidth", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LegendItem.prototype, "paddingX", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LegendItem.prototype, "paddingY", 2); __decorateClass([ Validate(BOOLEAN) ], LegendItem.prototype, "showSeriesStroke", 2); __decorateClass([ Validate(OBJECT) ], LegendItem.prototype, "marker", 2); __decorateClass([ Validate(OBJECT) ], LegendItem.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], LegendItem.prototype, "line", 2); LegendListeners = class extends BaseProperties { }; __decorateClass([ Validate(FUNCTION, { optional: true }) ], LegendListeners.prototype, "legendItemClick", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], LegendListeners.prototype, "legendItemDoubleClick", 2); ID_LEGEND_VISIBILITY = "legend-visibility"; ID_LEGEND_OTHER_SERIES = "legend-other-series"; Legend = class extends BaseProperties { constructor(ctx) { super(); this.ctx = ctx; this.id = createId(this); this.group = new TranslatableGroup({ name: "legend", zIndex: 14 /* LEGEND */ }); this.itemSelection = Selection.select( this.group, LegendMarkerLabel ); this.oldSize = [0, 0]; this.pages = []; this.maxPageSize = [0, 0]; /** Item index to track on re-pagination, so current page updates appropriately. */ this.paginationTrackingIndex = 0; this.truncatedItems = /* @__PURE__ */ new Set(); this._data = []; this.toggleSeries = true; this.item = new LegendItem(); this.listeners = new LegendListeners(); this.enabled = true; this.position = "bottom"; this.spacing = 20; this.destroyFns = []; this.size = [0, 0]; this._visible = true; this.pagination = new Pagination( (type) => ctx.updateService.update(type), (page) => this.updatePageNumber(page) ); this.pagination.attachPagination(this.group); this.destroyFns.push( ctx.contextMenuRegistry.registerDefaultAction({ id: ID_LEGEND_VISIBILITY, type: "legend", label: "contextMenuToggleSeriesVisibility", action: (params) => this.contextToggleVisibility(params) }), ctx.contextMenuRegistry.registerDefaultAction({ id: ID_LEGEND_OTHER_SERIES, type: "legend", label: "contextMenuToggleOtherSeries", action: (params) => this.contextToggleOtherSeries(params) }), ctx.legendManager.addListener("legend-change", this.onLegendDataChange.bind(this)) ); this.destroyFns.push( ctx.layoutManager.registerElement(1 /* Legend */, (e) => this.positionLegend(e)), ctx.localeManager.addListener("locale-changed", () => this.onLocaleChanged()), () => this.group.remove() ); this.domProxy = new LegendDOMProxy(this.ctx, this.id); this.ctx.historyManager.addMementoOriginator(ctx.legendManager); } set data(value) { if (objectsEqual(value, this._data)) return; this.domProxy.onDataUpdate(this._data, value); this._data = value; this.updateGroupVisibility(); } get data() { return this._data; } onLegendDataChange({ legendData = [] }) { if (!this.enabled) return; this.data = legendData.filter((datum) => !datum.hideInLegend); } destroy() { this.ctx.domManager.removeChild("canvas-overlay", `${this.id}-toolbar`); this.ctx.domManager.removeChild("canvas-overlay", `${this.id}-pagination`); this.destroyFns.forEach((f) => f()); this.itemSelection.clear(); this.domProxy.destroy(); } getOrientation() { if (this.orientation !== void 0) { return this.orientation; } switch (this.position) { case "right": case "left": return "vertical"; case "bottom": case "top": return "horizontal"; } } set visible(value) { this._visible = value; this.updateGroupVisibility(); } get visible() { return this._visible; } updateGroupVisibility() { this.group.visible = this.enabled && this.visible && this.data.length > 0; } attachLegend(scene) { scene.appendChild(this.group); } getItemLabel(datum) { const { ctx: { callbackCache } } = this; const { formatter } = this.item.label; if (formatter) { const seriesDatum = datum.datum; return callbackCache.call(formatter, { itemId: datum.itemId, value: datum.label.text, seriesId: datum.seriesId, ...seriesDatum && { datum: seriesDatum } }); } return datum.label.text; } /** * The method is given the desired size of the legend, which only serves as a hint. * The vertically oriented legend will take as much horizontal space as needed, but will * respect the height constraints, and the horizontal legend will take as much vertical * space as needed in an attempt not to exceed the given width. * After the layout is done, the {@link size} will contain the actual size of the legend. * If the actual size is not the same as the previous actual size, the legend will fire * the 'layoutChange' event to communicate that another layout is needed, and the above * process should be repeated. * @param width * @param height */ calcLayout(width2, height2) { const { paddingX, paddingY, label, maxWidth, label: { maxLength = Infinity, fontStyle, fontWeight, fontSize, fontFamily } } = this.item; const data = [...this.data]; if (this.reverseOrder) { data.reverse(); } this.itemSelection.update(data); const bboxes = []; const font3 = TextUtils.toFontString(label); const itemMaxWidthPercentage = 0.8; const maxItemWidth = maxWidth ?? width2 * itemMaxWidthPercentage; const markerWidth = this.calculateMarkerWidth(); this.itemSelection.each((markerLabel, datum) => { markerLabel.fontStyle = fontStyle; markerLabel.fontWeight = fontWeight; markerLabel.fontSize = fontSize; markerLabel.fontFamily = fontFamily; const paddedSymbolWidth = this.updateMarkerLabel(markerLabel, datum, markerWidth); const id = datum.itemId ?? datum.id; const labelText = this.getItemLabel(datum); const text3 = (labelText ?? "").replace(/\r?\n/g, " "); markerLabel.text = this.truncate(text3, maxLength, maxItemWidth, paddedSymbolWidth, font3, id); bboxes.push(markerLabel.getBBox()); }); width2 = Math.max(1, width2); height2 = Math.max(1, height2); if (!isFinite(width2)) { return {}; } const size = this.size; const oldSize = this.oldSize; size[0] = width2; size[1] = height2; if (size[0] !== oldSize[0] || size[1] !== oldSize[1]) { oldSize[0] = size[0]; oldSize[1] = size[1]; } const { pages, maxPageHeight, maxPageWidth } = this.updatePagination(bboxes, width2, height2); const oldPages = this.pages; this.pages = pages; this.maxPageSize = [maxPageWidth - paddingX, maxPageHeight - paddingY]; const pageNumber = this.pagination.currentPage; const page = this.pages[pageNumber]; if (this.pages.length < 1 || !page) { this.visible = false; return { oldPages }; } this.visible = true; this.updatePositions(pageNumber); this.update(); return { oldPages }; } isCustomMarker(markerEnabled, shape) { return markerEnabled && shape !== void 0 && typeof shape !== "string"; } calcSymbolsEnabled(symbol) { const { showSeriesStroke, marker } = this.item; const markerEnabled = !!marker.enabled || !showSeriesStroke || (symbol.marker.enabled ?? true); const lineEnabled = !!(symbol.line && showSeriesStroke); const isCustomMarker = this.isCustomMarker(markerEnabled, symbol.marker.shape); return { markerEnabled, lineEnabled, isCustomMarker }; } calcSymbolsLengths(symbol) { const { marker, line } = this.item; const { markerEnabled, lineEnabled } = this.calcSymbolsEnabled(symbol); const { strokeWidth: markerStrokeWidth } = this.getMarkerStyles(symbol); const { strokeWidth: lineStrokeWidth } = lineEnabled ? this.getLineStyles(symbol) : { strokeWidth: 0 }; let customMarkerSize; const { shape } = symbol.marker; if (this.isCustomMarker(markerEnabled, shape)) { const tmpShape = new Marker(); tmpShape.shape = shape; tmpShape.updatePath(); const bbox = tmpShape.getBBox(); customMarkerSize = Math.max(bbox.width, bbox.height); } const markerLength = markerEnabled ? marker.size : 0; const lineLength = lineEnabled ? line.length ?? 25 : 0; return { markerLength, markerStrokeWidth, lineLength, lineStrokeWidth, customMarkerSize }; } calculateMarkerWidth() { let markerWidth = 0; this.itemSelection.each((_, datum) => { const { symbol } = datum; const { markerLength, lineLength, customMarkerSize = -Infinity } = this.calcSymbolsLengths(symbol); markerWidth = Math.max(markerWidth, lineLength, customMarkerSize, markerLength); }); return markerWidth; } updateMarkerLabel(markerLabel, datum, markerWidth) { const { marker: itemMarker, paddingX } = this.item; const { symbol } = datum; let paddedSymbolWidth = paddingX; const { markerEnabled, lineEnabled, isCustomMarker } = this.calcSymbolsEnabled(symbol); const spacing = itemMarker.padding; if (markerEnabled || lineEnabled) { paddedSymbolWidth += spacing + markerWidth; } const { marker, line } = markerLabel; marker.visible = markerEnabled; if (marker.visible) { marker.shape = itemMarker.shape ?? symbol.marker.shape ?? "square"; marker.size = itemMarker.size; applyShapeStyle(marker, this.getMarkerStyles(symbol)); } line.visible = lineEnabled; if (line.visible) { applyShapeStyle(line, this.getLineStyles(symbol)); } markerLabel.length = markerWidth; markerLabel.spacing = spacing; markerLabel.isCustomMarker = isCustomMarker; return paddedSymbolWidth; } truncate(text3, maxCharLength, maxItemWidth, paddedMarkerWidth, font3, id) { let addEllipsis = false; if (text3.length > maxCharLength) { text3 = text3.substring(0, maxCharLength); addEllipsis = true; } const measurer3 = CachedTextMeasurerPool.getMeasurer({ font: font3 }); const result = TextWrapper.truncateLine(text3, measurer3, maxItemWidth - paddedMarkerWidth, addEllipsis); if (result.endsWith(TextUtils.EllipsisChar)) { this.truncatedItems.add(id); } else { this.truncatedItems.delete(id); } return result; } updatePagination(bboxes, width2, height2) { const orientation = this.getOrientation(); const trackingIndex = Math.min(this.paginationTrackingIndex, bboxes.length); this.pagination.orientation = orientation; this.pagination.translationX = 0; this.pagination.translationY = 0; const { pages, maxPageHeight, maxPageWidth, paginationBBox, paginationVertical } = this.calculatePagination( bboxes, width2, height2 ); const newCurrentPage = pages.findIndex((p) => p.endIndex >= trackingIndex); this.pagination.currentPage = clamp(0, newCurrentPage, pages.length - 1); const { paddingX: itemPaddingX, paddingY: itemPaddingY } = this.item; const paginationComponentPadding = 8; const legendItemsWidth = maxPageWidth - itemPaddingX; const legendItemsHeight = maxPageHeight - itemPaddingY; let paginationX = 0; let paginationY = -paginationBBox.y - this.item.marker.size / 2; if (paginationVertical) { paginationY += legendItemsHeight + paginationComponentPadding; } else { paginationX += -paginationBBox.x + legendItemsWidth + paginationComponentPadding; paginationY += (legendItemsHeight - paginationBBox.height) / 2; } this.pagination.translationX = paginationX; this.pagination.translationY = paginationY; this.pagination.update(); this.pagination.updateMarkers(); let pageIndex = 0; this.itemSelection.each((markerLabel, _, nodeIndex) => { if (nodeIndex > (pages[pageIndex]?.endIndex ?? Infinity)) { pageIndex++; } markerLabel.pageIndex = pageIndex; }); return { maxPageHeight, maxPageWidth, pages }; } calculatePagination(bboxes, width2, height2) { const { paddingX: itemPaddingX, paddingY: itemPaddingY } = this.item; const orientation = this.getOrientation(); const paginationVertical = ["left", "right"].includes(this.position); let paginationBBox = this.pagination.getBBox(); let lastPassPaginationBBox = new BBox(0, 0, 0, 0); let pages = []; let maxPageWidth = 0; let maxPageHeight = 0; let count = 0; const stableOutput = (bbox) => { return bbox.width === paginationBBox.width && bbox.height === paginationBBox.height; }; const forceResult = this.maxWidth !== void 0 && this.maxHeight !== void 0; do { if (count++ > 10) { logger_exports.warn("unable to find stable legend layout."); break; } paginationBBox = lastPassPaginationBBox; const maxWidth = width2 - (paginationVertical ? 0 : paginationBBox.width); const maxHeight = height2 - (paginationVertical ? paginationBBox.height : 0); const layout = gridLayout({ orientation, bboxes, maxHeight, maxWidth, itemPaddingY, itemPaddingX, forceResult }); pages = layout?.pages ?? []; maxPageWidth = layout?.maxPageWidth ?? 0; maxPageHeight = layout?.maxPageHeight ?? 0; const totalPages = pages.length; this.pagination.visible = totalPages > 1; this.pagination.totalPages = totalPages; this.pagination.update(); this.pagination.updateMarkers(); lastPassPaginationBBox = this.pagination.getBBox(); if (!this.pagination.visible) { break; } } while (!stableOutput(lastPassPaginationBBox)); return { maxPageWidth, maxPageHeight, pages, paginationBBox: lastPassPaginationBBox, paginationVertical }; } updatePositions(pageNumber = 0) { const { item: { paddingY }, itemSelection, pages } = this; if (pages.length < 1 || !pages[pageNumber]) { return; } const { columns, startIndex: visibleStart, endIndex: visibleEnd } = pages[pageNumber]; let x = 0; let y = 0; const columnCount = columns.length; const rowCount = columns[0].indices.length; const horizontal = this.getOrientation() === "horizontal"; const itemHeight = columns[0].bboxes[0].height + paddingY; const rowSumColumnWidths = []; itemSelection.each((markerLabel, _, i) => { if (i < visibleStart || i > visibleEnd) { markerLabel.visible = false; return; } const pageIndex = i - visibleStart; let columnIndex; let rowIndex; if (horizontal) { columnIndex = pageIndex % columnCount; rowIndex = Math.floor(pageIndex / columnCount); } else { columnIndex = Math.floor(pageIndex / rowCount); rowIndex = pageIndex % rowCount; } markerLabel.visible = true; const column = columns[columnIndex]; if (!column) { return; } y = Math.floor(itemHeight * rowIndex); x = Math.floor(rowSumColumnWidths[rowIndex] ?? 0); rowSumColumnWidths[rowIndex] = (rowSumColumnWidths[rowIndex] ?? 0) + column.columnWidth; markerLabel.translationX = x; markerLabel.translationY = y; }); } updatePageNumber(pageNumber) { const { itemSelection, group, pagination, pages, toggleSeries: interactive } = this; const { startIndex, endIndex } = pages[pageNumber]; if (startIndex === 0) { this.paginationTrackingIndex = 0; } else if (pageNumber === pages.length - 1) { this.paginationTrackingIndex = endIndex; } else { this.paginationTrackingIndex = Math.floor((startIndex + endIndex) / 2); } this.pagination.update(); this.pagination.updateMarkers(); this.updatePositions(pageNumber); this.domProxy.onPageChange({ itemSelection, group, pagination, interactive }); this.ctx.updateService.update(6 /* SCENE_RENDER */); } update() { const { label: { color } } = this.item; this.itemSelection.each((markerLabel, datum) => { markerLabel.setEnabled(datum.enabled); markerLabel.color = color; }); this.updateContextMenu(); } updateContextMenu() { const { toggleSeries, ctx: { contextMenuRegistry } } = this; if (toggleSeries) { contextMenuRegistry.hideAction(ID_LEGEND_VISIBILITY); contextMenuRegistry.hideAction(ID_LEGEND_OTHER_SERIES); } else { contextMenuRegistry.showAction(ID_LEGEND_VISIBILITY); contextMenuRegistry.showAction(ID_LEGEND_OTHER_SERIES); } } getLineStyles(datum) { const { stroke: stroke3, strokeOpacity = 1, strokeWidth, lineDash } = datum.line ?? {}; const defaultLineStrokeWidth = Math.min(2, strokeWidth ?? 1); return { stroke: stroke3, strokeOpacity, strokeWidth: this.item.line.strokeWidth ?? defaultLineStrokeWidth, lineDash }; } getMarkerStyles(datum) { const { fill, stroke: stroke3, strokeOpacity = 1, fillOpacity = 1, strokeWidth, lineDash, lineDashOffset } = datum.marker; const defaultLineStrokeWidth = Math.min(2, strokeWidth ?? 1); return { fill, stroke: stroke3, strokeOpacity, fillOpacity, strokeWidth: this.item.marker.strokeWidth ?? defaultLineStrokeWidth, lineDash, lineDashOffset }; } computePagedBBox() { const actualBBox = Group.computeChildrenBBox(this.group.children()); if (this.pages.length > 1) { const [maxPageWidth, maxPageHeight] = this.maxPageSize; actualBBox.height = Math.max(maxPageHeight, actualBBox.height); actualBBox.width = Math.max(maxPageWidth, actualBBox.width); } return actualBBox; } findNode(params) { const { datum, proxyButton } = this.itemSelection.select((ml) => ml.datum?.itemId === params.itemId)[0] ?? {}; if (datum === void 0 || proxyButton === void 0) { throw new Error( `AG Charts - Missing required properties { datum: ${datum}, proxyButton: ${JSON.stringify(proxyButton)} }` ); } return { datum, proxyButton }; } contextToggleVisibility(params) { const { datum, proxyButton } = this.findNode(params); this.doClick(params.event, datum, proxyButton); } contextToggleOtherSeries(params) { this.doDoubleClick(params.event, this.findNode(params).datum); } onContextClick(sourceEvent, node) { const legendItem = node.datum; if (this.preventHidingAll && this.contextMenuDatum?.enabled && this.getVisibleItemCount() <= 1) { this.ctx.contextMenuRegistry.disableAction(ID_LEGEND_VISIBILITY); } else { this.ctx.contextMenuRegistry.enableAction(ID_LEGEND_VISIBILITY); } const { offsetX, offsetY } = sourceEvent; const { x: canvasX, y: canvasY } = Transformable.toCanvasPoint(node, offsetX, offsetY); this.ctx.contextMenuRegistry.dispatchContext("legend", { sourceEvent, canvasX, canvasY }, { legendItem }); } onClick(event, datum, proxyButton) { if (this.doClick(event, datum, proxyButton)) { event.preventDefault(); } } getVisibleItemCount() { return this.ctx.chartService.series.flatMap((s) => s.getLegendData("category")).filter((d) => d.enabled).length; } doClick(event, datum, proxyButton) { const { listeners: { legendItemClick }, ctx: { chartService, highlightManager }, preventHidingAll, toggleSeries } = this; if (!datum) { return false; } const { legendType, seriesId, itemId, enabled } = datum; const series = chartService.series.find((s) => s.id === seriesId); if (!series) { return false; } let newEnabled = enabled; const clickEvent = makeLegendItemEvent("click", itemId, series.id, event); legendItemClick?.(clickEvent.apiEvent); if (clickEvent.defaultPrevented) return true; if (toggleSeries) { newEnabled = !enabled; if (preventHidingAll && !newEnabled) { const numVisibleItems = this.getVisibleItemCount(); if (numVisibleItems < 2) { newEnabled = true; } } proxyButton.setChecked(newEnabled); this.ctx.chartEventManager.legendItemClick(legendType, series, itemId, newEnabled, datum.legendItemName); } if (newEnabled) { highlightManager.updateHighlight(this.id, { series, itemId, datum: void 0, datumIndex: void 0 }); } else { highlightManager.updateHighlight(this.id); } this.ctx.legendManager.update(); this.ctx.updateService.update(2 /* PROCESS_DATA */, { forceNodeDataRefresh: true, skipAnimations: datum.skipAnimations ?? false }); return true; } onDoubleClick(event, datum) { if (this.doDoubleClick(event, datum)) { event.preventDefault(); } } doDoubleClick(event, datum) { const { listeners: { legendItemDoubleClick }, ctx: { chartService }, toggleSeries } = this; if (chartService.mode === "integrated") { return false; } if (!datum) { return false; } const { legendType, id, itemId, seriesId } = datum; const series = chartService.series.find((s) => s.id === id); if (!series) { return false; } const doubleClickEvent = makeLegendItemEvent("dblclick", itemId, series.id, event); legendItemDoubleClick?.(doubleClickEvent.apiEvent); if (doubleClickEvent.defaultPrevented) return true; if (toggleSeries) { const legendData = chartService.series.flatMap((s) => s.getLegendData("category")); const numVisibleItems = legendData.filter((d) => d.enabled).length; const clickedItem = legendData.find((d) => d.itemId === itemId && d.seriesId === seriesId); this.ctx.chartEventManager.legendItemDoubleClick( legendType, series, itemId, clickedItem?.enabled ?? false, numVisibleItems, clickedItem?.legendItemName ); } this.ctx.legendManager.update(); this.ctx.updateService.update(2 /* PROCESS_DATA */, { forceNodeDataRefresh: true }); return true; } toTooltipMeta(event, node) { let lastPointerEvent; if (event instanceof FocusEvent) { const { x, y } = Transformable.toCanvas(node).computeCenter(); lastPointerEvent = { type: "keyboard", canvasX: x, canvasY: y }; } else { event.preventDefault(); const { x, y } = Transformable.toCanvasPoint(node, event.offsetX, event.offsetY); lastPointerEvent = { type: "pointermove", canvasX: x, canvasY: y }; } const { canvasX, canvasY } = lastPointerEvent; return { canvasX, canvasY, lastPointerEvent, showArrow: false }; } onHover(event, node) { if (!this.enabled) throw new Error("AG Charts - onHover handler called on disabled legend"); this.pagination.setPage(node.pageIndex); const datum = node.datum; const series = datum ? this.ctx.chartService.series.find((s) => s.id === datum?.id) : void 0; if (datum && this.truncatedItems.has(datum.itemId ?? datum.id)) { const meta = this.toTooltipMeta(event, node); this.ctx.tooltipManager.updateTooltip(this.id, meta, { type: "structured", title: this.getItemLabel(datum) }); } else { this.ctx.tooltipManager.removeTooltip(this.id); } if (datum?.enabled && series) { this.updateHighlight({ series, itemId: datum?.itemId, datum: void 0, datumIndex: void 0 }); } else { this.updateHighlight(); } } onLeave() { this.ctx.tooltipManager.removeTooltip(this.id); this.updateHighlight(); } updateHighlight(datum) { if (this.ctx.interactionManager.isState(32 /* Default */)) { this.ctx.highlightManager.updateHighlight(this.id, datum); } else if (this.ctx.interactionManager.isState(2 /* Animation */)) { this.pendingHighlightDatum = datum; this.ctx.animationManager.onBatchStop(() => { this.ctx.highlightManager.updateHighlight(this.id, this.pendingHighlightDatum); }); } } onLocaleChanged() { this.domProxy.onLocaleChanged(this.ctx.localeManager, this.itemSelection, this); } positionLegend(ctx) { const oldPages = this.positionLegendScene(ctx); this.positionLegendDOM(oldPages); } positionLegendScene(ctx) { if (!this.enabled || !this.data.length) return; const { layoutBox } = ctx; const { x, y, width: width2, height: height2 } = layoutBox; const [legendWidth, legendHeight] = this.calculateLegendDimensions(layoutBox); const { oldPages } = this.calcLayout(legendWidth, legendHeight); const legendBBox = this.computePagedBBox(); const calculateTranslationPerpendicularDimension = () => { switch (this.position) { case "top": case "left": return 0; case "bottom": return height2 - legendBBox.height; case "right": default: return width2 - legendBBox.width; } }; if (this.visible) { const legendPadding = this.spacing; let translationX; let translationY; switch (this.position) { case "top": case "bottom": translationX = (width2 - legendBBox.width) / 2; translationY = calculateTranslationPerpendicularDimension(); layoutBox.shrink(legendBBox.height + legendPadding, this.position); break; case "left": case "right": default: translationX = calculateTranslationPerpendicularDimension(); translationY = (height2 - legendBBox.height) / 2; layoutBox.shrink(legendBBox.width + legendPadding, this.position); } this.group.translationX = Math.floor(x + translationX - legendBBox.x); this.group.translationY = Math.floor(y + translationY - legendBBox.y); } return oldPages; } positionLegendDOM(oldPages) { const { ctx, itemSelection, pagination, pages: newPages, toggleSeries, group, listeners: { legendItemClick, legendItemDoubleClick } } = this; const visible = this.visible && this.enabled; const interactive = toggleSeries || legendItemDoubleClick != null || legendItemClick != null; this.domProxy.update({ visible, interactive, ctx, itemSelection, group, pagination, oldPages, newPages, datumReader: this, itemListener: this }); } calculateLegendDimensions(shrinkRect) { const { width: width2, height: height2 } = shrinkRect; const aspectRatio = width2 / height2; const maxCoefficient = 0.5; const minHeightCoefficient = 0.2; const minWidthCoefficient = 0.25; let legendWidth, legendHeight; switch (this.position) { case "top": case "bottom": { const heightCoefficient = aspectRatio < 1 ? Math.min(maxCoefficient, minHeightCoefficient * (1 / aspectRatio)) : minHeightCoefficient; legendWidth = this.maxWidth ? Math.min(this.maxWidth, width2) : width2; legendHeight = this.maxHeight ? Math.min(this.maxHeight, height2) : Math.round(height2 * heightCoefficient); break; } case "left": case "right": default: { const widthCoefficient = aspectRatio > 1 ? Math.min(maxCoefficient, minWidthCoefficient * aspectRatio) : minWidthCoefficient; legendWidth = this.maxWidth ? Math.min(this.maxWidth, width2) : Math.round(width2 * widthCoefficient); legendHeight = this.maxHeight ? Math.min(this.maxHeight, height2) : height2; } } return [legendWidth, legendHeight]; } }; Legend.className = "Legend"; __decorateClass([ Validate(BOOLEAN) ], Legend.prototype, "toggleSeries", 2); __decorateClass([ Validate(OBJECT) ], Legend.prototype, "pagination", 2); __decorateClass([ Validate(OBJECT) ], Legend.prototype, "item", 2); __decorateClass([ Validate(OBJECT) ], Legend.prototype, "listeners", 2); __decorateClass([ ObserveChanges((target, newValue, oldValue) => { target.updateGroupVisibility(); if (newValue === oldValue) { return; } const { ctx: { legendManager, stateManager } } = target; if (oldValue === false && newValue === true) { stateManager.restoreState(legendManager); } }), Validate(BOOLEAN) ], Legend.prototype, "enabled", 2); __decorateClass([ Validate(POSITION) ], Legend.prototype, "position", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], Legend.prototype, "maxWidth", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], Legend.prototype, "maxHeight", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], Legend.prototype, "reverseOrder", 2); __decorateClass([ Validate(UNION(["horizontal", "vertical"], "an orientation"), { optional: true }) ], Legend.prototype, "orientation", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], Legend.prototype, "preventHidingAll", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], Legend.prototype, "spacing", 2); } }); // packages/ag-charts-community/src/chart/legend/legendModule.ts var CommunityLegendModule; var init_legendModule = __esm({ "packages/ag-charts-community/src/chart/legend/legendModule.ts"() { "use strict"; init_legend(); CommunityLegendModule = { type: "legend", optionsKey: "legend", identifier: "category", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Legend(ctx), packageType: "community", removable: "standalone-only" }; } }); // packages/ag-charts-community/src/chart/themes/constants.ts var constants_exports = {}; __export(constants_exports, { CARTESIAN_AXIS_TYPE: () => CARTESIAN_AXIS_TYPE, CARTESIAN_POSITION: () => CARTESIAN_POSITION, FONT_SIZE: () => FONT_SIZE, FONT_SIZE_RATIO: () => FONT_SIZE_RATIO, POLAR_AXIS_SHAPE: () => POLAR_AXIS_SHAPE, POLAR_AXIS_TYPE: () => POLAR_AXIS_TYPE }); var FONT_SIZE, FONT_SIZE_RATIO, CARTESIAN_POSITION, CARTESIAN_AXIS_TYPE, POLAR_AXIS_TYPE, POLAR_AXIS_SHAPE; var init_constants = __esm({ "packages/ag-charts-community/src/chart/themes/constants.ts"() { "use strict"; FONT_SIZE = /* @__PURE__ */ ((FONT_SIZE2) => { FONT_SIZE2[FONT_SIZE2["SMALLEST"] = 8] = "SMALLEST"; FONT_SIZE2[FONT_SIZE2["SMALLER"] = 10] = "SMALLER"; FONT_SIZE2[FONT_SIZE2["SMALL"] = 12] = "SMALL"; FONT_SIZE2[FONT_SIZE2["MEDIUM"] = 13] = "MEDIUM"; FONT_SIZE2[FONT_SIZE2["LARGE"] = 14] = "LARGE"; FONT_SIZE2[FONT_SIZE2["LARGEST"] = 17] = "LARGEST"; return FONT_SIZE2; })(FONT_SIZE || {}); FONT_SIZE_RATIO = /* @__PURE__ */ ((FONT_SIZE_RATIO5) => { FONT_SIZE_RATIO5[FONT_SIZE_RATIO5["SMALLEST"] = 0.6666666666666666] = "SMALLEST"; FONT_SIZE_RATIO5[FONT_SIZE_RATIO5["SMALLER"] = 0.8333333333333334] = "SMALLER"; FONT_SIZE_RATIO5[FONT_SIZE_RATIO5["SMALL"] = 1] = "SMALL"; FONT_SIZE_RATIO5[FONT_SIZE_RATIO5["MEDIUM"] = 1.0833333333333333] = "MEDIUM"; FONT_SIZE_RATIO5[FONT_SIZE_RATIO5["LARGE"] = 1.1666666666666667] = "LARGE"; FONT_SIZE_RATIO5[FONT_SIZE_RATIO5["LARGEST"] = 1.4166666666666667] = "LARGEST"; return FONT_SIZE_RATIO5; })(FONT_SIZE_RATIO || {}); CARTESIAN_POSITION = /* @__PURE__ */ ((CARTESIAN_POSITION8) => { CARTESIAN_POSITION8["TOP"] = "top"; CARTESIAN_POSITION8["RIGHT"] = "right"; CARTESIAN_POSITION8["BOTTOM"] = "bottom"; CARTESIAN_POSITION8["LEFT"] = "left"; return CARTESIAN_POSITION8; })(CARTESIAN_POSITION || {}); CARTESIAN_AXIS_TYPE = /* @__PURE__ */ ((CARTESIAN_AXIS_TYPE12) => { CARTESIAN_AXIS_TYPE12["CATEGORY"] = "category"; CARTESIAN_AXIS_TYPE12["GROUPED_CATEGORY"] = "grouped-category"; CARTESIAN_AXIS_TYPE12["ORDINAL_TIME"] = "ordinal-time"; CARTESIAN_AXIS_TYPE12["NUMBER"] = "number"; CARTESIAN_AXIS_TYPE12["TIME"] = "time"; CARTESIAN_AXIS_TYPE12["LOG"] = "log"; return CARTESIAN_AXIS_TYPE12; })(CARTESIAN_AXIS_TYPE || {}); POLAR_AXIS_TYPE = /* @__PURE__ */ ((POLAR_AXIS_TYPE11) => { POLAR_AXIS_TYPE11["ANGLE_CATEGORY"] = "angle-category"; POLAR_AXIS_TYPE11["ANGLE_NUMBER"] = "angle-number"; POLAR_AXIS_TYPE11["RADIUS_CATEGORY"] = "radius-category"; POLAR_AXIS_TYPE11["RADIUS_NUMBER"] = "radius-number"; return POLAR_AXIS_TYPE11; })(POLAR_AXIS_TYPE || {}); POLAR_AXIS_SHAPE = /* @__PURE__ */ ((POLAR_AXIS_SHAPE3) => { POLAR_AXIS_SHAPE3["CIRCLE"] = "circle"; POLAR_AXIS_SHAPE3["POLYGON"] = "polygon"; return POLAR_AXIS_SHAPE3; })(POLAR_AXIS_SHAPE || {}); } }); // packages/ag-charts-community/src/chart/themes/symbols.ts var symbols_exports = {}; __export(symbols_exports, { DEFAULT_ANNOTATION_HANDLE_FILL: () => DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_ANNOTATION_STATISTICS_COLOR: () => DEFAULT_ANNOTATION_STATISTICS_COLOR, DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, DEFAULT_ANNOTATION_STATISTICS_FILL: () => DEFAULT_ANNOTATION_STATISTICS_FILL, DEFAULT_ANNOTATION_STATISTICS_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_STROKE, DEFAULT_BACKGROUND_COLOUR: () => DEFAULT_BACKGROUND_COLOUR, DEFAULT_CAPTION_ALIGNMENT: () => DEFAULT_CAPTION_ALIGNMENT, DEFAULT_CAPTION_LAYOUT_STYLE: () => DEFAULT_CAPTION_LAYOUT_STYLE, DEFAULT_COLOR_RANGE: () => DEFAULT_COLOR_RANGE, DEFAULT_DIVERGING_SERIES_COLOR_RANGE: () => DEFAULT_DIVERGING_SERIES_COLOR_RANGE, DEFAULT_FIBONACCI_STROKES: () => DEFAULT_FIBONACCI_STROKES, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_FUNNEL_SERIES_COLOR_RANGE: () => DEFAULT_FUNNEL_SERIES_COLOR_RANGE, DEFAULT_GAUGE_SERIES_COLOR_RANGE: () => DEFAULT_GAUGE_SERIES_COLOR_RANGE, DEFAULT_GRIDLINE_ENABLED: () => DEFAULT_GRIDLINE_ENABLED, DEFAULT_HIERARCHY_FILLS: () => DEFAULT_HIERARCHY_FILLS, DEFAULT_HIERARCHY_STROKES: () => DEFAULT_HIERARCHY_STROKES, DEFAULT_POLAR_SERIES_STROKE: () => DEFAULT_POLAR_SERIES_STROKE, DEFAULT_SEPARATION_LINES_COLOUR: () => DEFAULT_SEPARATION_LINES_COLOUR, DEFAULT_SHADOW_COLOUR: () => DEFAULT_SHADOW_COLOUR, DEFAULT_SPARKLINE_CROSSHAIR_STROKE: () => DEFAULT_SPARKLINE_CROSSHAIR_STROKE, DEFAULT_TEXTBOX_COLOR: () => DEFAULT_TEXTBOX_COLOR, DEFAULT_TEXTBOX_FILL: () => DEFAULT_TEXTBOX_FILL, DEFAULT_TEXTBOX_STROKE: () => DEFAULT_TEXTBOX_STROKE, DEFAULT_TEXT_ANNOTATION_COLOR: () => DEFAULT_TEXT_ANNOTATION_COLOR, DEFAULT_TOOLBAR_POSITION: () => DEFAULT_TOOLBAR_POSITION, IS_COMMUNITY: () => IS_COMMUNITY, IS_DARK_THEME: () => IS_DARK_THEME, IS_ENTERPRISE: () => IS_ENTERPRISE, PALETTE_ALT_DOWN_FILL: () => PALETTE_ALT_DOWN_FILL, PALETTE_ALT_DOWN_STROKE: () => PALETTE_ALT_DOWN_STROKE, PALETTE_ALT_NEUTRAL_FILL: () => PALETTE_ALT_NEUTRAL_FILL, PALETTE_ALT_NEUTRAL_STROKE: () => PALETTE_ALT_NEUTRAL_STROKE, PALETTE_ALT_UP_FILL: () => PALETTE_ALT_UP_FILL, PALETTE_ALT_UP_STROKE: () => PALETTE_ALT_UP_STROKE, PALETTE_DOWN_FILL: () => PALETTE_DOWN_FILL, PALETTE_DOWN_STROKE: () => PALETTE_DOWN_STROKE, PALETTE_NEUTRAL_FILL: () => PALETTE_NEUTRAL_FILL, PALETTE_NEUTRAL_STROKE: () => PALETTE_NEUTRAL_STROKE, PALETTE_UP_FILL: () => PALETTE_UP_FILL, PALETTE_UP_STROKE: () => PALETTE_UP_STROKE }); var IS_DARK_THEME, IS_COMMUNITY, IS_ENTERPRISE, DEFAULT_SEPARATION_LINES_COLOUR, DEFAULT_BACKGROUND_COLOUR, DEFAULT_SHADOW_COLOUR, DEFAULT_CAPTION_LAYOUT_STYLE, DEFAULT_CAPTION_ALIGNMENT, PALETTE_UP_STROKE, PALETTE_DOWN_STROKE, PALETTE_UP_FILL, PALETTE_DOWN_FILL, PALETTE_NEUTRAL_STROKE, PALETTE_NEUTRAL_FILL, PALETTE_ALT_UP_STROKE, PALETTE_ALT_DOWN_STROKE, PALETTE_ALT_UP_FILL, PALETTE_ALT_DOWN_FILL, PALETTE_ALT_NEUTRAL_FILL, PALETTE_ALT_NEUTRAL_STROKE, DEFAULT_POLAR_SERIES_STROKE, DEFAULT_DIVERGING_SERIES_COLOR_RANGE, DEFAULT_COLOR_RANGE, DEFAULT_SPARKLINE_CROSSHAIR_STROKE, DEFAULT_GAUGE_SERIES_COLOR_RANGE, DEFAULT_FUNNEL_SERIES_COLOR_RANGE, DEFAULT_HIERARCHY_FILLS, DEFAULT_HIERARCHY_STROKES, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_FIBONACCI_STROKES, DEFAULT_TEXT_ANNOTATION_COLOR, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_ANNOTATION_STATISTICS_FILL, DEFAULT_ANNOTATION_STATISTICS_STROKE, DEFAULT_ANNOTATION_STATISTICS_COLOR, DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, DEFAULT_TEXTBOX_FILL, DEFAULT_TEXTBOX_STROKE, DEFAULT_TEXTBOX_COLOR, DEFAULT_TOOLBAR_POSITION, DEFAULT_GRIDLINE_ENABLED; var init_symbols = __esm({ "packages/ag-charts-community/src/chart/themes/symbols.ts"() { "use strict"; IS_DARK_THEME = Symbol("is-dark-theme"); IS_COMMUNITY = Symbol("is-community"); IS_ENTERPRISE = Symbol("is-enterprise"); DEFAULT_SEPARATION_LINES_COLOUR = Symbol("default-separation-lines-colour"); DEFAULT_BACKGROUND_COLOUR = Symbol("default-background-colour"); DEFAULT_SHADOW_COLOUR = Symbol("default-shadow-colour"); DEFAULT_CAPTION_LAYOUT_STYLE = Symbol("default-caption-layout-style"); DEFAULT_CAPTION_ALIGNMENT = Symbol("default-caption-alignment"); PALETTE_UP_STROKE = Symbol("palette-up-stroke"); PALETTE_DOWN_STROKE = Symbol("palette-down-stroke"); PALETTE_UP_FILL = Symbol("palette-up-fill"); PALETTE_DOWN_FILL = Symbol("palette-down-fill"); PALETTE_NEUTRAL_STROKE = Symbol("palette-neutral-stroke"); PALETTE_NEUTRAL_FILL = Symbol("palette-neutral-fill"); PALETTE_ALT_UP_STROKE = Symbol("palette-alt-up-stroke"); PALETTE_ALT_DOWN_STROKE = Symbol("palette-alt-down-stroke"); PALETTE_ALT_UP_FILL = Symbol("palette-alt-up-fill"); PALETTE_ALT_DOWN_FILL = Symbol("palette-alt-down-fill"); PALETTE_ALT_NEUTRAL_FILL = Symbol("palette-gray-fill"); PALETTE_ALT_NEUTRAL_STROKE = Symbol("palette-gray-stroke"); DEFAULT_POLAR_SERIES_STROKE = Symbol("default-polar-series-stroke"); DEFAULT_DIVERGING_SERIES_COLOR_RANGE = Symbol( "default-diverging-series-colour-range" ); DEFAULT_COLOR_RANGE = Symbol("default-colour-range"); DEFAULT_SPARKLINE_CROSSHAIR_STROKE = Symbol("default-sparkline-crosshair-stroke"); DEFAULT_GAUGE_SERIES_COLOR_RANGE = Symbol("default-gauge-series-colour-range"); DEFAULT_FUNNEL_SERIES_COLOR_RANGE = Symbol("default-funnel-series-colour-range"); DEFAULT_HIERARCHY_FILLS = Symbol("default-hierarchy-fills"); DEFAULT_HIERARCHY_STROKES = Symbol("default-hierarchy-strokes"); DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR = Symbol( "default-financial-charts-annotation-stroke" ); DEFAULT_FIBONACCI_STROKES = Symbol("default-hierarchy-strokes"); DEFAULT_TEXT_ANNOTATION_COLOR = Symbol("default-text-annotation-color"); DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL = Symbol( "default-financial-charts-annotation-background-fill" ); DEFAULT_ANNOTATION_HANDLE_FILL = Symbol("default-annotation-handle-fill"); DEFAULT_ANNOTATION_STATISTICS_FILL = Symbol("default-annotation-statistics-fill"); DEFAULT_ANNOTATION_STATISTICS_STROKE = Symbol("default-annotation-statistics-stroke"); DEFAULT_ANNOTATION_STATISTICS_COLOR = Symbol("default-annotation-statistics-color"); DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE = Symbol( "default-annotation-statistics-divider-stroke" ); DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL = Symbol( "default-annotation-statistics-fill" ); DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE = Symbol( "default-annotation-statistics-stroke" ); DEFAULT_TEXTBOX_FILL = Symbol("default-textbox-fill"); DEFAULT_TEXTBOX_STROKE = Symbol("default-textbox-stroke"); DEFAULT_TEXTBOX_COLOR = Symbol("default-textbox-color"); DEFAULT_TOOLBAR_POSITION = Symbol("default-toolbar-position"); DEFAULT_GRIDLINE_ENABLED = Symbol("default-gridline-enabled"); } }); // packages/ag-charts-community/src/chart/themes/util.ts function swapAxisCondition(axes, swap) { return (series) => { if (!swap(series)) return axes; return [ { ...axes[0], position: axes[1].position }, { ...axes[1], position: axes[0].position } ]; }; } function singleSeriesPaletteFactory({ takeColors }) { const { fills: [fill], strokes: [stroke3] } = takeColors(1); return { fill, stroke: stroke3 }; } function markerPaletteFactory(params) { return { marker: singleSeriesPaletteFactory(params) }; } var init_util3 = __esm({ "packages/ag-charts-community/src/chart/themes/util.ts"() { "use strict"; } }); // packages/ag-charts-community/src/motion/pathMotion.ts function pathMotion(groupId, subId, animationManager, paths, fns) { const { addPhaseFn, updatePhaseFn, removePhaseFn } = fns; const animate = (phase, path, updateFn) => { animationManager.animate({ id: `${groupId}_${subId}_${path.id}_${phase}`, groupId, from: 0, to: 1, ease: easeOut, collapsable: false, onUpdate(ratio2, preInit) { if (preInit && phase !== "removed") return; path.path.clear(true); updateFn(ratio2, path); path.checkPathDirty(); }, onStop() { if (phase !== "added") return; path.path.clear(true); updateFn(1, path); path.checkPathDirty(); }, phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[phase] }); }; for (const path of paths) { if (!animationManager.isSkipped()) { animate("removed", path, removePhaseFn); animate("updated", path, updatePhaseFn); } animate("added", path, addPhaseFn); } } var init_pathMotion = __esm({ "packages/ag-charts-community/src/motion/pathMotion.ts"() { "use strict"; init_easing(); init_fromToMotion(); } }); // packages/ag-charts-community/src/chart/series/seriesLabelUtil.ts function seriesLabelFadeInAnimation({ id }, subId, animationManager, ...labelSelections) { staticFromToMotion( id, subId, animationManager, labelSelections, { opacity: 0 }, { opacity: 1 }, { phase: "trailing" } ); } function seriesLabelFadeOutAnimation({ id }, subId, animationManager, ...labelSelections) { staticFromToMotion( id, subId, animationManager, labelSelections, { opacity: 1 }, { opacity: 0 }, { phase: "remove" } ); } function resetLabelFn(_node) { return { opacity: 1 }; } var init_seriesLabelUtil = __esm({ "packages/ag-charts-community/src/chart/series/seriesLabelUtil.ts"() { "use strict"; init_fromToMotion(); } }); // packages/ag-charts-community/src/scene/dropShadow.ts var DropShadow; var init_dropShadow = __esm({ "packages/ag-charts-community/src/scene/dropShadow.ts"() { "use strict"; init_validation2(); init_node(); init_changeDetectableProperties(); DropShadow = class extends ChangeDetectableProperties { constructor() { super(...arguments); this.enabled = true; this.color = "rgba(0, 0, 0, 0.5)"; this.xOffset = 0; this.yOffset = 0; this.blur = 5; } }; __decorateClass([ Validate(BOOLEAN), SceneChangeDetection() ], DropShadow.prototype, "enabled", 2); __decorateClass([ Validate(COLOR_STRING), SceneChangeDetection() ], DropShadow.prototype, "color", 2); __decorateClass([ Validate(NUMBER), SceneChangeDetection() ], DropShadow.prototype, "xOffset", 2); __decorateClass([ Validate(NUMBER), SceneChangeDetection() ], DropShadow.prototype, "yOffset", 2); __decorateClass([ Validate(POSITIVE_NUMBER), SceneChangeDetection() ], DropShadow.prototype, "blur", 2); } }); // packages/ag-charts-community/src/chart/series/seriesTooltip.ts var SeriesTooltipInteraction, SeriesTooltip; var init_seriesTooltip = __esm({ "packages/ag-charts-community/src/chart/series/seriesTooltip.ts"() { "use strict"; init_properties(); init_validation2(); init_tooltip(); SeriesTooltipInteraction = class extends BaseProperties { constructor() { super(...arguments); this.enabled = false; } }; __decorateClass([ Validate(BOOLEAN) ], SeriesTooltipInteraction.prototype, "enabled", 2); SeriesTooltip = class extends BaseProperties { constructor() { super(...arguments); this.enabled = true; this.interaction = new SeriesTooltipInteraction(); this.position = new TooltipPosition(); this.range = void 0; this.class = void 0; } formatTooltip(content, params) { const overrides = this.renderer?.(params); if (typeof overrides === "string") return { type: "raw", rawHtmlString: overrides }; if (overrides != null) return { type: "structured", ...content, ...overrides }; return { type: "structured", ...content }; } }; __decorateClass([ Validate(BOOLEAN) ], SeriesTooltip.prototype, "enabled", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], SeriesTooltip.prototype, "showArrow", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], SeriesTooltip.prototype, "renderer", 2); __decorateClass([ Validate(OBJECT) ], SeriesTooltip.prototype, "interaction", 2); __decorateClass([ Validate(OBJECT) ], SeriesTooltip.prototype, "position", 2); __decorateClass([ Validate(INTERACTION_RANGE, { optional: true }) ], SeriesTooltip.prototype, "range", 2); __decorateClass([ Validate(STRING, { optional: true }) ], SeriesTooltip.prototype, "class", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/interpolationProperties.ts var INTERPOLATION_TYPE, INTERPOLATION_STEP_POSITION, InterpolationProperties; var init_interpolationProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/interpolationProperties.ts"() { "use strict"; init_properties(); init_validation2(); INTERPOLATION_TYPE = UNION(["linear", "smooth", "step"], "a line style"); INTERPOLATION_STEP_POSITION = UNION(["start", "middle", "end"]); InterpolationProperties = class extends BaseProperties { constructor() { super(...arguments); this.type = "linear"; this.tension = 1; this.position = "end"; } }; __decorateClass([ Validate(INTERPOLATION_TYPE) ], InterpolationProperties.prototype, "type", 2); __decorateClass([ Validate(RATIO) ], InterpolationProperties.prototype, "tension", 2); __decorateClass([ Validate(INTERPOLATION_STEP_POSITION) ], InterpolationProperties.prototype, "position", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/areaSeriesProperties.ts var AreaSeriesProperties; var init_areaSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/areaSeriesProperties.ts"() { "use strict"; init_dropShadow(); init_validation2(); init_label(); init_seriesMarker(); init_seriesTooltip(); init_cartesianSeries(); init_interpolationProperties(); AreaSeriesProperties = class extends CartesianSeriesProperties { constructor() { super(...arguments); this.xName = void 0; this.defaultColorRange = []; this.fill = "#c16068"; this.fillOpacity = 1; this.stroke = "#874349"; this.strokeWidth = 2; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.interpolation = new InterpolationProperties(); this.shadow = new DropShadow(); this.marker = new SeriesMarker(); this.label = new Label(); this.tooltip = new SeriesTooltip(); this.connectMissingData = false; } }; __decorateClass([ Validate(STRING) ], AreaSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], AreaSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate(STRING) ], AreaSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], AreaSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], AreaSeriesProperties.prototype, "yFilterKey", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], AreaSeriesProperties.prototype, "normalizedTo", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], AreaSeriesProperties.prototype, "defaultColorRange", 2); __decorateClass([ Validate(OR(COLOR_GRADIENT, COLOR_STRING)) ], AreaSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate(RATIO) ], AreaSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING) ], AreaSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AreaSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO) ], AreaSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], AreaSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], AreaSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate(OBJECT) ], AreaSeriesProperties.prototype, "interpolation", 2); __decorateClass([ Validate(OBJECT) ], AreaSeriesProperties.prototype, "shadow", 2); __decorateClass([ Validate(OBJECT) ], AreaSeriesProperties.prototype, "marker", 2); __decorateClass([ Validate(OBJECT) ], AreaSeriesProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], AreaSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate(BOOLEAN) ], AreaSeriesProperties.prototype, "connectMissingData", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/lineInterpolation.ts function spanRange(span) { switch (span.type) { case "linear": case "step": return [ { x: span.x0, y: span.y0 }, { x: span.x1, y: span.y1 } ]; case "cubic": return [ { x: span.cp0x, y: span.cp0y }, { x: span.cp3x, y: span.cp3y } ]; } } function spanRangeNormalized(span) { const range4 = spanRange(span); if (range4[0].x > range4[1].x) { range4.reverse(); } return range4; } function collapseSpanToPoint(span, point) { const { x, y } = point; switch (span.type) { case "linear": return { type: "linear", moveTo: span.moveTo, x0: x, y0: y, x1: x, y1: y }; case "step": return { type: "step", moveTo: span.moveTo, x0: x, y0: y, x1: x, y1: y, stepX: x }; case "cubic": return { type: "cubic", moveTo: span.moveTo, cp0x: x, cp0y: y, cp1x: x, cp1y: y, cp2x: x, cp2y: y, cp3x: x, cp3y: y }; } } function rescaleSpan(span, nextStart, nextEnd) { const [prevStart, prevEnd] = spanRange(span); const widthScale = prevEnd.x !== prevStart.x ? (nextEnd.x - nextStart.x) / (prevEnd.x - prevStart.x) : 0; const heightScale = prevEnd.y !== prevStart.y ? (nextEnd.y - nextStart.y) / (prevEnd.y - prevStart.y) : 0; switch (span.type) { case "linear": return { type: "linear", moveTo: span.moveTo, x0: nextStart.x, y0: nextStart.y, x1: nextEnd.x, y1: nextEnd.y }; case "cubic": return { type: "cubic", moveTo: span.moveTo, cp0x: nextStart.x, cp0y: nextStart.y, cp1x: nextEnd.x - (span.cp2x - prevStart.x) * widthScale, cp1y: nextEnd.y - (span.cp2y - prevStart.y) * heightScale, cp2x: nextEnd.x - (span.cp1x - prevStart.x) * widthScale, cp2y: nextEnd.y - (span.cp1y - prevStart.y) * heightScale, cp3x: nextEnd.x, cp3y: nextEnd.y }; case "step": return { type: "step", moveTo: span.moveTo, x0: nextStart.x, y0: nextStart.y, x1: nextEnd.x, y1: nextEnd.y, stepX: nextEnd.x - (span.stepX - prevStart.x) * widthScale }; } } function clipSpanX(span, x0, x1) { const { moveTo } = span; const [start2, end2] = spanRangeNormalized(span); const { x: spanX0, y: spanY0 } = start2; const { x: spanX1, y: spanY1 } = end2; if (x1 < spanX0) { return rescaleSpan(span, start2, start2); } else if (x0 > spanX1) { return rescaleSpan(span, end2, end2); } switch (span.type) { case "linear": { const m = spanY0 === spanY1 ? void 0 : (spanY1 - spanY0) / (spanX1 - spanX0); const y0 = m == null ? spanY0 : m * (x0 - spanX0) + spanY0; const y1 = m == null ? spanY0 : m * (x1 - spanX0) + spanY0; return { type: "linear", moveTo, x0, y0, x1, y1 }; } case "step": if (x1 <= span.stepX) { const y = span.y0; return { type: "step", moveTo, x0, y0: y, x1, y1: y, stepX: x1 }; } else if (x0 >= span.stepX) { const y = span.y1; return { type: "step", moveTo, x0, y0: y, x1, y1: y, stepX: x0 }; } else { const { y0, y1, stepX } = span; return { type: "step", moveTo, x0, y0, x1, y1, stepX }; } case "cubic": { const t0 = solveBezier(span.cp0x, span.cp1x, span.cp2x, span.cp3x, x0); let [_unused, bezier] = splitBezier( span.cp0x, span.cp0y, span.cp1x, span.cp1y, span.cp2x, span.cp2y, span.cp3x, span.cp3y, t0 ); const t1 = solveBezier(bezier[0].x, bezier[1].x, bezier[2].x, bezier[3].x, x1); [bezier, _unused] = splitBezier( bezier[0].x, bezier[0].y, bezier[1].x, bezier[1].y, bezier[2].x, bezier[2].y, bezier[3].x, bezier[3].y, t1 ); return { type: "cubic", moveTo, cp0x: bezier[0].x, cp0y: bezier[0].y, cp1x: bezier[1].x, cp1y: bezier[1].y, cp2x: bezier[2].x, cp2y: bezier[2].y, cp3x: bezier[3].x, cp3y: bezier[3].y }; } } } function linearPoints(points) { const spans = []; let i = 0; let x0 = NaN; let y0 = NaN; for (const { x: x1, y: y1 } of points) { if (i > 0) { const moveTo = i === 1; spans.push({ type: "linear", moveTo, x0, y0, x1, y1 }); } i += 1; x0 = x1; y0 = y1; } return spans; } function stepPoints(points, position) { const spans = []; let i = 0; let x0 = NaN; let y0 = NaN; const p0 = typeof position === "number" ? position : lineSteps[position]; for (const { x: x1, y: y1 } of points) { if (i > 0) { const moveTo = i === 1; const stepX = x0 + (x1 - x0) * p0; spans.push({ type: "step", moveTo, x0, y0, x1, y1, stepX }); } i += 1; x0 = x1; y0 = y1; } return spans; } function smoothPoints(iPoints, tension) { const points = Array.isArray(iPoints) ? iPoints : Array.from(iPoints); if (points.length <= 1) return []; const gradients = points.map((c, i) => { const p = i === 0 ? c : points[i - 1]; const n = i === points.length - 1 ? c : points[i + 1]; const isTerminalPoint = i === 0 || i === points.length - 1; if (Math.sign(p.y - c.y) === Math.sign(n.y - c.y)) { return 0; } if (!isTerminalPoint) { const range4 = Math.abs(p.y - n.y); const prevRatio = Math.abs(c.y - p.y) / range4; const nextRatio = Math.abs(c.y - n.y) / range4; if (prevRatio <= flatnessRatio || 1 - prevRatio <= flatnessRatio || nextRatio <= flatnessRatio || 1 - nextRatio <= flatnessRatio) { return 0; } } return (n.y - p.y) / (n.x - p.x); }); if (gradients[1] === 0) { gradients[0] *= 2; } if (gradients[gradients.length - 2] === 0) { gradients[gradients.length - 1] *= 2; } const spans = []; for (let i = 1; i < points.length; i += 1) { const prev = points[i - 1]; const prevM = gradients[i - 1]; const cur = points[i]; const curM = gradients[i]; const dx2 = cur.x - prev.x; const dy2 = cur.y - prev.y; let dcp1x = dx2 * tension / 3; let dcp1y = dx2 * prevM * tension / 3; let dcp2x = dx2 * tension / 3; let dcp2y = dx2 * curM * tension / 3; if (curM === 0 && Math.abs(dcp1y) > Math.abs(dy2)) { dcp1x *= Math.abs(dy2 / dcp1y); dcp1y = Math.sign(dcp1y) * Math.abs(dy2); } if (prevM === 0 && Math.abs(dcp2y) > Math.abs(dy2)) { dcp2x *= Math.abs(dy2 / dcp2y); dcp2y = Math.sign(dcp2y) * Math.abs(dy2); } spans.push({ type: "cubic", moveTo: i === 1, cp0x: prev.x, cp0y: prev.y, cp1x: prev.x + dcp1x, cp1y: prev.y + dcp1y, cp2x: cur.x - dcp2x, cp2y: cur.y - dcp2y, cp3x: cur.x, cp3y: cur.y }); } return spans; } var lineSteps, flatnessRatio; var init_lineInterpolation = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineInterpolation.ts"() { "use strict"; init_bezier(); lineSteps = { start: 0, middle: 0.5, end: 1 }; flatnessRatio = 0.05; } }); // packages/ag-charts-community/src/chart/series/cartesian/lineInterpolationPlotting.ts function lerp2(a, b, ratio2) { return (b - a) * ratio2 + a; } function linearSupertype(span, stepX) { const { x0, y0, x1, y1 } = span; const m = (y1 - y0) / (x1 - x0); const stepY = m * (stepX - x0) + y0; return { leftCp1x: x0, leftCp1y: y0, leftCp2x: stepX, leftCp2y: stepY, stepX, stepY0: stepY, stepY1: stepY, rightCp1x: stepX, rightCp1y: stepY, rightCp2x: x1, rightCp2y: y1 }; } function bezierSupertype(span, stepX) { const { cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y } = span; const t = solveBezier(cp0x, cp1x, cp2x, cp3x, stepX); const [left, right] = splitBezier(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, t); const stepY = left[3].y; return { leftCp1x: left[1].x, leftCp1y: left[1].y, leftCp2x: left[2].x, leftCp2y: left[2].y, stepX, stepY0: stepY, stepY1: stepY, rightCp1x: right[1].x, rightCp1y: right[1].y, rightCp2x: right[2].x, rightCp2y: right[2].y }; } function stepSupertype(span) { const { x0, y0, x1, y1, stepX } = span; return { leftCp1x: (x0 + stepX) / 2, leftCp1y: y0, leftCp2x: (x0 + stepX) / 2, leftCp2y: y0, stepX, stepY0: y0, stepY1: y1, rightCp1x: (stepX + x1) / 2, rightCp1y: y1, rightCp2x: (stepX + x1) / 2, rightCp2y: y1 }; } function spanSupertype(span, stepX) { if (span.type === "linear") { return linearSupertype(span, stepX); } else if (span.type === "cubic") { return bezierSupertype(span, stepX); } else { return stepSupertype(span); } } function plotStart(path, moveTo, x0, y0, x1, y1, reversed) { switch (moveTo) { case 0 /* MoveTo */: if (reversed) { path.moveTo(x1, y1); } else { path.moveTo(x0, y0); } break; case 1 /* LineTo */: if (reversed) { path.lineTo(x1, y1); } else { path.lineTo(x0, y0); } break; } } function plotLinear(path, x0, y0, x1, y1, reversed) { if (reversed) { path.lineTo(x0, y0); } else { path.lineTo(x1, y1); } } function plotCubic(path, cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, reversed) { if (reversed) { path.cubicCurveTo(cp2x, cp2y, cp1x, cp1y, cp0x, cp0y); } else { path.cubicCurveTo(cp1x, cp1y, cp2x, cp2y, cp3x, cp3y); } } function plotStep(path, x0, y0, x1, y1, stepX, reversed) { if (reversed) { path.lineTo(stepX, y1); path.lineTo(stepX, y0); path.lineTo(x0, y0); } else { path.lineTo(stepX, y0); path.lineTo(stepX, y1); path.lineTo(x1, y1); } } function plotSpan(path, span, moveTo, reversed) { const [start2, end2] = spanRange(span); plotStart(path, moveTo, start2.x, start2.y, end2.x, end2.y, reversed); switch (span.type) { case "linear": plotLinear(path, span.x0, span.y0, span.x1, span.y1, reversed); break; case "cubic": plotCubic( path, span.cp0x, span.cp0y, span.cp1x, span.cp1y, span.cp2x, span.cp2y, span.cp3x, span.cp3y, reversed ); break; case "step": plotStep(path, span.x0, span.y0, span.x1, span.y1, span.stepX, reversed); break; } } function interpolatedSpanRange(a, b, ratio2) { const [aStart, aEnd] = spanRange(a); const [bStart, bEnd] = spanRange(b); const x0 = lerp2(aStart.x, bStart.x, ratio2); const y0 = lerp2(aStart.y, bStart.y, ratio2); const x1 = lerp2(aEnd.x, bEnd.x, ratio2); const y1 = lerp2(aEnd.y, bEnd.y, ratio2); return [ { x: x0, y: y0 }, { x: x1, y: y1 } ]; } function plotInterpolatedSpans(path, a, b, ratio2, moveTo, reversed) { const [{ x: x0, y: y0 }, { x: x1, y: y1 }] = interpolatedSpanRange(a, b, ratio2); plotStart(path, moveTo, x0, y0, x1, y1, reversed); if (a.type === "cubic" && b.type === "cubic") { const cp1x = lerp2(a.cp1x, b.cp1x, ratio2); const cp1y = lerp2(a.cp1y, b.cp1y, ratio2); const cp2x = lerp2(a.cp2x, b.cp2x, ratio2); const cp2y = lerp2(a.cp2y, b.cp2y, ratio2); plotCubic(path, x0, y0, cp1x, cp1y, cp2x, cp2y, x1, y1, reversed); } else if (a.type === "step" && b.type === "step") { const stepX = lerp2(a.stepX, b.stepX, ratio2); plotStep(path, x0, y0, x1, y1, stepX, reversed); } else if (a.type === "linear" && b.type === "linear") { plotLinear(path, x0, y0, x1, y1, reversed); } else { let defaultStepX; if (a.type === "step") { defaultStepX = a.stepX; } else if (b.type === "step") { defaultStepX = b.stepX; } else { defaultStepX = (x0 + x1) / 2; } const as = spanSupertype(a, defaultStepX); const bs = spanSupertype(b, defaultStepX); const leftCp1x = lerp2(as.leftCp1x, bs.leftCp1x, ratio2); const leftCp1y = lerp2(as.leftCp1y, bs.leftCp1y, ratio2); const leftCp2x = lerp2(as.leftCp2x, bs.leftCp2x, ratio2); const leftCp2y = lerp2(as.leftCp2y, bs.leftCp2y, ratio2); const stepX = lerp2(as.stepX, bs.stepX, ratio2); const stepY0 = lerp2(as.stepY0, bs.stepY0, ratio2); const stepY1 = lerp2(as.stepY1, bs.stepY1, ratio2); const rightCp1x = lerp2(as.rightCp1x, bs.rightCp1x, ratio2); const rightCp1y = lerp2(as.rightCp1y, bs.rightCp1y, ratio2); const rightCp2x = lerp2(as.rightCp2x, bs.rightCp2x, ratio2); const rightCp2y = lerp2(as.rightCp2y, bs.rightCp2y, ratio2); if (reversed) { path.cubicCurveTo(rightCp2x, rightCp2y, rightCp1x, rightCp1y, stepX, stepY1); path.lineTo(stepX, stepY0); path.cubicCurveTo(leftCp2x, leftCp2y, leftCp1x, leftCp1y, x0, y0); } else { path.cubicCurveTo(leftCp1x, leftCp1y, leftCp2x, leftCp2y, stepX, stepY0); path.lineTo(stepX, stepY1); path.cubicCurveTo(rightCp1x, rightCp1y, rightCp2x, rightCp2y, x1, y1); } } } var init_lineInterpolationPlotting = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineInterpolationPlotting.ts"() { "use strict"; init_bezier(); init_lineInterpolation(); } }); // packages/ag-charts-community/src/chart/series/cartesian/lineInterpolationUtil.ts function integratedCategoryMatch(a, b) { if (a == null || b == null) return false; if (typeof a !== "object" || typeof b !== "object") return false; if ("id" in a && "id" in b) { return a.id === b.id; } return a.toString() === b.toString(); } function scale(val, scaling) { if (!scaling) return NaN; if (val instanceof Date) { val = val.getTime(); } if (scaling.type === "continuous" && typeof val === "number") { const domainRatio = (val - scaling.domain[0]) / (scaling.domain[1] - scaling.domain[0]); return domainRatio * (scaling.range[1] - scaling.range[0]) + scaling.range[0]; } if (scaling.type === "log" && typeof val === "number") { return scaling.convert(val); } if (scaling.type !== "category") return NaN; const matchingIndex = scaling.domain.findIndex((d) => d === val); if (matchingIndex >= 0) { return scaling.inset + scaling.step * matchingIndex; } const matchingIntegratedIndex = scaling.domain.findIndex((d) => integratedCategoryMatch(val, d)); if (matchingIntegratedIndex >= 0) { return scaling.inset + scaling.step * matchingIndex; } return NaN; } function toAxisValue(value) { return transformIntegratedCategoryValue(value).valueOf(); } function getAxisIndices({ data }, values) { return data.map((datum, datumIndex) => ({ xValue0Index: values.indexOf(toAxisValue(datum.xValue0)), xValue1Index: values.indexOf(toAxisValue(datum.xValue1)), datumIndex })); } function validateCategorySorting(newData, oldData) { const oldScale = oldData.scales.x; const newScale = newData.scales.x; if (oldScale?.type !== "category" || newScale?.type !== "category") return true; let x0 = -Infinity; for (const oldValue of oldScale.domain) { const x = scale(oldValue, newScale); if (!Number.isFinite(x)) continue; if (x < x0) { return false; } else { x0 = x; } } return true; } function validateAxisEntriesOrder(axisValues, data) { let x0 = -Infinity; for (const axisValue of axisValues) { const x = scale(axisValue.value, data.scales.x); if (!Number.isFinite(x)) continue; if (x < x0) { return false; } else { x0 = x; } } return true; } function spanAxisContext(newData, oldData) { const allAxisEntries = /* @__PURE__ */ new Map(); for (const { xValue0, xValue1 } of newData.data) { const xValue0Value = toAxisValue(xValue0); const xValue1Value = toAxisValue(xValue1); allAxisEntries.set(xValue0Value, xValue0).set(xValue1Value, xValue1); } const newAxisEntries = Array.from(allAxisEntries, ([axisValue, value]) => ({ axisValue, value })); newAxisEntries.sort((a, b) => { return scale(a.value, newData.scales.x) - scale(b.value, newData.scales.x); }); const exclusivelyOldAxisEntries = []; for (const { xValue0, xValue1 } of oldData.data) { const xValue0Value = toAxisValue(xValue0); const xValue1Value = toAxisValue(xValue1); if (!allAxisEntries.has(xValue0Value)) { allAxisEntries.set(xValue0Value, xValue0); exclusivelyOldAxisEntries.push({ axisValue: xValue0Value, value: xValue0 }); } if (!allAxisEntries.has(xValue1Value)) { allAxisEntries.set(xValue1Value, xValue1); exclusivelyOldAxisEntries.push({ axisValue: xValue1Value, value: xValue1 }); } } exclusivelyOldAxisEntries.sort((a, b) => { return scale(a.value, oldData.scales.x) - scale(b.value, oldData.scales.x); }); const axisEntries = newAxisEntries; let insertionIndex = 0; for (const oldAxisEntries of exclusivelyOldAxisEntries) { for (let i = axisEntries.length - 1; i > insertionIndex; i -= 1) { const oldValueX = scale(oldAxisEntries.value, oldData.scales.x); const newValueX = scale(axisEntries[i].value, oldData.scales.x); if (oldValueX > newValueX) { insertionIndex = i + 1; break; } } axisEntries.splice(insertionIndex, 0, oldAxisEntries); insertionIndex += 1; } if (!validateAxisEntriesOrder(axisEntries, oldData)) return; const axisValues = axisEntries.map((axisEntry) => axisEntry.axisValue); const oldDataAxisIndices = getAxisIndices(oldData, axisValues); const newDataAxisIndices = getAxisIndices(newData, axisValues); return { axisValues, oldDataAxisIndices, newDataAxisIndices }; } function clipSpan(span, xValue0Index, xIndices) { if (xIndices.xValue1Index === xIndices.xValue0Index + 1) return span; const range4 = spanRange(span); const step = (range4[1].x - range4[0].x) / (xIndices.xValue1Index - xIndices.xValue0Index); const start2 = range4[0].x + (xValue0Index - xIndices.xValue0Index) * step; const end2 = start2 + step; return clipSpanX(span, start2, end2); } function axisZeroSpan(span, data) { const [r0, r1] = spanRange(span); const y0 = scale(0, data.scales.y); return rescaleSpan(span, { x: r0.x, y: y0 }, { x: r1.x, y: y0 }); } function collapseSpanToMidpoint(span) { const [r0, r1] = spanRange(span); return collapseSpanToPoint(span, { x: (r0.x + r1.x) / 2, y: (r0.y + r1.y) / 2 }); } function collapseSpan(span, collapseMode, data, axisIndices, indices, range4) { let xValue; let yValue; if (indices.xValue0Index >= range4.xValue1Index) { const datumIndex = axisIndices.findLast((i) => i.xValue1Index <= range4.xValue1Index)?.datumIndex; const datum = datumIndex != null ? data.data[datumIndex] : void 0; xValue = datum?.xValue1; yValue = datum?.yValue1; } else if (indices.xValue0Index <= range4.xValue0Index) { const datumIndex = axisIndices.find((i) => i.xValue0Index >= range4.xValue0Index)?.datumIndex; const datum = datumIndex != null ? data.data[datumIndex] : void 0; xValue = datum?.xValue0; yValue = datum?.yValue0; } if (xValue == null || yValue == null) { switch (collapseMode) { case 0 /* Zero */: return axisZeroSpan(span, data); case 1 /* Split */: return collapseSpanToMidpoint(span); } } const x = scale(xValue, data.scales.x); const y = scale(yValue, data.scales.y); const point = { x, y }; return rescaleSpan(span, point, point); } function zeroDataSpan(spanDatum, zeroData) { if (zeroData == null) return; const newSpanXValue0 = toAxisValue(spanDatum.xValue0); const newSpanXValue1 = toAxisValue(spanDatum.xValue1); return zeroData.find( (zeroSpanDatum) => toAxisValue(zeroSpanDatum.xValue0) === newSpanXValue0 && toAxisValue(zeroSpanDatum.xValue1) === newSpanXValue1 )?.span; } function addSpan(newData, collapseMode, newAxisIndices, newIndices, oldZeroData, range4, out) { const newSpanDatum = newData.data[newIndices.datumIndex]; const newSpan = newSpanDatum.span; const zeroSpan = zeroDataSpan(newSpanDatum, oldZeroData); if (zeroSpan != null) { out.removed.push({ from: zeroSpan, to: zeroSpan }); out.moved.push({ from: zeroSpan, to: newSpan }); out.added.push({ from: newSpan, to: newSpan }); } else { const oldSpan = collapseSpan(newSpan, collapseMode, newData, newAxisIndices, newIndices, range4); out.added.push({ from: oldSpan, to: newSpan }); } } function removeSpan(oldData, collapseMode, oldAxisIndices, oldIndices, newZeroData, range4, out) { const oldSpanDatum = oldData.data[oldIndices.datumIndex]; const oldSpan = oldSpanDatum.span; const zeroSpan = zeroDataSpan(oldSpanDatum, newZeroData); if (zeroSpan != null) { out.removed.push({ from: oldSpan, to: oldSpan }); out.moved.push({ from: oldSpan, to: zeroSpan }); out.added.push({ from: zeroSpan, to: zeroSpan }); } else { const newSpan = collapseSpan(oldSpan, collapseMode, oldData, oldAxisIndices, oldIndices, range4); out.removed.push({ from: oldSpan, to: newSpan }); } } function alignSpanToContainingSpan(span, axisValues, preData, postData, postSpanIndices) { const startXValue0 = axisValues[postSpanIndices.xValue0Index]; const startDatum = preData.data.find((spanDatum) => toAxisValue(spanDatum.xValue0) === startXValue0); const endXValue1 = axisValues[postSpanIndices.xValue1Index]; const endDatum = preData.data.find((spanDatum) => toAxisValue(spanDatum.xValue1) === endXValue1); if (startDatum == null || endDatum == null) return; const [{ x: x0 }, { x: x1 }] = spanRange(span); const startX = scale(startDatum.xValue0, preData.scales.x); const startY = scale(startDatum.yValue0, preData.scales.y); const endX = scale(endDatum.xValue1, preData.scales.x); const endY = scale(endDatum.yValue1, preData.scales.y); let altSpan = postData.data[postSpanIndices.datumIndex].span; altSpan = rescaleSpan(altSpan, { x: startX, y: startY }, { x: endX, y: endY }); altSpan = clipSpanX(altSpan, x0, x1); return altSpan; } function appendSpanPhases(newData, oldData, collapseMode, axisValues, xValue0Index, newAxisIndices, oldAxisIndices, range4, out) { const xValue1Index = xValue0Index + 1; const oldIndices = oldAxisIndices.find((i) => i.xValue0Index <= xValue0Index && i.xValue1Index >= xValue1Index); const newIndices = newAxisIndices.find((i) => i.xValue0Index <= xValue0Index && i.xValue1Index >= xValue1Index); const oldZeroData = oldData.zeroData; const newZeroData = newData.zeroData; if (oldIndices == null && newIndices != null) { addSpan(newData, collapseMode, newAxisIndices, newIndices, oldZeroData, range4, out); return; } else if (oldIndices != null && newIndices == null) { removeSpan(oldData, collapseMode, oldAxisIndices, oldIndices, newZeroData, range4, out); return; } else if (oldIndices == null || newIndices == null) { return; } let ordering; if (oldIndices.xValue0Index === newIndices.xValue0Index && oldIndices.xValue1Index === newIndices.xValue1Index) { ordering = 0; } else if (oldIndices.xValue0Index <= newIndices.xValue0Index && oldIndices.xValue1Index >= newIndices.xValue1Index) { ordering = -1; } else if (oldIndices.xValue0Index >= newIndices.xValue0Index && oldIndices.xValue1Index <= newIndices.xValue1Index) { ordering = 1; } else { ordering = 0; } const oldSpanDatum = oldData.data[oldIndices.datumIndex]; const clippedOldSpanOldScale = clipSpan(oldSpanDatum.span, xValue0Index, oldIndices); const newSpanDatum = newData.data[newIndices.datumIndex]; const clippedNewSpanNewScale = clipSpan(newSpanDatum.span, xValue0Index, newIndices); if (ordering === 1) { const clippedPostRemoveOldSpanOldScale = alignSpanToContainingSpan( clippedOldSpanOldScale, axisValues, oldData, newData, newIndices ); if (clippedPostRemoveOldSpanOldScale != null) { out.removed.push({ from: clippedOldSpanOldScale, to: clippedPostRemoveOldSpanOldScale }); out.moved.push({ from: clippedPostRemoveOldSpanOldScale, to: clippedNewSpanNewScale }); out.added.push({ from: clippedNewSpanNewScale, to: clippedNewSpanNewScale }); } else { removeSpan(oldData, collapseMode, oldAxisIndices, oldIndices, newZeroData, range4, out); } } else if (ordering === -1) { const clippedPreAddedNewSpanNewScale = alignSpanToContainingSpan( clippedNewSpanNewScale, axisValues, newData, oldData, oldIndices ); if (clippedPreAddedNewSpanNewScale != null) { out.removed.push({ from: clippedOldSpanOldScale, to: clippedOldSpanOldScale }); out.moved.push({ from: clippedOldSpanOldScale, to: clippedPreAddedNewSpanNewScale }); out.added.push({ from: clippedPreAddedNewSpanNewScale, to: clippedNewSpanNewScale }); } else { addSpan(newData, collapseMode, newAxisIndices, newIndices, oldZeroData, range4, out); } } else { out.removed.push({ from: clippedOldSpanOldScale, to: clippedOldSpanOldScale }); out.moved.push({ from: clippedOldSpanOldScale, to: clippedNewSpanNewScale }); out.added.push({ from: clippedNewSpanNewScale, to: clippedNewSpanNewScale }); } } function phaseAnimation(axisContext, newData, oldData, collapseMode) { const out = { removed: [], moved: [], added: [] }; const { axisValues, oldDataAxisIndices, newDataAxisIndices } = axisContext; const range4 = { xValue0Index: Math.max( oldDataAxisIndices.at(0)?.xValue0Index ?? -Infinity, newDataAxisIndices.at(0)?.xValue0Index ?? -Infinity ), xValue1Index: Math.min( oldDataAxisIndices.at(-1)?.xValue1Index ?? Infinity, newDataAxisIndices.at(-1)?.xValue1Index ?? Infinity ) }; for (let xValue0Index = 0; xValue0Index < axisValues.length - 1; xValue0Index += 1) { appendSpanPhases( newData, oldData, collapseMode, axisValues, xValue0Index, newDataAxisIndices, oldDataAxisIndices, range4, out ); } return out; } function resetSpan(data, spanDatum, collapseMode) { const { span } = spanDatum; switch (collapseMode) { case 0 /* Zero */: return zeroDataSpan(spanDatum, data.zeroData) ?? axisZeroSpan(span, data); case 1 /* Split */: return collapseSpanToMidpoint(span); } } function resetAnimation(newData, oldData, collapseMode) { const added = []; const removed = []; for (const oldSpanDatum of oldData.data) { const oldSpan = oldSpanDatum.span; const collapsedSpan = resetSpan(oldData, oldSpanDatum, collapseMode); removed.push({ from: oldSpan, to: collapsedSpan }); } for (const newSpanDatum of newData.data) { const newSpan = newSpanDatum.span; const collapsedSpan = resetSpan(newData, newSpanDatum, collapseMode); added.push({ from: collapsedSpan, to: newSpan }); } return { removed, moved: [], added }; } function pairUpSpans(newData, oldData, collapseMode) { if (!validateCategorySorting(newData, oldData)) return; const axisContext = spanAxisContext(newData, oldData); return axisContext == null ? resetAnimation(newData, oldData, collapseMode) : phaseAnimation(axisContext, newData, oldData, collapseMode); } var CollapseMode; var init_lineInterpolationUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineInterpolationUtil.ts"() { "use strict"; init_value(); init_lineInterpolation(); CollapseMode = /* @__PURE__ */ ((CollapseMode3) => { CollapseMode3[CollapseMode3["Zero"] = 0] = "Zero"; CollapseMode3[CollapseMode3["Split"] = 1] = "Split"; return CollapseMode3; })(CollapseMode || {}); } }); // packages/ag-charts-community/src/chart/series/cartesian/scaling.ts function isContinuousScaling(scaling) { return scaling.type === "continuous" || scaling.type === "log"; } function isCategoryScaling(scaling) { return scaling.type === "category"; } function areScalingEqual(a, b) { if (a === void 0 || b === void 0) { return a !== void 0 || b !== void 0; } if (isContinuousScaling(a) && isContinuousScaling(b)) { return a.type === b.type && arraysEqual(a.domain, b.domain) && arraysEqual(a.range, b.range); } if (isCategoryScaling(a) && isCategoryScaling(b)) { return a.inset === b.inset && a.step === b.step && arraysEqual(a.domain, b.domain); } return false; } function isScaleValid(scale2) { if (scale2 == null) return false; if (scale2.type === "category") return scale2.domain.every((v) => v != null); return scale2.domain.every((v) => Number.isFinite(v) || v instanceof Date) && scale2.range.every((v) => Number.isFinite(v)); } var init_scaling = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/scaling.ts"() { "use strict"; init_main(); } }); // packages/ag-charts-community/src/chart/series/cartesian/lineUtil.ts function interpolatePoints(points, interpolation) { let spans; const pointsIter = points.map((point) => point.point); switch (interpolation.type) { case "linear": spans = linearPoints(pointsIter); break; case "smooth": spans = smoothPoints(pointsIter, interpolation.tension); break; case "step": spans = stepPoints(pointsIter, interpolation.position); break; } return spans.map((span, i) => ({ span, xValue0: points[i].xDatum, yValue0: points[i].yDatum, xValue1: points[i + 1].xDatum, yValue1: points[i + 1].yDatum })); } function pointsEq(a, b, delta4 = 1e-3) { return Math.abs(a.x - b.x) < delta4 && Math.abs(a.y - b.y) < delta4; } function plotLinePathStroke({ path }, spans) { let lastPoint; for (const { span } of spans) { const [start2, end2] = spanRange(span); const join = lastPoint != null && pointsEq(lastPoint, start2) ? 1 /* LineTo */ : 0 /* MoveTo */; plotSpan(path, span, join, false); lastPoint = end2; } } function plotInterpolatedLinePathStroke(ratio2, path, spans) { let lastPoint; for (const span of spans) { const [start2, end2] = interpolatedSpanRange(span.from, span.to, ratio2); const join = lastPoint != null && pointsEq(lastPoint, start2) ? 1 /* LineTo */ : 0 /* MoveTo */; plotInterpolatedSpans(path.path, span.from, span.to, ratio2, join, false); lastPoint = end2; } } function prepareLinePathStrokeAnimationFns(status, spans, visibleToggleMode) { const removePhaseFn = (ratio2, path) => plotInterpolatedLinePathStroke(ratio2, path, spans.removed); const updatePhaseFn = (ratio2, path) => plotInterpolatedLinePathStroke(ratio2, path, spans.moved); const addPhaseFn = (ratio2, path) => plotInterpolatedLinePathStroke(ratio2, path, spans.added); const pathProperties = prepareLinePathPropertyAnimation(status, visibleToggleMode); return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties }; } function prepareLinePathPropertyAnimation(status, visibleToggleMode) { const phase = visibleToggleMode === "none" ? "updated" : status; const result = { fromFn: (_path) => { let mixin; if (status === "removed") { mixin = { finish: { visible: false } }; } else if (status === "added") { mixin = { start: { visible: true } }; } else { mixin = {}; } return { phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[phase], ...mixin }; }, toFn: (_path) => { return { phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[phase] }; } }; if (visibleToggleMode === "fade") { return { fromFn: (path) => { const opacity = status === "added" ? 0 : path.opacity; return { opacity, ...result.fromFn(path) }; }, toFn: (path) => { const opacity = status === "removed" ? 0 : 1; return { opacity, ...result.toFn(path) }; } }; } return result; } function prepareLinePathAnimation(newData, oldData, diff8) { const isCategoryBased = newData.scales.x?.type === "category"; const wasCategoryBased = oldData.scales.x?.type === "category"; if (isCategoryBased !== wasCategoryBased || !isScaleValid(newData.scales.x) || !isScaleValid(oldData.scales.x)) { return; } if (newData.strokeData == null || oldData.strokeData == null) { return; } let status = "updated"; if (oldData.visible && !newData.visible) { status = "removed"; } else if (!oldData.visible && newData.visible) { status = "added"; } const strokeSpans = pairUpSpans( { scales: newData.scales, data: newData.strokeData.spans }, { scales: oldData.scales, data: oldData.strokeData.spans }, 1 /* Split */ ); if (strokeSpans == null) return; const stroke3 = prepareLinePathStrokeAnimationFns(status, strokeSpans, "fade"); const hasMotion = (diff8?.changed ?? true) || !areScalingEqual(newData.scales.x, oldData.scales.x) || !areScalingEqual(newData.scales.y, oldData.scales.y) || status !== "updated"; return { status, stroke: stroke3, hasMotion }; } var init_lineUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineUtil.ts"() { "use strict"; init_fromToMotion(); init_lineInterpolation(); init_lineInterpolationPlotting(); init_lineInterpolationUtil(); init_scaling(); } }); // packages/ag-charts-community/src/chart/series/cartesian/areaUtil.ts function plotAreaPathFill({ path }, { spans, phantomSpans }) { for (let i = 0; i < spans.length; i += 1) { const { span } = spans[i]; const phantomSpan = phantomSpans[i].span; plotSpan(path, span, 0 /* MoveTo */, false); plotSpan(path, phantomSpan, 1 /* LineTo */, true); path.closePath(); } } function plotInterpolatedAreaSeriesFillSpans(ratio2, { path }, spans, fillPhantomSpans) { for (let i = 0; i < spans.length; i += 1) { const span = spans[i]; const reversedPhantomSpan = fillPhantomSpans[i]; plotInterpolatedSpans(path, span.from, span.to, ratio2, 0 /* MoveTo */, false); plotInterpolatedSpans(path, reversedPhantomSpan.from, reversedPhantomSpan.to, ratio2, 1 /* LineTo */, true); path.closePath(); } } function prepareAreaFillAnimationFns(status, spans, fillPhantomSpans, visibleToggleMode) { const removePhaseFn = (ratio2, path) => plotInterpolatedAreaSeriesFillSpans(ratio2, path, spans.removed, fillPhantomSpans.removed); const updatePhaseFn = (ratio2, path) => plotInterpolatedAreaSeriesFillSpans(ratio2, path, spans.moved, fillPhantomSpans.moved); const addPhaseFn = (ratio2, path) => plotInterpolatedAreaSeriesFillSpans(ratio2, path, spans.added, fillPhantomSpans.added); const pathProperties = prepareLinePathPropertyAnimation(status, visibleToggleMode); return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties }; } function prepareAreaPathAnimation(newData, oldData) { const isCategoryBased = newData.scales.x?.type === "category"; const wasCategoryBased = oldData.scales.x?.type === "category"; if (isCategoryBased !== wasCategoryBased || !isScaleValid(newData.scales.x) || !isScaleValid(oldData.scales.x)) { return; } let status = "updated"; if (oldData.visible && !newData.visible) { status = "removed"; } else if (!oldData.visible && newData.visible) { status = "added"; } const fillSpans = pairUpSpans( { scales: newData.scales, data: newData.fillData.spans }, { scales: oldData.scales, data: oldData.fillData.spans }, 0 /* Zero */ ); if (fillSpans == null) return; const fillPhantomSpans = pairUpSpans( { scales: newData.scales, data: newData.fillData.phantomSpans }, { scales: oldData.scales, data: oldData.fillData.phantomSpans }, 0 /* Zero */ ); if (fillPhantomSpans == null) return; const strokeSpans = pairUpSpans( { scales: newData.scales, data: newData.strokeData.spans, zeroData: newData.fillData.phantomSpans }, { scales: oldData.scales, data: oldData.strokeData.spans, zeroData: oldData.fillData.phantomSpans }, 0 /* Zero */ ); if (strokeSpans == null) return; const fadeMode = "none"; const fill = prepareAreaFillAnimationFns(status, fillSpans, fillPhantomSpans, fadeMode); const stroke3 = prepareLinePathStrokeAnimationFns(status, strokeSpans, fadeMode); return { status, fill, stroke: stroke3 }; } var init_areaUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/areaUtil.ts"() { "use strict"; init_lineInterpolationPlotting(); init_lineInterpolationUtil(); init_lineUtil(); init_scaling(); } }); // packages/ag-charts-community/src/chart/series/cartesian/markerUtil.ts function markerFadeInAnimation({ id }, animationManager, status, ...markerSelections) { const params = { phase: status ? NODE_UPDATE_STATE_TO_PHASE_MAPPING[status] : "trailing" }; staticFromToMotion(id, "markers", animationManager, markerSelections, { opacity: 0 }, { opacity: 1 }, params); markerSelections.forEach((s) => s.cleanup()); } function markerScaleInAnimation({ id }, animationManager, ...markerSelections) { staticFromToMotion( id, "markers", animationManager, markerSelections, { scalingX: 0, scalingY: 0 }, { scalingX: 1, scalingY: 1 }, { phase: "initial" } ); markerSelections.forEach((s) => s.cleanup()); } function markerSwipeScaleInAnimation({ id, nodeDataDependencies }, animationManager, ...markerSelections) { const seriesWidth = nodeDataDependencies.seriesRectWidth; const fromFn = (_, datum) => { const x = datum.midPoint?.x ?? seriesWidth; let delay = clamp(0, inverseEaseOut(x / seriesWidth), 1); if (isNaN(delay)) { delay = 0; } return { scalingX: 0, scalingY: 0, delay, duration: QUICK_TRANSITION, phase: "initial" }; }; const toFn = () => { return { scalingX: 1, scalingY: 1 }; }; fromToMotion(id, "markers", animationManager, markerSelections, { fromFn, toFn }); } function resetMarkerFn(_node) { return { opacity: 1, scalingX: 1, scalingY: 1 }; } function resetMarkerPositionFn(_node, datum) { return { translationX: datum.point?.x ?? NaN, translationY: datum.point?.y ?? NaN }; } function computeMarkerFocusBounds(series, { datumIndex }) { const nodeData = series.getNodeData(); if (nodeData === void 0) return void 0; const datum = nodeData[datumIndex]; const { point } = datum; if (datum == null || point == null) return void 0; const size = 4 + (point.focusSize ?? series.getFormattedMarkerStyle(datum).size); const radius = size / 2; const x = datum.point.x - radius; const y = datum.point.y - radius; return Transformable.toCanvas(series.contentGroup, new BBox(x, y, size, size)); } var init_markerUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/markerUtil.ts"() { "use strict"; init_animation(); init_fromToMotion(); init_bbox(); init_transformable(); init_number(); init_easing(); } }); // packages/ag-charts-community/src/chart/series/cartesian/pathUtil.ts function pathSwipeInAnimation({ id, visible, nodeDataDependencies }, animationManager, ...paths) { const { seriesRectWidth: width2, seriesRectHeight: height2 } = nodeDataDependencies; staticFromToMotion( id, "path_properties", animationManager, paths, { clipX: 0 }, { clipX: width2 }, { phase: "initial", start: { clip: true, clipY: height2, visible }, finish: { clip: false, visible } } ); } function pathFadeInAnimation({ id }, subId, animationManager, phase = "add", ...selection) { staticFromToMotion(id, subId, animationManager, selection, { opacity: 0 }, { opacity: 1 }, { phase }); } function buildResetPathFn(opts) { return (_node) => ({ visible: opts.getVisible(), opacity: opts.getOpacity(), clipScalingX: 1, clip: false }); } function updateClipPath({ nodeDataDependencies }, path) { const toFinite = (value) => isFinite(value) ? value : 0; path.clipX = toFinite(nodeDataDependencies.seriesRectWidth); path.clipY = toFinite(nodeDataDependencies.seriesRectHeight); } var init_pathUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/pathUtil.ts"() { "use strict"; init_fromToMotion(); } }); // packages/ag-charts-community/src/chart/series/cartesian/areaSeries.ts var CROSS_FILTER_AREA_FILL_OPACITY_FACTOR, CROSS_FILTER_AREA_STROKE_OPACITY_FACTOR, AreaSeries; var init_areaSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/areaSeries.ts"() { "use strict"; init_main(); init_fromToMotion(); init_pathMotion(); init_resetMotion(); init_group(); init_fill(); init_extent(); init_object(); init_value(); init_logAxis(); init_timeAxis(); init_dataModel(); init_processors(); init_seriesLabelUtil(); init_util(); init_areaSeriesProperties(); init_areaUtil(); init_cartesianSeries(); init_lineUtil(); init_markerUtil(); init_pathUtil(); CROSS_FILTER_AREA_FILL_OPACITY_FACTOR = 0.125; CROSS_FILTER_AREA_STROKE_OPACITY_FACTOR = 0.25; AreaSeries = class extends CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, pathsPerSeries: ["fill", "stroke"], pathsZIndexSubOrderOffset: [0, 1e3], hasMarkers: true, markerSelectionGarbageCollection: false, pickModes: [2 /* AXIS_ALIGNED */, 0 /* EXACT_SHAPE_MATCH */], animationResetFns: { path: buildResetPathFn({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }), label: resetLabelFn, marker: (node, datum) => ({ ...resetMarkerFn(node), ...resetMarkerPositionFn(node, datum) }) } }); this.properties = new AreaSeriesProperties(); this.connectsToYAxis = true; this.backgroundGroup = new Group({ name: `${this.id}-background`, zIndex: 0 /* BACKGROUND */ }); this._isStacked = void 0; } get pickModeAxis() { return "main"; } renderToOffscreenCanvas() { return super.renderToOffscreenCanvas() || this.contextNodeData != null && (this.contextNodeData.fillData.spans.length > RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD || this.contextNodeData.strokeData.spans.length > RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD); } attachSeries(seriesContentNode, seriesNode, annotationNode) { super.attachSeries(seriesContentNode, seriesNode, annotationNode); seriesContentNode.appendChild(this.backgroundGroup); } detachSeries(seriesContentNode, seriesNode, annotationNode) { super.detachSeries(seriesContentNode, seriesNode, annotationNode); seriesContentNode?.removeChild(this.backgroundGroup); } attachPaths([fill, stroke3]) { this.backgroundGroup.appendChild(fill); this.contentGroup.appendChild(stroke3); stroke3.zIndex = -1; } detachPaths([fill, stroke3]) { this.backgroundGroup.removeChild(fill); this.contentGroup.removeChild(stroke3); } isStacked() { const stackCount = this.seriesGrouping?.stackCount ?? 1; return stackCount > 1; } setSeriesIndex(index) { const isStacked = this.isStacked(); if (!super.setSeriesIndex(index) && this._isStacked === isStacked) return false; this._isStacked = isStacked; if (isStacked) { this.backgroundGroup.zIndex = [0 /* BACKGROUND */, index]; this.contentGroup.zIndex = [1 /* ANY_CONTENT */, index, 0 /* FOREGROUND */]; } else { this.backgroundGroup.zIndex = [1 /* ANY_CONTENT */, index, 0 /* FOREGROUND */, 0]; this.contentGroup.zIndex = [1 /* ANY_CONTENT */, index, 0 /* FOREGROUND */, 1]; } return true; } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { data, visible, seriesGrouping: { groupIndex = this.id, stackCount = 1 } = {} } = this; const { xKey, yKey, yFilterKey, connectMissingData, normalizedTo } = this.properties; const animationEnabled = !this.ctx.animationManager.isSkipped(); const xScale = this.axes["x" /* X */]?.scale; const yScale = this.axes["y" /* Y */]?.scale; const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const idMap = { value: `area-stack-${groupIndex}-yValue`, values: `area-stack-${groupIndex}-yValues`, stack: `area-stack-${groupIndex}-yValue-stack`, marker: `area-stack-${groupIndex}-yValues-marker` }; const extraProps = []; if (isDefined(normalizedTo)) { extraProps.push(normaliseGroupTo(Object.values(idMap), normalizedTo)); } if (animationEnabled) { extraProps.push(animationValidation()); } const common = { invalidValue: null }; if ((isDefined(normalizedTo) || connectMissingData) && stackCount > 1) { common.invalidValue = 0; } if (!visible) { common.forceValue = 0; } await this.requestDataModel(dataController, data, { props: [ keyProperty(xKey, xScaleType, { id: "xValue" }), valueProperty(yKey, yScaleType, { id: `yValueRaw`, ...common }), ...yFilterKey != null ? [valueProperty(yFilterKey, yScaleType, { id: "yFilterRaw" })] : [], ...groupStackValueProperty(yKey, yScaleType, { id: `yValueStack`, ...common, groupId: idMap.stack }), valueProperty(yKey, yScaleType, { id: `yValue`, ...common, groupId: idMap.value }), ...groupAccumulativeValueProperty( yKey, "window", "current", { id: `yValueEnd`, ...common, groupId: idMap.values }, yScaleType ), ...groupAccumulativeValueProperty( yKey, "normal", "current", { id: `yValueCumulative`, ...common, groupId: idMap.marker }, yScaleType ), ...extraProps ], groupByKeys: true, groupByData: false }); this.animationState.transition("updateData"); } xCoordinateRange(xValue, pixelSize) { const { marker } = this.properties; const x = this.axes["x" /* X */].scale.convert(xValue); const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0; return [x - r, x + r]; } yCoordinateRange(yValues, pixelSize) { const { marker } = this.properties; const y = this.axes["y" /* Y */].scale.convert(yValues[0]); const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0; return [y - r, y + r]; } getSeriesDomain(direction) { const { processedData, dataModel, axes } = this; if (!processedData || !dataModel) return []; const yAxis = axes["y" /* Y */]; if (direction === "x" /* X */) { const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`); const keys = dataModel.getDomain(this, `xValue`, "key", processedData); if (keyDef?.def.type === "key" && keyDef.def.valueType === "category") { return keys; } return fixNumericExtent(extent(keys)); } const yExtent = this.domainForClippedRange("y" /* Y */, ["yValueEnd"], "xValue", true); if (yAxis instanceof LogAxis || yAxis instanceof TimeAxis) { return fixNumericExtent(yExtent); } else { const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [yExtent[0] > 0 ? 0 : yExtent[0], yExtent[1] < 0 ? 0 : yExtent[1]] : []; return fixNumericExtent(fixedYExtent); } } getSeriesRange(_direction, visibleRange) { const [y0, y1] = this.domainForVisibleRange("y" /* Y */, ["yValueEnd"], "xValue", visibleRange, true); return [Math.min(y0, 0), Math.max(y1, 0)]; } getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) { return this.countVisibleItems("xValue", ["yValueEnd"], xVisibleRange, yVisibleRange, minVisibleItems); } createNodeData() { const { axes, data, processedData, dataModel } = this; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!xAxis || !yAxis || !data || !dataModel || processedData?.type !== "grouped" || !this.properties.isValid()) { return; } const { yKey, xKey, yFilterKey, marker, label, fill: seriesFill, stroke: seriesStroke, connectMissingData, interpolation } = this.properties; const { scale: xScale } = xAxis; const { scale: yScale } = yAxis; const { isContinuousY } = this.getScaleInformation({ xScale, yScale }); const xOffset = (xScale.bandwidth ?? 0) / 2; const xValues = dataModel.resolveKeysById(this, "xValue", processedData); const yEndValues = dataModel.resolveColumnById(this, `yValueEnd`, processedData); const yRawValues = dataModel.resolveColumnById(this, `yValueRaw`, processedData); const yCumulativeValues = dataModel.resolveColumnById(this, `yValueCumulative`, processedData); const yFilterValues = yFilterKey != null ? dataModel.resolveColumnById(this, "yFilterRaw", processedData) : void 0; const yStackValues = dataModel.resolveColumnById(this, "yValueStack", processedData); const createMarkerCoordinate = (xDatum, yEnd, rawYDatum) => { let currY; if (isDefined(this.properties.normalizedTo) ? isContinuousY && isContinuous(rawYDatum) : !isNaN(rawYDatum)) { currY = yEnd; } return { x: xScale.convert(xDatum) + xOffset, y: yScale.convert(currY), size: marker.size }; }; const labelData = []; const markerData = []; const { visibleSameStackCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this); let crossFiltering = false; const { dataSources } = processedData; const rawData = dataSources.get(this.id) ?? []; for (const { datumIndex } of dataModel.forEachGroupDatum(this, processedData)) { const xDatum = xValues[datumIndex]; if (xDatum == null) return; const seriesDatum = rawData[datumIndex]; const yDatum = yRawValues[datumIndex]; const yValueCumulative = yCumulativeValues[datumIndex]; const yValueEnd = yEndValues[datumIndex]; const validPoint = Number.isFinite(yDatum); const point = createMarkerCoordinate(xDatum, +yValueCumulative, yDatum); const selected = yFilterValues != null ? yFilterValues[datumIndex] === yDatum : void 0; if (selected === false) { crossFiltering = true; } if (validPoint && marker) { markerData.push({ series: this, itemId: yKey, datum: seriesDatum, datumIndex, midPoint: { x: point.x, y: point.y }, cumulativeValue: yValueEnd, yValue: yDatum, xValue: xDatum, yKey, xKey, point, fill: marker.fill ?? seriesFill, stroke: marker.stroke ?? seriesStroke, strokeWidth: marker.strokeWidth ?? this.getStrokeWidth(this.properties.strokeWidth), selected }); } if (validPoint && label) { const labelText = this.getLabelText(label, { value: yDatum, datum: seriesDatum, xKey, yKey, xName: this.properties.xName, yName: this.properties.yName }); labelData.push({ series: this, itemId: yKey, datum: seriesDatum, datumIndex, x: point.x, y: point.y, labelText }); } } const spansForPoints = (points) => { return points.flatMap((p) => { return Array.isArray(p) ? interpolatePoints(p, interpolation) : new Array(p.skip).fill(null); }); }; const createPoint = (xDatum, yDatum) => ({ point: { x: xScale.convert(xDatum) + xOffset, y: yScale.convert(yDatum) }, xDatum, yDatum }); const getSeriesSpans = (index) => { const points = []; for (const { datumIndexes: [pIdx, datumIndex, nIndx] } of dataModel.forEachGroupDatumTuple(this, processedData)) { const xDatum = xValues[datumIndex]; const yValueStack = yStackValues[datumIndex]; const yDatum = yValueStack[index]; const yDatumIsFinite = Number.isFinite(yDatum); if (connectMissingData && !yDatumIsFinite) continue; const lastYValueStack = pIdx != null ? yStackValues[pIdx] : void 0; const nextYValueStack = nIndx != null ? yStackValues[nIndx] : void 0; let yValueEndBackwards = 0; let yValueEndForwards = 0; for (let j = 0; j <= index; j += 1) { const value = yValueStack[j]; if (Number.isFinite(value)) { const lastWasFinite = lastYValueStack == null || Number.isFinite(lastYValueStack[j]); const nextWasFinite = nextYValueStack == null || Number.isFinite(nextYValueStack[j]); if (lastWasFinite) { yValueEndBackwards += value; } if (nextWasFinite) { yValueEndForwards += value; } } } const currentPoints = points[points.length - 1]; if (!connectMissingData && (yValueEndBackwards !== yValueEndForwards || !yDatumIsFinite)) { if (!yDatumIsFinite && Array.isArray(currentPoints) && currentPoints.length === 1) { points[points.length - 1] = { skip: 1 }; } else { const pointBackwards = createPoint(xDatum, yValueEndBackwards); const pointForwards = createPoint(xDatum, yValueEndForwards); if (Array.isArray(currentPoints)) { currentPoints.push(pointBackwards); } else if (currentPoints != null) { currentPoints.skip += 1; } points.push(yDatumIsFinite ? [pointForwards] : { skip: 0 }); } } else { const yValueEnd = Math.max(yValueEndBackwards, yValueEndForwards); const point = createPoint(xDatum, yValueEnd); if (Array.isArray(currentPoints)) { currentPoints.push(point); } else if (currentPoints != null) { currentPoints.skip += 1; points.push([point]); } else { points.push([point]); } } } return spansForPoints(points); }; const stackIndex = this.seriesGrouping?.stackIndex ?? 0; const getAxisSpans = () => { const yValueZeroPoints = Array.from(dataModel.forEachGroupDatum(this, processedData), ({ datumIndex }) => { const xDatum = xValues[datumIndex]; const yValueStack = yStackValues[datumIndex]; const yDatum = yValueStack[stackIndex]; if (connectMissingData && !Number.isFinite(yDatum)) return; return createPoint(xDatum, 0); }).filter((x) => x != null); return interpolatePoints(yValueZeroPoints, interpolation); }; const currentSeriesSpans = getSeriesSpans(stackIndex); const phantomSpans = currentSeriesSpans.map(() => null); for (let j = stackIndex - 1; j >= -1; j -= 1) { let spans; for (let i = 0; i < phantomSpans.length; i += 1) { if (phantomSpans[i] != null) continue; spans ?? (spans = j !== -1 ? getSeriesSpans(j) : getAxisSpans()); phantomSpans[i] = spans[i]; } } const fillSpans = currentSeriesSpans.map((span, index) => span ?? phantomSpans[index]); const strokeSpans = currentSeriesSpans.filter((span) => span != null); const context = { itemId: yKey, fillData: { itemId: yKey, spans: fillSpans, phantomSpans }, strokeData: { itemId: yKey, spans: strokeSpans }, labelData, nodeData: markerData, scales: this.calculateScaling(), visible: this.visible, stackVisible: visibleSameStackCount > 0, crossFiltering }; return context; } isPathOrSelectionDirty() { return this.properties.marker.isDirty(); } updatePathNodes(opts) { const { opacity, visible, animationEnabled } = opts; const [fill, stroke3] = opts.paths; const crossFiltering = this.contextNodeData?.crossFiltering === true; const strokeWidth = this.getStrokeWidth(this.properties.strokeWidth); stroke3.setProperties({ fill: void 0, lineCap: "round", lineJoin: "round", pointerEvents: 1 /* None */, stroke: this.properties.stroke, strokeWidth, strokeOpacity: this.properties.strokeOpacity * (crossFiltering ? CROSS_FILTER_AREA_STROKE_OPACITY_FACTOR : 1), lineDash: this.properties.lineDash, lineDashOffset: this.properties.lineDashOffset, opacity, visible: visible || animationEnabled }); const { fill: seriesFill } = this.properties; if (isGradientFill(seriesFill)) { const gradientFillOptions = this.getGradientFillOptions(seriesFill, this.properties.defaultColorRange); fill.gradientFillOptions = gradientFillOptions; } fill.setProperties({ stroke: void 0, lineJoin: "round", pointerEvents: 1 /* None */, fill: this.properties.fill, fillOpacity: this.properties.fillOpacity * (crossFiltering ? CROSS_FILTER_AREA_FILL_OPACITY_FACTOR : 1), fillShadow: this.properties.shadow, opacity, visible: visible || animationEnabled }); updateClipPath(this, stroke3); updateClipPath(this, fill); } updatePaths(opts) { this.updateAreaPaths(opts.paths, opts.contextData); } updateAreaPaths(paths, contextData) { for (const path of paths) { path.visible = contextData.visible; } if (contextData.visible) { this.updateFillPath(paths, contextData); this.updateStrokePath(paths, contextData); } else { for (const path of paths) { path.path.clear(); path.markDirty(); } } } updateFillPath(paths, contextData) { const [fill] = paths; fill.path.clear(); plotAreaPathFill(fill, contextData.fillData); fill.markDirty(); } updateStrokePath(paths, contextData) { const { spans } = contextData.strokeData; const [, stroke3] = paths; stroke3.path.clear(); plotLinePathStroke(stroke3, spans); stroke3.markDirty(); } updateMarkerSelection(opts) { const { nodeData, markerSelection } = opts; const markersEnabled = this.properties.marker.enabled || this.contextNodeData?.crossFiltering === true; if (this.properties.marker.isDirty()) { markerSelection.clear(); markerSelection.cleanup(); } return markerSelection.update(markersEnabled ? nodeData : []); } getMarkerItemBaseStyle(highlighted) { const { marker } = this.properties; const highlightStyle = highlighted ? this.properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? marker.fill, fillOpacity: highlightStyle?.fillOpacity ?? marker.fillOpacity, stroke: highlightStyle?.stroke ?? marker.stroke, strokeWidth: highlightStyle?.strokeWidth ?? marker.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? marker.strokeOpacity }; } getMarkerItemStyleOverrides(datumId, datum, xValue, yValue, format, highlighted) { const { marker } = this.properties; const { itemStyler } = marker; if (itemStyler == null) return; const { id: seriesId, properties } = this; const { xKey, yKey } = properties; const { xDomain, yDomain } = this.cachedDatumCallback("domain", () => ({ xDomain: this.getSeriesDomain("x" /* X */), yDomain: this.getSeriesDomain("y" /* Y */) })); return this.cachedDatumCallback(createDatumId(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), xValue, yValue, highlighted, ...format }); }); } updateMarkerNodes(opts) { const { markerSelection, isHighlight: highlighted } = opts; const { xKey, yKey, marker, fill, stroke: stroke3, strokeWidth, fillOpacity, strokeOpacity, highlightStyle } = this.properties; const xDomain = this.getSeriesDomain("x" /* X */); const yDomain = this.getSeriesDomain("y" /* Y */); const baseStyle = mergeDefaults(highlighted && highlightStyle.item, marker.getStyle(), { fill, stroke: stroke3, strokeWidth, fillOpacity, strokeOpacity }); markerSelection.each((node, datum) => { this.updateMarkerStyle( node, marker, { ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), highlighted }, baseStyle, { selected: datum.selected } ); }); if (!highlighted) { this.properties.marker.markClean(); } } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; return labelSelection.update(labelData); } updateLabelNodes(opts) { const { labelSelection } = opts; const { enabled: labelEnabled, fontStyle, fontWeight, fontSize, fontFamily, color } = this.properties.label; labelSelection.each((text3, datum) => { const { x, y, labelText } = datum; if (labelText && labelEnabled && this.visible) { text3.fontStyle = fontStyle; text3.fontWeight = fontWeight; text3.fontSize = fontSize; text3.fontFamily = fontFamily; text3.textAlign = "center"; text3.textBaseline = "bottom"; text3.text = labelText; text3.x = x; text3.y = y - 10; text3.fill = color; text3.visible = true; } else { text3.visible = false; } }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { xKey, xName, yKey, yName, tooltip } = properties; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValueRaw`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getMarkerItemBaseStyle(false); Object.assign( format, this.getMarkerItemStyleOverrides(String(datumIndex), datum, xValue, yValue, format, false) ); return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), symbol: this.legendItemSymbol(), data: [{ label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(yValue) }] }, { seriesId, datum, title: yName, xKey, xName, yKey, yName, ...format, ...this.getModuleTooltipParams() } ); } legendItemSymbol() { const { fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, marker } = this.properties; const useAreaFill = !marker.enabled || marker.fill === void 0; return { marker: { shape: marker.shape, fill: useAreaFill ? fill : marker.fill, fillOpacity: useAreaFill ? fillOpacity : marker.fillOpacity, stroke: marker.stroke ?? stroke3, strokeOpacity: marker.strokeOpacity, strokeWidth: marker.strokeWidth, lineDash: marker.lineDash, lineDashOffset: marker.lineDashOffset, enabled: marker.enabled || strokeWidth <= 0 }, line: { stroke: stroke3, strokeOpacity, strokeWidth, lineDash } }; } getLegendData(legendType) { if (!this.properties.isValid() || legendType !== "category") { return []; } const { id: seriesId, ctx: { legendManager }, visible } = this; const { yKey: itemId, yName, legendItemName, showInLegend } = this.properties; return [ { legendType, id: seriesId, itemId, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }), label: { text: legendItemName ?? yName ?? itemId }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend } ]; } animateEmptyUpdateReady(animationData) { const { markerSelection, labelSelection, contextData, paths } = animationData; const { animationManager } = this.ctx; this.updateAreaPaths(paths, contextData); pathSwipeInAnimation(this, animationManager, ...paths); resetMotion([markerSelection], resetMarkerPositionFn); markerSwipeScaleInAnimation(this, animationManager, markerSelection); seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection); } animateReadyResize(animationData) { const { contextData, paths } = animationData; this.updateAreaPaths(paths, contextData); super.animateReadyResize(animationData); } animateWaitingUpdateReady(animationData) { const { animationManager } = this.ctx; const { markerSelection, labelSelection, contextData, paths, previousContextData } = animationData; const [fill, stroke3] = paths; if (fill == null && stroke3 == null) return; this.resetMarkerAnimation(animationData); this.resetLabelAnimation(animationData); const update = () => { this.resetPathAnimation(animationData); this.updateAreaPaths(paths, contextData); }; const skip = () => { animationManager.skipCurrentBatch(); update(); }; if (contextData == null || previousContextData == null) { update(); markerFadeInAnimation(this, animationManager, "added", markerSelection); pathFadeInAnimation(this, "fill_path_properties", animationManager, "add", fill); pathFadeInAnimation(this, "stroke_path_properties", animationManager, "add", stroke3); seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection); return; } if (contextData.crossFiltering !== previousContextData.crossFiltering) { skip(); return; } const fns = prepareAreaPathAnimation(contextData, previousContextData); if (fns === void 0) { skip(); return; } else if (fns.status === "no-op") { return; } markerFadeInAnimation(this, animationManager, void 0, markerSelection); fromToMotion(this.id, "fill_path_properties", animationManager, [fill], fns.fill.pathProperties); pathMotion(this.id, "fill_path_update", animationManager, [fill], fns.fill.path); fromToMotion(this.id, "stroke_path_properties", animationManager, [stroke3], fns.stroke.pathProperties); pathMotion(this.id, "stroke_path_update", animationManager, [stroke3], fns.stroke.path); seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection); this.ctx.animationManager.animate({ id: this.id, groupId: "reset_after_animation", phase: "trailing", from: {}, to: {}, onComplete: () => this.updateAreaPaths(paths, contextData) }); } isLabelEnabled() { return this.properties.label.enabled; } nodeFactory() { return new Group(); } getFormattedMarkerStyle(datum) { const { xKey, yKey } = datum; const xDomain = this.getSeriesDomain("x" /* X */); const yDomain = this.getSeriesDomain("y" /* Y */); return this.getMarkerStyle(this.properties.marker, { ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), highlighted: true }); } computeFocusBounds(opts) { return computeMarkerFocusBounds(this, opts); } }; AreaSeries.className = "AreaSeries"; AreaSeries.type = "area"; } }); // packages/ag-charts-community/src/chart/series/cartesian/areaSeriesModule.ts var AreaSeriesModule; var init_areaSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/areaSeriesModule.ts"() { "use strict"; init_symbols(); init_util3(); init_areaSeries(); AreaSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["cartesian"], identifier: "area", moduleFactory: (ctx) => new AreaSeries(ctx), stackable: true, tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: "number" /* NUMBER */, position: "left" /* LEFT */ }, { type: "category" /* CATEGORY */, position: "bottom" /* BOTTOM */ } ], themeTemplate: { series: { nodeClickRange: "nearest", tooltip: { position: { type: "node" } }, fillOpacity: 0.8, strokeOpacity: 1, strokeWidth: 0, lineDash: [0], lineDashOffset: 0, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR, xOffset: 3, yOffset: 3, blur: 5 }, interpolation: { type: "linear", tension: 1, position: "end" }, marker: { enabled: false, shape: "circle", size: 7, strokeWidth: 0 }, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } } } }, paletteFactory: (params) => { const { marker } = markerPaletteFactory(params); const defaultColorRange = params.themeTemplateParameters.get(DEFAULT_COLOR_RANGE); return { fill: marker.fill, stroke: marker.stroke, marker, defaultColorRange }; } }; } }); // packages/ag-charts-community/src/chart/series/cartesian/quadtreeUtil.ts function addHitTestersToQuadtree(quadtree, hitTesters) { for (const node of hitTesters) { const datum = node.datum; if (datum === void 0) { logger_exports.error("undefined datum"); } else { quadtree.addValue(node, datum); } } } function findQuadtreeMatch(series, point) { const { x, y } = point; const { nearest, distanceSquared: distanceSquared2 } = series.getQuadTree().find(x, y); if (nearest !== void 0) { return { datum: nearest.value, distance: Math.sqrt(distanceSquared2) }; } return void 0; } var init_quadtreeUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/quadtreeUtil.ts"() { "use strict"; init_main(); } }); // packages/ag-charts-community/src/chart/series/cartesian/abstractBarSeries.ts var AbstractBarSeriesProperties, AbstractBarSeries; var init_abstractBarSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/abstractBarSeries.ts"() { "use strict"; init_main(); init_categoryScale(); init_continuousScale(); init_extent(); init_validation2(); init_categoryAxis(); init_groupedCategoryAxis(); init_dataModel(); init_cartesianSeries(); init_quadtreeUtil(); AbstractBarSeriesProperties = class extends CartesianSeriesProperties { constructor() { super(...arguments); this.direction = "vertical"; } }; __decorateClass([ Validate(DIRECTION) ], AbstractBarSeriesProperties.prototype, "direction", 2); AbstractBarSeries = class extends CartesianSeries { constructor() { super(...arguments); /** * Used to get the position of bars within each group. */ this.groupScale = new CategoryScale(); this.smallestDataInterval = void 0; this.largestDataInterval = void 0; } padBandExtent(keys, alignStart) { const ratio2 = typeof alignStart === "boolean" ? 1 : 0.5; const scalePadding = isFiniteNumber(this.smallestDataInterval) ? this.smallestDataInterval * ratio2 : 0; const keysExtent = extent(keys) ?? [NaN, NaN]; if (typeof alignStart === "boolean") { keysExtent[alignStart ? 0 : 1] -= (alignStart ? 1 : -1) * scalePadding; } else { keysExtent[0] -= scalePadding; keysExtent[1] += scalePadding; } return fixNumericExtent(keysExtent); } getBandScalePadding() { return { inner: 0.3, outer: 0.15 }; } shouldFlipXY() { return !this.isVertical(); } isVertical() { return this.properties.direction === "vertical"; } getBarDirection() { return this.shouldFlipXY() ? "x" /* X */ : "y" /* Y */; } getCategoryDirection() { return this.shouldFlipXY() ? "y" /* Y */ : "x" /* X */; } getValueAxis() { const direction = this.getBarDirection(); return this.axes[direction]; } getCategoryAxis() { const direction = this.getCategoryDirection(); return this.axes[direction]; } getBandwidth(xAxis) { return ContinuousScale.is(xAxis.scale) ? xAxis.scale.calcBandwidth(this.smallestDataInterval) : xAxis.scale.bandwidth; } xCoordinateRange(xValue) { const xAxis = this.axes[this.getCategoryDirection()]; const xScale = xAxis.scale; const bandWidth = this.getBandwidth(xAxis) ?? 0; const barOffset = ContinuousScale.is(xScale) ? bandWidth * -0.5 : 0; const x = xScale.convert(xValue) + barOffset; return [x, x + bandWidth]; } yCoordinateRange(yValues) { const yAxis = this.axes[this.getBarDirection()]; const yScale = yAxis.scale; const ys = yValues.map((yValue) => yScale.convert(yValue)); if (ys.length === 1) { const y0 = yScale.convert(0); return [Math.min(ys[0], y0), Math.max(ys[0], y0)]; } return [Math.min(...ys), Math.max(...ys)]; } updateGroupScale(xAxis) { const domain = []; const { groupScale } = this; const xBandWidth = this.getBandwidth(xAxis); const { index: groupIndex, visibleGroupCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this); for (let groupIdx = 0; groupIdx < visibleGroupCount; groupIdx++) { domain.push(String(groupIdx)); } groupScale.domain = domain; groupScale.range = [0, xBandWidth ?? 0]; if (xAxis instanceof GroupedCategoryAxis) { groupScale.paddingInner = xAxis.groupPaddingInner; } else if (xAxis instanceof CategoryAxis) { groupScale.paddingInner = xAxis.groupPaddingInner; groupScale.round = groupScale.padding !== 0; } else { groupScale.padding = 0; } const barWidth = groupScale.bandwidth >= 1 ? ( // Pixel-rounded value for low-volume bar charts. groupScale.bandwidth ) : ( // Handle high-volume bar charts gracefully. groupScale.rawBandwidth ); return { barWidth, groupIndex }; } resolveKeyDirection(direction) { if (this.getBarDirection() === "x" /* X */) { if (direction === "x" /* X */) { return "y" /* Y */; } return "x" /* X */; } return direction; } initQuadTree(quadtree) { addHitTestersToQuadtree(quadtree, this.datumNodesIter()); } pickNodeClosestDatum(point) { return findQuadtreeMatch(this, point); } }; } }); // packages/ag-charts-community/src/chart/series/cartesian/barSeriesProperties.ts var BarSeriesLabel, BarSeriesProperties; var init_barSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/barSeriesProperties.ts"() { "use strict"; init_dropShadow(); init_validation2(); init_label(); init_seriesTooltip(); init_abstractBarSeries(); BarSeriesLabel = class extends Label { constructor() { super(...arguments); this.placement = "inside-center"; this.padding = 0; } }; __decorateClass([ Validate(UNION(["inside-center", "inside-start", "inside-end", "outside-start", "outside-end"], "a placement")) ], BarSeriesLabel.prototype, "placement", 2); __decorateClass([ Validate(NUMBER) ], BarSeriesLabel.prototype, "padding", 2); BarSeriesProperties = class extends AbstractBarSeriesProperties { constructor() { super(...arguments); this.fill = "#c16068"; this.fillOpacity = 1; this.stroke = "#874349"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.crisp = void 0; this.shadow = new DropShadow(); this.label = new BarSeriesLabel(); this.tooltip = new SeriesTooltip(); this.sparklineMode = false; this.fastDataProcessing = false; } }; __decorateClass([ Validate(STRING) ], BarSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BarSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate(STRING) ], BarSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BarSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BarSeriesProperties.prototype, "yFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BarSeriesProperties.prototype, "stackGroup", 2); __decorateClass([ Validate(NUMBER, { optional: true }) ], BarSeriesProperties.prototype, "normalizedTo", 2); __decorateClass([ Validate(COLOR_STRING) ], BarSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate(RATIO) ], BarSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING) ], BarSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], BarSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO) ], BarSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], BarSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], BarSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], BarSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate(BOOLEAN, { optional: true }) ], BarSeriesProperties.prototype, "crisp", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], BarSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate(OBJECT, { optional: true }) ], BarSeriesProperties.prototype, "shadow", 2); __decorateClass([ Validate(OBJECT) ], BarSeriesProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], BarSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate(BOOLEAN) ], BarSeriesProperties.prototype, "sparklineMode", 2); __decorateClass([ Validate(BOOLEAN) ], BarSeriesProperties.prototype, "fastDataProcessing", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/barUtil.ts function checkCrisp(scale2, visibleRange, smallestDataInterval, largestDataInterval) { if (visibleRange != null) { const [visibleMin, visibleMax] = visibleRange; const isZoomed = visibleMin !== 0 || visibleMax !== 1; if (isZoomed) return false; } if (ContinuousScale.is(scale2)) { const spacing = scale2.calcBandwidth(largestDataInterval) - scale2.calcBandwidth(smallestDataInterval); if (spacing > 0 && spacing < 1) return false; } return true; } function collapsedStartingBarPosition(isVertical, axes, mode) { const { startingX, startingY } = getStartingValues(isVertical, axes); const calculate = (datum, prevDatum) => { let x = isVertical ? datum.x : startingX; let y = isVertical ? startingY : datum.y; let width2 = isVertical ? datum.width : 0; let height2 = isVertical ? 0 : datum.height; const { opacity = 1 } = datum; if (prevDatum && (isNaN(x) || isNaN(y))) { ({ x, y } = prevDatum); width2 = isVertical ? prevDatum.width : 0; height2 = isVertical ? 0 : prevDatum.height; if (isVertical && !isDatumNegative(prevDatum)) { y += prevDatum.height; } else if (!isVertical && isDatumNegative(prevDatum)) { x += prevDatum.width; } } let clipBBox; if (datum.clipBBox == null) { clipBBox = void 0; } else if (isDatumNegative(datum)) { clipBBox = isVertical ? new BBox(x, y - height2, width2, height2) : new BBox(x - width2, y, width2, height2); } else { clipBBox = new BBox(x, y, width2, height2); } return { x, y, width: width2, height: height2, clipBBox, opacity }; }; return { isVertical, calculate, mode }; } function midpointStartingBarPosition(isVertical, mode) { return { isVertical, calculate: (datum) => { return { x: isVertical ? datum.x : datum.x + datum.width / 2, y: isVertical ? datum.y + datum.height / 2 : datum.y, width: isVertical ? datum.width : 0, height: isVertical ? 0 : datum.height, clipBBox: datum.clipBBox, opacity: datum.opacity ?? 1 }; }, mode }; } function prepareBarAnimationFunctions(initPos) { const isRemoved = (datum) => datum == null || isNaN(datum.x) || isNaN(datum.y); const fromFn = (rect, datum, status) => { if (status === "updated" && isRemoved(datum)) { status = "removed"; } else if (status === "updated" && isRemoved(rect.previousDatum)) { status = "added"; } let source; if (status === "added" && rect.previousDatum == null && initPos.mode === "fade") { source = { ...resetBarSelectionsFn(rect, datum), opacity: 0 }; } else if (status === "unknown" || status === "added") { source = initPos.calculate(datum, rect.previousDatum); } else { source = { x: rect.x, y: rect.y, width: rect.width, height: rect.height, clipBBox: rect.clipBBox, opacity: rect.opacity ?? 1 }; } const phase = NODE_UPDATE_STATE_TO_PHASE_MAPPING[status]; return { ...source, phase }; }; const toFn = (rect, datum, status) => { if (status === "removed" && rect.datum == null && initPos.mode === "fade") { return { ...resetBarSelectionsFn(rect, datum), opacity: 0 }; } else if (status === "removed" || isRemoved(datum)) { return initPos.calculate(datum, rect.previousDatum); } else { return { x: datum.x, y: datum.y, width: datum.width, height: datum.height, clipBBox: datum.clipBBox, opacity: datum.opacity ?? 1 }; } }; const applyFn = (rect, datum, status) => { rect.setProperties(datum); rect.crisp = status === "end" && (rect.datum?.crisp ?? false); }; return { toFn, fromFn, applyFn }; } function getStartingValues(isVertical, axes) { const axis = axes[isVertical ? "y" /* Y */ : "x" /* X */]; let startingX = Infinity; let startingY = 0; if (!axis) { return { startingX, startingY }; } if (isVertical) { startingY = axis.scale.convert(ContinuousScale.is(axis.scale) ? 0 : Math.max(...axis.range)); } else { startingX = axis.scale.convert(ContinuousScale.is(axis.scale) ? 0 : Math.min(...axis.range)); } return { startingX, startingY }; } function resetBarSelectionsFn(rect, { x, y, width: width2, height: height2, clipBBox, opacity = 1 }) { return { x, y, width: width2, height: height2, clipBBox, opacity, crisp: rect.datum?.crisp ?? false }; } function computeBarFocusBounds(series, datum) { if (datum === void 0) return void 0; const { x, y, width: width2, height: height2 } = datum; return Transformable.toCanvas(series.contentGroup, new BBox(x, y, width2, height2)); } var isDatumNegative; var init_barUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/barUtil.ts"() { "use strict"; init_fromToMotion(); init_continuousScale(); init_bbox(); init_transformable(); init_number(); isDatumNegative = (datum) => { return isNegative(datum.yValue ?? 0); }; } }); // packages/ag-charts-community/src/chart/series/cartesian/labelUtil.ts function updateLabelNode(textNode, label, labelDatum) { if (label.enabled && labelDatum) { const { x, y, text: text3, textAlign, textBaseline } = labelDatum; const { color: fill, fontStyle, fontWeight, fontSize, fontFamily } = label; textNode.setProperties({ visible: true, x, y, text: text3, fill, fontStyle, fontWeight, fontSize, fontFamily, textAlign, textBaseline }); } else { textNode.visible = false; } } function adjustLabelPlacement({ isUpward, isVertical, placement, padding = 0, rect }) { let x = rect.x + rect.width / 2; let y = rect.y + rect.height / 2; let textAlign = "center"; let textBaseline = "middle"; if (placement !== "inside-center") { const barDirection = (isUpward ? 1 : -1) * (isVertical ? -1 : 1); const { direction, textAlignment } = placements[placement]; const displacementRatio = (direction + 1) * 0.5; if (isVertical) { const y0 = isUpward ? rect.y + rect.height : rect.y; const height2 = rect.height * barDirection; y = y0 + height2 * displacementRatio + padding * textAlignment * barDirection; textBaseline = textAlignment === barDirection ? "top" : "bottom"; } else { const x0 = isUpward ? rect.x : rect.x + rect.width; const width2 = rect.width * barDirection; x = x0 + width2 * displacementRatio + padding * textAlignment * barDirection; textAlign = textAlignment === barDirection ? "left" : "right"; } } return { x, y, textAlign, textBaseline }; } var placements; var init_labelUtil = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/labelUtil.ts"() { "use strict"; placements = { "inside-start": { inside: true, direction: -1, textAlignment: 1 }, "inside-end": { inside: true, direction: 1, textAlignment: -1 }, "outside-start": { inside: false, direction: -1, textAlignment: -1 }, "outside-end": { inside: false, direction: 1, textAlignment: 1 } }; } }); // packages/ag-charts-community/src/chart/series/cartesian/barSeries.ts var X_MIN, X_MAX, Y_MIN, Y_MAX, SPAN2, BarSeries; var init_barSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/barSeries.ts"() { "use strict"; init_main(); init_fromToMotion(); init_continuousScale(); init_bbox(); init_rect(); init_logAxis(); init_dataModel(); init_processors(); init_seriesLabelUtil(); init_shapeUtil(); init_util(); init_abstractBarSeries(); init_barSeriesProperties(); init_barUtil(); init_cartesianSeries(); init_labelUtil(); init_scaling(); X_MIN = 0; X_MAX = 1; Y_MIN = 2; Y_MAX = 3; SPAN2 = 4; BarSeries = class extends AbstractBarSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, pickModes: [ 2 /* AXIS_ALIGNED */, // Only used in sparklineMode 1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */ ], pathsPerSeries: [], hasHighlightedLabels: true, datumSelectionGarbageCollection: false, animationAlwaysUpdateSelections: true, animationResetFns: { datum: resetBarSelectionsFn, label: resetLabelFn } }); this.properties = new BarSeriesProperties(); this.connectsToYAxis = true; this.dataAggregationFilters = void 0; } get pickModeAxis() { return this.properties.sparklineMode ? "main" : void 0; } crossFilteringEnabled() { return this.properties.yFilterKey != null && (this.seriesGrouping == null || this.seriesGrouping.stackIndex === 0); } async processData(dataController) { if (!this.properties.isValid() || !this.data) { return; } const { xKey, yKey, yFilterKey, normalizedTo, fastDataProcessing } = this.properties; const { seriesGrouping: { groupIndex = this.id } = {}, data } = this; const groupCount2 = this.seriesGrouping?.groupCount ?? 0; const stackCount = this.seriesGrouping?.stackCount ?? 0; const stacked = stackCount >= 1 || normalizedTo != null; const grouped = !fastDataProcessing || groupCount2 > 1 || stacked; const animationEnabled = !this.ctx.animationManager.isSkipped(); const xScale = this.getCategoryAxis()?.scale; const yScale = this.getValueAxis()?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const stackGroupName = `bar-stack-${groupIndex}-yValues`; const stackGroupTrailingName = `${stackGroupName}-trailing`; const visibleProps = this.visible ? {} : { forceValue: 0 }; const props = [ keyProperty(xKey, xScaleType, { id: "xValue" }), valueProperty(yKey, yScaleType, { id: `yValue-raw`, invalidValue: null, ...visibleProps }) ]; if (this.crossFilteringEnabled()) { props.push( valueProperty(yFilterKey, yScaleType, { id: `yFilterValue`, invalidValue: null, ...visibleProps }) ); } if (stacked) { props.push( ...groupAccumulativeValueProperty( yKey, "normal", "current", { id: `yValue-end`, rangeId: `yValue-range`, invalidValue: null, missingValue: 0, groupId: stackGroupName, separateNegative: true, ...visibleProps }, yScaleType ), ...groupAccumulativeValueProperty( yKey, "trailing", "current", { id: `yValue-start`, invalidValue: null, missingValue: 0, groupId: stackGroupTrailingName, separateNegative: true, ...visibleProps }, yScaleType ) ); } if (isContinuousX) { props.push(SMALLEST_KEY_INTERVAL, LARGEST_KEY_INTERVAL); } if (isFiniteNumber(normalizedTo)) { props.push(normaliseGroupTo([stackGroupName, stackGroupTrailingName], Math.abs(normalizedTo))); } if (animationEnabled && this.processedData) { props.push(diff(this.id, this.processedData)); } if (animationEnabled || !grouped) { props.push(animationValidation()); } const { dataModel, processedData } = await this.requestDataModel(dataController, data, { props, groupByKeys: grouped, groupByData: !grouped }); this.dataAggregationFilters = this.aggregateData(dataModel, processedData); this.smallestDataInterval = processedData.reduced?.smallestKeyInterval; this.largestDataInterval = processedData.reduced?.largestKeyInterval; this.animationState.transition("updateData"); } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (dataModel == null || processedData == null) return []; if (direction === this.getCategoryDirection()) { const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`); const keys = dataModel.getDomain(this, `xValue`, "key", processedData); if (keyDef?.def.type === "key" && keyDef.def.valueType === "category") { return keys; } return this.padBandExtent(keys); } const yKey = this.dataModel?.hasColumnById(this, `yValue-end`) ? "yValue-end" : "yValue-raw"; let yExtent = this.domainForClippedRange("y" /* Y */, [yKey], "xValue", true); const yFilterExtent = this.crossFilteringEnabled() ? dataModel.getDomain(this, `yFilterValue`, "value", processedData) : void 0; if (yFilterExtent != null) { yExtent = [Math.min(yExtent[0], yFilterExtent[0]), Math.max(yExtent[1], yFilterExtent[1])]; } if (this.getValueAxis() instanceof LogAxis) { return fixNumericExtent(yExtent); } else { const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [Math.min(0, yExtent[0]), Math.max(0, yExtent[1])] : []; return fixNumericExtent(fixedYExtent); } } getSeriesRange(_direction, visibleRange) { const yKey = this.dataModel?.hasColumnById(this, `yValue-end`) ? "yValue-end" : "yValue-raw"; const [y0, y1] = this.domainForVisibleRange("y" /* Y */, [yKey], "xValue", visibleRange, true); return [Math.min(y0, 0), Math.max(y1, 0)]; } getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) { const yKey = this.dataModel?.hasColumnById(this, `yValue-end`) ? "yValue-end" : "yValue-raw"; return this.countVisibleItems("xValue", [yKey], xVisibleRange, yVisibleRange, minVisibleItems); } aggregateData(_dataModel, _processedData) { return; } createNodeData() { const { dataModel, processedData, groupScale, dataAggregationFilters } = this; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis || !this.properties.isValid()) { return; } const rawData = processedData.dataSources?.get(this.id); if (rawData == null) return; const xScale = xAxis.scale; const yScale = yAxis.scale; const { xKey, yKey, xName, yName, legendItemName, label } = this.properties; const yReversed = yAxis.isReversed(); const { barWidth, groupIndex: groupScaleIndex } = this.updateGroupScale(xAxis); const groupOffset = groupScale.convert(String(groupScaleIndex)); const barOffset = ContinuousScale.is(xScale) ? barWidth * -0.5 : 0; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const yRawValues = dataModel.resolveColumnById(this, `yValue-raw`, processedData); const yFilterValues = this.crossFilteringEnabled() ? dataModel.resolveColumnById(this, `yFilterValue`, processedData) : void 0; const animationEnabled = !this.ctx.animationManager.isSkipped(); const xPosition = (index) => xScale.convert(xValues[index]) + groupOffset + barOffset; const crisp = this.properties.crisp ?? checkCrisp(xAxis?.scale, xAxis?.visibleRange, this.smallestDataInterval, this.largestDataInterval); const bboxBottom = yScale.convert(0); const nodeDatum = ({ datum, datumIndex, valueIndex, xValue, yValue, cumulativeValue, phantom, currY, prevY, x, width: width2, isPositive, yRange, labelText, opacity, crossScale = 1 }) => { const isUpward = isPositive !== yReversed; const y = yScale.convert(currY); const bottomY = yScale.convert(prevY); const bboxHeight = yScale.convert(yRange); const barAlongX = this.getBarDirection() === "x" /* X */; const xOffset = width2 * 0.5 * (1 - crossScale); const rect = { x: barAlongX ? Math.min(y, bottomY) : x + xOffset, y: barAlongX ? x + xOffset : Math.min(y, bottomY), width: barAlongX ? Math.abs(bottomY - y) : width2 * crossScale, height: barAlongX ? width2 * crossScale : Math.abs(bottomY - y) }; const clipBBox = new BBox(rect.x, rect.y, rect.width, rect.height); const barRect = { x: barAlongX ? Math.min(bboxBottom, bboxHeight) : x + xOffset, y: barAlongX ? x + xOffset : Math.min(bboxBottom, bboxHeight), width: barAlongX ? Math.abs(bboxBottom - bboxHeight) : width2 * crossScale, height: barAlongX ? width2 * crossScale : Math.abs(bboxBottom - bboxHeight) }; const lengthRatioMultiplier = this.shouldFlipXY() ? rect.height : rect.width; return { series: this, itemId: phantom ? createDatumId(yKey, phantom) : yKey, datum, datumIndex, valueIndex, cumulativeValue, phantom, xValue, yValue, yKey, xKey, capDefaults: { lengthRatioMultiplier, lengthMax: lengthRatioMultiplier }, x: barRect.x, y: barRect.y, width: barRect.width, height: barRect.height, midPoint: { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }, opacity, topLeftCornerRadius: barAlongX !== isUpward, topRightCornerRadius: isUpward, bottomRightCornerRadius: barAlongX === isUpward, bottomLeftCornerRadius: !isUpward, clipBBox, crisp, label: labelText != null ? { text: labelText, ...adjustLabelPlacement({ isUpward, isVertical: !barAlongX, placement: label.placement, padding: label.padding, rect }) } : void 0, missing: yValue == null, focusable: !phantom }; }; const phantomNodes = []; const nodes = []; const labels = []; const handleDatum = (datumIndex, valueIndex, x, width2, yStart, yEnd, yRange, opacity) => { const xValue = xValues[datumIndex]; if (xValue == null) return; const yRawValue = yRawValues[datumIndex]; const yFilterValue = yFilterValues != null ? Number(yFilterValues[datumIndex]) : void 0; const isPositive = yRawValue >= 0 && !Object.is(yRawValue, -0); if (!Number.isFinite(yEnd)) return; if (yFilterValue != null && !Number.isFinite(yFilterValue)) return; const labelText = yRawValue != null ? this.getLabelText(this.properties.label, { datum: rawData[datumIndex], value: yFilterValue ?? yRawValue, xKey, yKey, xName, yName, legendItemName }) : void 0; const inset = yFilterValue != null && yFilterValue > yRawValue; const nodeData = nodeDatum({ datum: rawData[datumIndex], datumIndex, valueIndex, xValue, yValue: yFilterValue ?? yRawValue, cumulativeValue: yFilterValue ?? yEnd, phantom: false, currY: yFilterValue != null ? yStart + yFilterValue : yEnd, prevY: yStart, x, width: width2, isPositive, yRange: Math.max(yStart + (yFilterValue ?? -Infinity), yRange), labelText, opacity, crossScale: inset ? 0.6 : void 0 }); nodes.push(nodeData); labels.push(nodeData); if (yFilterValue != null) { const phantomNodeData = nodeDatum({ datum: rawData[datumIndex], datumIndex, valueIndex, xValue, yValue: yFilterValue, cumulativeValue: yFilterValue, phantom: true, currY: yEnd, prevY: yStart, x, width: width2, isPositive, yRange, labelText: void 0, opacity, crossScale: void 0 }); phantomNodes.push(phantomNodeData); } }; const [r0, r1] = xScale.range; const range4 = r1 - r0; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range4); if (processedData.type === "grouped") { const width2 = barWidth; const stacked = dataModel.hasColumnById(this, `yValue-start`); const yStartValues = stacked ? dataModel.resolveColumnById(this, `yValue-start`, processedData) : void 0; const yEndValues = stacked ? dataModel.resolveColumnById(this, `yValue-end`, processedData) : void 0; const yRangeIndex = stacked ? dataModel.resolveProcessedDataIndexById(this, `yValue-range`) : -1; for (const { datumIndex, valueIndex, group: { aggregation } } of dataModel.forEachGroupDatum(this, processedData)) { const x = xPosition(datumIndex); const yRawValue = yRawValues[datumIndex]; const isPositive = yRawValue >= 0 && !Object.is(yRawValue, -0); const yStart = stacked ? Number(yStartValues?.[datumIndex]) : 0; const yEnd = stacked ? Number(yEndValues?.[datumIndex]) : yRawValue; let yRange = yEnd; if (stacked) { yRange = aggregation[yRangeIndex][isPositive ? 1 : 0]; } handleDatum(datumIndex, valueIndex, x, width2, yStart, yEnd, yRange, 1); } } else if (dataAggregationFilter == null) { const width2 = barWidth; let [start2, end2] = this.visibleRange("xValue", xAxis.range); if (processedData.input.count < 1e3) { start2 = 0; end2 = processedData.input.count; } for (let datumIndex = start2; datumIndex < end2; datumIndex += 1) { const x = xPosition(datumIndex); const yEnd = Number(yRawValues[datumIndex]); handleDatum(datumIndex, 0, x, width2, 0, yEnd, yEnd, 1); } } else { const { indexData, indices } = dataAggregationFilter; const [start2, end2] = this.visibleRange("xValue", xAxis.range, indices); for (let i = start2; i < end2; i += 1) { const aggIndex = i * SPAN2; const xMinIndex = indexData[aggIndex + X_MIN]; const xMaxIndex = indexData[aggIndex + X_MAX]; const yMinIndex = indexData[aggIndex + Y_MIN]; const yMaxIndex = indexData[aggIndex + Y_MAX]; if (xMinIndex === -1) continue; const x = xPosition((xMinIndex + xMaxIndex) / 2 | 0); const width2 = Math.abs(xPosition(xMaxIndex) - xPosition(xMinIndex)) + barWidth; const yEndMax = xValues[yMaxIndex] != null ? Number(yRawValues[yMaxIndex]) : NaN; const yEndMin = xValues[yMinIndex] != null ? Number(yRawValues[yMinIndex]) : NaN; if (yEndMax > 0) { const opacity = yEndMin >= 0 ? yEndMin / yEndMax : 1; handleDatum(yMaxIndex, 0, x, width2, 0, yEndMax, yEndMax, opacity); } if (yEndMin < 0) { const opacity = yEndMax <= 0 ? yEndMax / yEndMin : 1; handleDatum(yMinIndex, 1, x, width2, 0, yEndMin, yEndMin, opacity); } } } return { itemId: yKey, nodeData: phantomNodes.length > 0 ? [...phantomNodes, ...nodes] : nodes, labelData: labels, scales: this.calculateScaling(), visible: this.visible || animationEnabled, groupScale: this.getScaling(this.groupScale) }; } nodeFactory() { return new Rect(); } getHighlightData(nodeData, highlightedItem) { const highlightItem = nodeData.find( (nodeDatum) => nodeDatum.datum === highlightedItem.datum && !nodeDatum.phantom ); return highlightItem != null ? [highlightItem] : void 0; } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => this.getDatumId(datum)); } getItemBaseStyle(highlighted) { const { properties } = this; const { cornerRadius } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash ?? [], lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset, cornerRadius }; } getItemStyleOverrides(datumId, datum, xValue, yValue, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yKey, itemStyler } = properties; if (itemStyler == null) return; const { xDomain, yDomain } = this.cachedDatumCallback("domain", () => ({ xDomain: this.getSeriesDomain("x" /* X */), yDomain: this.getSeriesDomain("y" /* Y */) })); return this.cachedDatumCallback(createDatumId(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), xValue, yValue, highlighted, ...format }); }); } updateDatumNodes(opts) { if (!this.properties.isValid()) { return; } const { shadow } = this.properties; const categoryAlongX = this.getCategoryDirection() === "x" /* X */; const style = this.getItemBaseStyle(opts.isHighlight); opts.datumSelection.each((rect, datum) => { const overrides = this.getItemStyleOverrides( String(datum.datumIndex), datum.datum, datum.xValue, datum.yValue, style, opts.isHighlight ); rect.opacity = datum.opacity ?? 0; applyShapeStyle(rect, style, overrides); const cornerRadius = overrides?.cornerRadius ?? style.cornerRadius; rect.topLeftCornerRadius = datum.topLeftCornerRadius ? cornerRadius : 0; rect.topRightCornerRadius = datum.topRightCornerRadius ? cornerRadius : 0; rect.bottomRightCornerRadius = datum.bottomRightCornerRadius ? cornerRadius : 0; rect.bottomLeftCornerRadius = datum.bottomLeftCornerRadius ? cornerRadius : 0; rect.visible = categoryAlongX ? (datum.clipBBox?.width ?? datum.width) > 0 : (datum.clipBBox?.height ?? datum.height) > 0; rect.crisp = datum.crisp; rect.fillShadow = shadow; }); } updateLabelSelection(opts) { const data = this.isLabelEnabled() ? opts.labelData : []; return opts.labelSelection.update(data, (text3) => { text3.pointerEvents = 1 /* None */; }); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode(textNode, this.properties.label, datum.label); }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { xKey, xName, yKey, yName, legendItemName, stackGroup, tooltip } = properties; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis) { return; } const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValue-raw`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datum, xValue, yValue, format, false)); return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), symbol: this.legendItemSymbol(), data: [{ label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(yValue) }] }, { seriesId, datum, title: yName, xKey, xName, yKey, yName, legendItemName, stackGroup, ...format, ...this.getModuleTooltipParams() } ); } legendItemSymbol() { const { fill, stroke: stroke3, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { marker: { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } }; } getLegendData(legendType) { const { showInLegend } = this.properties; if (legendType !== "category" || !this.properties.isValid()) { return []; } const { id: seriesId, ctx: { legendManager }, visible } = this; const { yKey: itemId, yName, legendItemName } = this.properties; return [ { legendType: "category", id: seriesId, itemId, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }), label: { text: legendItemName ?? yName ?? itemId }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend } ]; } animateEmptyUpdateReady({ datumSelection, labelSelection, annotationSelections }) { const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(this.isVertical(), this.axes, "normal")); fromToMotion(this.id, "nodes", this.ctx.animationManager, [datumSelection], fns); seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection); seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, ...annotationSelections); } animateWaitingUpdateReady(data) { const { datumSelection, labelSelection, annotationSelections, previousContextData } = data; this.ctx.animationManager.stopByAnimationGroupId(this.id); let dataDiff = this.processedData?.reduced?.diff?.[this.id]; if (dataDiff == null && this.processedData?.reduced?.diff != null) { dataDiff = { changed: true, added: new Set(Array.from(datumSelection, ({ datum }) => this.getDatumId(datum))), updated: /* @__PURE__ */ new Set(), removed: /* @__PURE__ */ new Set(), moved: /* @__PURE__ */ new Set() }; } const mode = previousContextData == null ? "fade" : "normal"; const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(this.isVertical(), this.axes, mode)); fromToMotion( this.id, "nodes", this.ctx.animationManager, [datumSelection], fns, (_, datum) => this.getDatumId(datum), dataDiff ); const scalingChanged = previousContextData != null && (!areScalingEqual(data.contextData.scales.x, previousContextData.scales.x) || !areScalingEqual(data.contextData.scales.y, previousContextData.scales.y) || !areScalingEqual( data.contextData.groupScale, data.previousContextData.groupScale )); const hasMotion = (dataDiff?.changed ?? false) || scalingChanged; if (hasMotion) { seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection); seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, ...annotationSelections); } } getDatumId(datum) { return createDatumId(datum.xValue, datum.valueIndex, datum.phantom); } isLabelEnabled() { return this.properties.label.enabled; } computeFocusBounds({ datumIndex }) { const datumBox = this.contextNodeData?.nodeData[datumIndex].clipBBox; return computeBarFocusBounds(this, datumBox); } }; BarSeries.className = "BarSeries"; BarSeries.type = "bar"; } }); // packages/ag-charts-community/src/chart/series/cartesian/barSeriesModule.ts var BarSeriesModule; var init_barSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/barSeriesModule.ts"() { "use strict"; init_symbols(); init_util3(); init_barSeries(); BarSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["cartesian"], identifier: "bar", moduleFactory: (ctx) => new BarSeries(ctx), stackable: true, groupable: true, tooltipDefaults: { range: "exact" }, defaultAxes: swapAxisCondition( [ { type: "number" /* NUMBER */, position: "left" /* LEFT */ }, { type: "category" /* CATEGORY */, position: "bottom" /* BOTTOM */ } ], (series) => series?.direction === "horizontal" ), themeTemplate: { series: { direction: "vertical", fillOpacity: 1, strokeWidth: 0, lineDash: [0], lineDashOffset: 0, label: { enabled: false, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $if: [ { $or: [ { $eq: [{ $path: "./placement" }, "outside-start"] }, { $eq: [{ $path: "./placement" }, "outside-end"] } ] }, { $ref: "textColor" }, { $ref: "backgroundColor" } ] }, placement: "inside-center" }, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR, xOffset: 3, yOffset: 3, blur: 5 }, errorBar: { cap: { lengthRatio: 0.3 } } } }, paletteFactory: singleSeriesPaletteFactory }; } }); // packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesProperties.ts var BubbleSeriesMarker, BubbleSeriesLabel, BubbleSeriesProperties; var init_bubbleSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesProperties.ts"() { "use strict"; init_changeDetectable(); init_proxy(); init_validation2(); init_label(); init_seriesMarker(); init_seriesTooltip(); init_cartesianSeries(); BubbleSeriesMarker = class extends SeriesMarker { constructor() { super(...arguments); this.maxSize = 30; } }; __decorateClass([ Validate(POSITIVE_NUMBER), SceneChangeDetection() ], BubbleSeriesMarker.prototype, "maxSize", 2); __decorateClass([ Validate(NUMBER_ARRAY, { optional: true }), SceneChangeDetection() ], BubbleSeriesMarker.prototype, "domain", 2); BubbleSeriesLabel = class extends Label { constructor() { super(...arguments); this.placement = "top"; } }; __decorateClass([ Validate(LABEL_PLACEMENT) ], BubbleSeriesLabel.prototype, "placement", 2); BubbleSeriesProperties = class extends CartesianSeriesProperties { constructor() { super(...arguments); this.colorRange = ["#ffff00", "#00ff00", "#0000ff"]; this.label = new BubbleSeriesLabel(); this.tooltip = new SeriesTooltip(); // No validation. Not a part of the options contract. this.marker = new BubbleSeriesMarker(); } }; __decorateClass([ Validate(STRING) ], BubbleSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate(STRING) ], BubbleSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate(STRING) ], BubbleSeriesProperties.prototype, "sizeKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "xFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "yFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "sizeFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate(NUMBER_ARRAY, { optional: true }) ], BubbleSeriesProperties.prototype, "colorDomain", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], BubbleSeriesProperties.prototype, "colorRange", 2); __decorateClass([ Validate(STRING, { optional: true }) ], BubbleSeriesProperties.prototype, "title", 2); __decorateClass([ ProxyProperty("marker.shape") ], BubbleSeriesProperties.prototype, "shape", 2); __decorateClass([ ProxyProperty("marker.size") ], BubbleSeriesProperties.prototype, "size", 2); __decorateClass([ ProxyProperty("marker.maxSize") ], BubbleSeriesProperties.prototype, "maxSize", 2); __decorateClass([ ProxyProperty("marker.domain", { optional: true }) ], BubbleSeriesProperties.prototype, "domain", 2); __decorateClass([ ProxyProperty("marker.fill", { optional: true }) ], BubbleSeriesProperties.prototype, "fill", 2); __decorateClass([ ProxyProperty("marker.fillOpacity") ], BubbleSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ ProxyProperty("marker.stroke", { optional: true }) ], BubbleSeriesProperties.prototype, "stroke", 2); __decorateClass([ ProxyProperty("marker.strokeWidth") ], BubbleSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ ProxyProperty("marker.strokeOpacity") ], BubbleSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ ProxyProperty("marker.lineDash") ], BubbleSeriesProperties.prototype, "lineDash", 2); __decorateClass([ ProxyProperty("marker.lineDashOffset") ], BubbleSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ ProxyProperty("marker.itemStyler", { optional: true }) ], BubbleSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate(OBJECT) ], BubbleSeriesProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], BubbleSeriesProperties.prototype, "tooltip", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/bubbleSeries.ts var BubbleSeriesNodeEvent, BubbleSeries; var init_bubbleSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/bubbleSeries.ts"() { "use strict"; init_colorScale(); init_linearScale(); init_group(); init_extent(); init_object(); init_textMeasurer(); init_dataModel(); init_processors(); init_marker(); init_seriesLabelUtil(); init_bubbleSeriesProperties(); init_cartesianSeries(); init_markerUtil(); BubbleSeriesNodeEvent = class extends CartesianSeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.sizeKey = series.properties.sizeKey; } }; BubbleSeries = class extends CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, pickModes: [ 2 /* AXIS_ALIGNED */, 1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */ ], pathsPerSeries: [], hasMarkers: true, markerSelectionGarbageCollection: false, animationResetFns: { label: resetLabelFn, marker: resetMarkerFn }, usesPlacedLabels: true }); this.NodeEvent = BubbleSeriesNodeEvent; this.clipFocusBox = false; this.properties = new BubbleSeriesProperties(); this.sizeScale = new LinearScale(); this.colorScale = new ColorScale(); } get pickModeAxis() { return "main-category"; } async processData(dataController) { if (!this.properties.isValid() || this.data == null || !this.visible) return; const xScale = this.axes["x" /* X */]?.scale; const yScale = this.axes["y" /* Y */]?.scale; const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const colorScaleType = this.colorScale.type; const sizeScaleType = this.sizeScale.type; const { xKey, yKey, sizeKey, xFilterKey, yFilterKey, sizeFilterKey, labelKey, colorDomain, colorRange, colorKey, marker } = this.properties; const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, { props: [ valueProperty(xKey, xScaleType, { id: `xValue` }), valueProperty(yKey, yScaleType, { id: `yValue` }), ...xFilterKey != null ? [valueProperty(xFilterKey, xScaleType, { id: `xFilterValue` })] : [], ...yFilterKey != null ? [valueProperty(yFilterKey, yScaleType, { id: `yFilterValue` })] : [], ...sizeFilterKey != null ? [valueProperty(sizeFilterKey, sizeScaleType, { id: `sizeFilterValue` })] : [], valueProperty(sizeKey, sizeScaleType, { id: `sizeValue` }), ...colorKey ? [valueProperty(colorKey, colorScaleType, { id: `colorValue` })] : [], ...labelKey ? [valueProperty(labelKey, "band", { id: `labelValue` })] : [] ] }); const sizeKeyIdx = dataModel.resolveProcessedDataIndexById(this, `sizeValue`); const processedSize = processedData.domain.values[sizeKeyIdx] ?? []; this.sizeScale.domain = marker.domain ? marker.domain : processedSize; if (colorKey) { const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, `colorValue`); this.colorScale.domain = colorDomain ?? processedData.domain.values[colorKeyIdx] ?? []; this.colorScale.range = colorRange; this.colorScale.update(); } this.animationState.transition("updateData"); } xCoordinateRange(xValue, pixelSize, index) { const { properties, sizeScale } = this; const { size, sizeKey } = properties; const x = this.axes["x" /* X */].scale.convert(xValue); const sizeValues = sizeKey != null ? this.dataModel.resolveColumnById(this, `sizeValue`, this.processedData) : void 0; const sizeValue = sizeValues != null ? sizeScale.convert(sizeValues[index]) : size; const r = 0.5 * sizeValue * pixelSize; return [x - r, x + r]; } yCoordinateRange(yValues, pixelSize, index) { const { properties, sizeScale } = this; const { size, sizeKey } = properties; const y = this.axes["y" /* Y */].scale.convert(yValues[0]); const sizeValues = sizeKey != null ? this.dataModel.resolveColumnById(this, `sizeValue`, this.processedData) : void 0; const sizeValue = sizeValues != null ? sizeScale.convert(sizeValues[index]) : size; const r = 0.5 * sizeValue * pixelSize; return [y - r, y + r]; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!processedData || !dataModel) return []; const dataValues = { ["x" /* X */]: "xValue", ["y" /* Y */]: "yValue" }; const id = dataValues[direction]; const dataDef = dataModel.resolveProcessedDataDefById(this, id); const domain = dataModel.getDomain(this, id, "value", processedData); if (dataDef?.def.type === "value" && dataDef?.def.valueType === "category") { return domain; } const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */; const crossId = dataValues[crossDirection]; const ext = this.domainForClippedRange(direction, [id], crossId, false); return fixNumericExtent(extent(ext)); } getSeriesRange(_direction, visibleRange) { return this.domainForVisibleRange("y" /* Y */, ["yValue"], "xValue", visibleRange, false); } getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) { return this.countVisibleItems("xValue", ["yValue"], xVisibleRange, yVisibleRange, minVisibleItems); } createNodeData() { const { axes, dataModel, processedData, colorScale, sizeScale, visible } = this; const { xKey, yKey, sizeKey, xFilterKey, yFilterKey, sizeFilterKey, labelKey, xName, yName, sizeName, labelName, label, colorKey, marker } = this.properties; const { placement } = label; const anchor = Marker.anchor(marker.shape); const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!(dataModel && processedData && visible && xAxis && yAxis)) { return; } const xDataValues = dataModel.resolveColumnById(this, `xValue`, processedData); const yDataValues = dataModel.resolveColumnById(this, `yValue`, processedData); const sizeDataValues = sizeKey != null ? dataModel.resolveColumnById(this, `sizeValue`, processedData) : void 0; const colorDataValues = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0; const labelDataValues = labelKey != null ? dataModel.resolveColumnById(this, `labelValue`, processedData) : void 0; const xFilterDataValues = xFilterKey != null ? dataModel.resolveColumnById(this, `xFilterValue`, processedData) : void 0; const yFilterDataValues = yFilterKey != null ? dataModel.resolveColumnById(this, `yFilterValue`, processedData) : void 0; const sizeFilterDataValues = sizeFilterKey != null ? dataModel.resolveColumnById(this, `sizeFilterValue`, processedData) : void 0; const xScale = xAxis.scale; const yScale = yAxis.scale; const xOffset = (xScale.bandwidth ?? 0) / 2; const yOffset = (yScale.bandwidth ?? 0) / 2; const nodeData = []; sizeScale.range = [marker.size, marker.maxSize]; const font3 = label.getFont(); const textMeasurer = CachedTextMeasurerPool.getMeasurer({ font: font3 }); processedData.dataSources.get(this.id)?.forEach((datum, datumIndex) => { const xDatum = xDataValues[datumIndex]; const yDatum = yDataValues[datumIndex]; const sizeValue = sizeDataValues?.[datumIndex]; const x = xScale.convert(xDatum) + xOffset; const y = yScale.convert(yDatum) + yOffset; let selected; if (xFilterDataValues != null && yFilterDataValues != null) { selected = xFilterDataValues[datumIndex] === xDatum && yFilterDataValues[datumIndex] === yDatum; if (sizeFilterDataValues != null) { selected && (selected = sizeFilterDataValues[datumIndex] === sizeValue); } } const labelText = this.getLabelText(label, { value: labelDataValues != null ? labelDataValues[datumIndex] : yDatum, datum, xKey, yKey, sizeKey, labelKey, xName, yName, sizeName, labelName }); const size = textMeasurer.measureText(String(labelText)); const markerSize = sizeValue != null ? sizeScale.convert(sizeValue) : marker.size; const fill = colorDataValues != null ? colorScale.convert(colorDataValues[datumIndex]) : void 0; nodeData.push({ series: this, itemId: yKey, yKey, xKey, datum, datumIndex, xValue: xDatum, yValue: yDatum, sizeValue, point: { x, y, size: markerSize }, midPoint: { x, y }, fill, label: { text: labelText, ...size }, anchor, placement, selected }); }); return { itemId: yKey, nodeData, labelData: nodeData, scales: this.calculateScaling(), visible: this.visible }; } isPathOrSelectionDirty() { return this.properties.marker.isDirty(); } getLabelData() { if (!this.isLabelEnabled()) return []; return this.contextNodeData?.labelData ?? []; } updateMarkerSelection(opts) { const { nodeData, markerSelection } = opts; if (this.properties.marker.isDirty()) { markerSelection.clear(); markerSelection.cleanup(); } const data = this.properties.marker.enabled ? nodeData : []; return markerSelection.update( data, void 0, (datum) => createDatumId([datum.xValue, datum.yValue, datum.label.text]) ); } getMarkerItemBaseStyle(highlighted) { const { properties } = this; const { marker } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? marker.fill, fillOpacity: highlightStyle?.fillOpacity ?? marker.fillOpacity, stroke: highlightStyle?.stroke ?? marker.stroke, strokeWidth: highlightStyle?.strokeWidth ?? marker.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? marker.strokeOpacity, lineDash: highlightStyle?.lineDash ?? marker.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? marker.lineDashOffset }; } getMarkerItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yKey, sizeKey, labelKey, marker } = properties; const { itemStyler } = marker; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, xKey, yKey, sizeKey, labelKey, highlighted, ...format }); }); } updateMarkerNodes(opts) { const { markerSelection, isHighlight: highlighted } = opts; const { xKey, yKey, sizeKey, labelKey, marker } = this.properties; const { size, shape, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = mergeDefaults(highlighted && this.properties.highlightStyle.item, marker.getStyle()); const baseStyle = { size, shape, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset }; this.sizeScale.range = [marker.size, marker.maxSize]; markerSelection.each((node, datum) => { this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yKey, sizeKey, labelKey }, baseStyle, { selected: datum.selected }); }); if (!highlighted) { this.properties.marker.markClean(); } } updatePlacedLabelData(labelData) { this.labelSelection.update( labelData.map((v) => ({ ...v.datum, point: { x: v.x, y: v.y, size: v.datum.point.size } })), (text3) => { text3.pointerEvents = 1 /* None */; } ); this.updateLabelNodes({ labelSelection: this.labelSelection }); } updateLabelNodes(opts) { const { label } = this.properties; opts.labelSelection.each((text3, datum) => { text3.text = datum.label.text; text3.fill = label.color; text3.x = datum.point?.x ?? 0; text3.y = datum.point?.y ?? 0; text3.fontStyle = label.fontStyle; text3.fontWeight = label.fontWeight; text3.fontSize = label.fontSize; text3.fontFamily = label.fontFamily; text3.textAlign = "left"; text3.textBaseline = "top"; }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { xKey, xName, yKey, yName, sizeKey, sizeName, labelKey, labelName, title, tooltip } = properties; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex]; if (xValue == null) return; const data = [ { label: xName, fallbackLabel: xKey, value: xAxis.formatDatum(xValue) }, { label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(yValue) } ]; if (sizeKey != null) { const sizeValue = dataModel.resolveColumnById(this, `sizeValue`, processedData)[datumIndex]; data.push({ label: sizeName, fallbackLabel: sizeKey, value: String(sizeValue) }); } const format = this.getMarkerItemBaseStyle(false); Object.assign(format, this.getMarkerItemStyleOverrides(String(datumIndex), datum, format, false)); return tooltip.formatTooltip( { title, symbol: this.legendItemSymbol(), data }, { seriesId, datum, title: yKey, xKey, xName, yKey, yName, sizeKey, sizeName, labelKey, labelName, ...format, ...this.getModuleTooltipParams() } ); } legendItemSymbol() { const { marker } = this.properties; const { shape, fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = marker; return { marker: { shape, fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke3 ?? "rgba(0, 0, 0, 0)", fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData() { if (!this.properties.isValid()) { return []; } const { id: seriesId, ctx: { legendManager }, visible } = this; const { yKey: itemId, yName, title } = this.properties; return [ { legendType: "category", id: seriesId, itemId, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }), label: { text: title ?? yName ?? itemId }, symbol: this.legendItemSymbol() } ]; } animateEmptyUpdateReady({ markerSelection, labelSelection }) { markerScaleInAnimation(this, this.ctx.animationManager, markerSelection); seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection); } isLabelEnabled() { return this.properties.label.enabled; } nodeFactory() { return new Group(); } getFormattedMarkerStyle(datum) { const { xKey, yKey, sizeKey, labelKey } = this.properties; return this.getMarkerStyle(this.properties.marker, { datum, xKey, yKey, sizeKey, labelKey, highlighted: false }); } computeFocusBounds(opts) { return computeMarkerFocusBounds(this, opts); } }; BubbleSeries.className = "BubbleSeries"; BubbleSeries.type = "bubble"; } }); // packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesModule.ts var BubbleSeriesModule; var init_bubbleSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesModule.ts"() { "use strict"; init_util3(); init_bubbleSeries(); BubbleSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["cartesian"], identifier: "bubble", moduleFactory: (ctx) => new BubbleSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: "number" /* NUMBER */, position: "bottom" /* BOTTOM */ }, { type: "number" /* NUMBER */, position: "left" /* LEFT */ } ], themeTemplate: { series: { shape: "circle", size: 7, maxSize: 30, fillOpacity: 0.8, tooltip: { position: { type: "node" } }, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } } } }, paletteFactory: singleSeriesPaletteFactory }; } }); // packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesProperties.ts var HistogramSeriesProperties; var init_histogramSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesProperties.ts"() { "use strict"; init_dropShadow(); init_validation2(); init_label(); init_seriesTooltip(); init_cartesianSeries(); HistogramSeriesProperties = class extends CartesianSeriesProperties { constructor() { super(...arguments); this.fillOpacity = 1; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.areaPlot = false; this.aggregation = "sum"; this.shadow = new DropShadow(); this.label = new Label(); this.tooltip = new SeriesTooltip(); } }; __decorateClass([ Validate(STRING) ], HistogramSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], HistogramSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], HistogramSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], HistogramSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], HistogramSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate(RATIO) ], HistogramSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate(COLOR_STRING, { optional: true }) ], HistogramSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], HistogramSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO) ], HistogramSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], HistogramSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], HistogramSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], HistogramSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate(BOOLEAN) ], HistogramSeriesProperties.prototype, "areaPlot", 2); __decorateClass([ Validate(ARRAY, { optional: true }) ], HistogramSeriesProperties.prototype, "bins", 2); __decorateClass([ Validate(UNION(["count", "sum", "mean"], "a histogram aggregation")) ], HistogramSeriesProperties.prototype, "aggregation", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], HistogramSeriesProperties.prototype, "binCount", 2); __decorateClass([ Validate(OBJECT) ], HistogramSeriesProperties.prototype, "shadow", 2); __decorateClass([ Validate(OBJECT) ], HistogramSeriesProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], HistogramSeriesProperties.prototype, "tooltip", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/histogramSeries.ts var defaultBinCount, HistogramSeries; var init_histogramSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/histogramSeries.ts"() { "use strict"; init_main(); init_fromToMotion(); init_rect(); init_number(); init_ticks(); init_aggregateFunctions(); init_dataModel(); init_processors(); init_seriesLabelUtil(); init_shapeUtil(); init_barUtil(); init_cartesianSeries(); init_histogramSeriesProperties(); init_quadtreeUtil(); defaultBinCount = 10; HistogramSeries = class extends CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */], datumSelectionGarbageCollection: false, animationResetFns: { datum: resetBarSelectionsFn, label: resetLabelFn } }); this.properties = new HistogramSeriesProperties(); this.calculatedBins = []; } // During processData phase, used to unify different ways of the user specifying // the bins. Returns bins in format[[min1, max1], [min2, max2], ... ]. deriveBins(xDomain) { const binStarts = createTicks(xDomain[0], xDomain[1], defaultBinCount); const binSize = tickStep(xDomain[0], xDomain[1], defaultBinCount); const [firstBinEnd] = binStarts; const expandStartToBin = (n) => [n, n + binSize]; return [[firstBinEnd - binSize, firstBinEnd], ...binStarts.map(expandStartToBin)]; } calculateNiceBins(domain, binCount) { const startGuess = Math.floor(domain[0]); const stop = domain[1]; const segments = binCount || 1; const { start: start2, binSize } = this.calculateNiceStart(startGuess, stop, segments); return this.getBins(start2, stop, binSize, segments); } getBins(start2, stop, step, count) { const bins = []; const precision = this.calculatePrecision(step); for (let i = 0; i < count; i++) { const a = Math.round((start2 + i * step) * precision) / precision; let b = Math.round((start2 + (i + 1) * step) * precision) / precision; if (i === count - 1) { b = Math.max(b, stop); } bins[i] = [a, b]; } return bins; } calculatePrecision(step) { let precision = 10; if (isFinite(step) && step > 0) { while (step < 1) { precision *= 10; step *= 10; } } return precision; } calculateNiceStart(a, b, segments) { const binSize = Math.abs(b - a) / segments; const order = Math.floor(Math.log10(binSize)); const magnitude = Math.pow(10, order); const start2 = Math.floor(a / magnitude) * magnitude; return { start: start2, binSize }; } async processData(dataController) { if (!this.visible) { this.processedData = void 0; this.animationState.transition("updateData"); } const { xKey, yKey, areaPlot, aggregation } = this.properties; const xScale = this.axes["x" /* X */]?.scale; const yScale = this.axes["y" /* Y */]?.scale; const { xScaleType, yScaleType } = this.getScaleInformation({ yScale, xScale }); const props = [keyProperty(xKey, xScaleType), SORT_DOMAIN_GROUPS]; if (yKey) { let aggProp = groupCount("groupAgg"); if (aggregation === "count") { } else if (aggregation === "sum") { aggProp = groupSum("groupAgg"); } else if (aggregation === "mean") { aggProp = groupAverage("groupAgg"); } if (areaPlot) { aggProp = area("groupAgg", aggProp); } props.push(valueProperty(yKey, yScaleType, { invalidValue: void 0 }), aggProp); } else { props.push(rowCountProperty("count")); let aggProp = groupCount("groupAgg"); if (areaPlot) { aggProp = area("groupAgg", aggProp); } props.push(aggProp); } const groupByFn = (dataSet) => { const xExtent = fixNumericExtent(dataSet.domain.keys[0]); if (xExtent.length === 0) { dataSet.domain.groups = []; return () => []; } const bins = isNumber(this.properties.binCount) ? this.calculateNiceBins(xExtent, this.properties.binCount) : this.properties.bins ?? this.deriveBins(xExtent); const binCount = bins.length; this.calculatedBins = [...bins]; return (keys) => { let xValue = keys[0]; if (isDate(xValue)) { xValue = xValue.getTime(); } if (!isNumber(xValue)) return []; for (let i = 0; i < binCount; i++) { const nextBin = bins[i]; if (xValue >= nextBin[0] && xValue < nextBin[1]) { return nextBin; } if (i === binCount - 1 && xValue <= nextBin[1]) { return nextBin; } } return []; }; }; if (!this.ctx.animationManager.isSkipped() && this.processedData) { props.push(diff(this.id, this.processedData, false)); } await this.requestDataModel(dataController, this.data, { props, groupByFn }); this.animationState.transition("updateData"); } xCoordinateRange() { return [NaN, NaN]; } yCoordinateRange() { return [NaN, NaN]; } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (!processedData || !dataModel || !this.calculatedBins.length) return []; const yDomain = dataModel.getDomain(this, `groupAgg`, "aggregate", processedData); const xDomainMin = this.calculatedBins?.[0][0]; const xDomainMax = this.calculatedBins?.[(this.calculatedBins?.length ?? 0) - 1][1]; if (direction === "x" /* X */) { return fixNumericExtent([xDomainMin, xDomainMax]); } return fixNumericExtent(yDomain); } getSeriesRange(_direction, [r0, r1]) { const { dataModel, processedData } = this; if (!dataModel || processedData?.type !== "grouped") return [NaN, NaN]; const xScale = this.axes["x" /* X */].scale; const yMin = 0; let yMax = -Infinity; processedData.groups.forEach(({ keys, aggregation }) => { const [[negativeAgg, positiveAgg] = [0, 0]] = aggregation; const [xDomainMin, xDomainMax] = keys; const [x0, x1] = findMinMax([xScale.convert(xDomainMin), xScale.convert(xDomainMax)]); if (x1 >= r0 && x0 <= r1) { const total = negativeAgg + positiveAgg; yMax = Math.max(yMax, total); } }); if (yMin > yMax) return [NaN, NaN]; return [yMin, yMax]; } createNodeData() { const { id: seriesId, axes, processedData, dataModel } = this; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!xAxis || !yAxis || !dataModel) { return; } const { scale: xScale } = xAxis; const { scale: yScale } = yAxis; const { xKey, yKey, xName, yName } = this.properties; const labelFormatter = this.properties.label.formatter ?? ((params) => String(params.value)); const nodeData = []; const context = { itemId: this.properties.yKey ?? this.id, nodeData, labelData: nodeData, scales: this.calculateScaling(), animationValid: true, visible: this.visible }; if (!this.visible || processedData == null || processedData.type !== "grouped") { return context; } processedData.groups.forEach((group, groupIndex) => { const { keys, datumIndices, aggregation } = group; const [[negativeAgg, positiveAgg] = [0, 0]] = aggregation; const frequency = datumIndices.length; const domain = keys; const [xDomainMin, xDomainMax] = domain; const datum = [...dataModel.forEachDatum(this, processedData, group)]; const xMinPx = xScale.convert(xDomainMin); const xMaxPx = xScale.convert(xDomainMax); const total = negativeAgg + positiveAgg; const yZeroPx = yScale.convert(0); const yMaxPx = yScale.convert(total); const w = Math.abs(xMaxPx - xMinPx); const h = Math.abs(yMaxPx - yZeroPx); const x = Math.min(xMinPx, xMaxPx); const y = Math.min(yZeroPx, yMaxPx); let selectionDatumLabel = void 0; if (total !== 0) { selectionDatumLabel = { x: x + w / 2, y: y + h / 2, text: this.cachedDatumCallback( createDatumId(groupIndex, "label"), () => labelFormatter({ value: total, datum, seriesId, xKey, yKey, xName, yName }) ) ?? String(total) }; } const nodeMidPoint = { x: x + w / 2, y: y + h / 2 }; const yAxisReversed = yAxis.isReversed(); nodeData.push({ series: this, datumIndex: groupIndex, datum, // required by SeriesNodeDatum, but might not make sense here // since each selection is an aggregation of multiple data. aggregatedValue: total, frequency, domain, yKey, xKey, x, y, xValue: xMinPx, yValue: yMaxPx, width: w, height: h, midPoint: nodeMidPoint, topLeftCornerRadius: !yAxisReversed, topRightCornerRadius: !yAxisReversed, bottomRightCornerRadius: yAxisReversed, bottomLeftCornerRadius: yAxisReversed, label: selectionDatumLabel, crisp: true }); }); nodeData.sort((a, b) => a.x - b.x); return context; } nodeFactory() { return new Rect(); } updateDatumSelection(opts) { const { nodeData, datumSelection } = opts; return datumSelection.update(nodeData, void 0, (datum) => datum.domain.join("_")); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset, cornerRadius: properties.cornerRadius }; } updateDatumNodes(opts) { const { isHighlight: isDatumHighlighted } = opts; const { shadow } = this.properties; const style = this.getItemBaseStyle(isDatumHighlighted); opts.datumSelection.each((rect, datum) => { const { cornerRadius } = style; const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius } = datum; applyShapeStyle(rect, style); rect.topLeftCornerRadius = topLeftCornerRadius ? cornerRadius : 0; rect.topRightCornerRadius = topRightCornerRadius ? cornerRadius : 0; rect.bottomRightCornerRadius = bottomRightCornerRadius ? cornerRadius : 0; rect.bottomLeftCornerRadius = bottomLeftCornerRadius ? cornerRadius : 0; rect.crisp = datum.crisp; rect.fillShadow = shadow; rect.visible = datum.height > 0; }); } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; return labelSelection.update(labelData, (text3) => { text3.pointerEvents = 1 /* None */; text3.textAlign = "center"; text3.textBaseline = "middle"; }); } updateLabelNodes(opts) { const { fontStyle, fontWeight, fontFamily, fontSize, color } = this.properties.label; const labelEnabled = this.isLabelEnabled(); opts.labelSelection.each((text3, datum) => { if (labelEnabled && datum?.label) { text3.text = datum.label.text; text3.x = datum.label.x; text3.y = datum.label.y; text3.fontStyle = fontStyle; text3.fontWeight = fontWeight; text3.fontFamily = fontFamily; text3.fontSize = fontSize; text3.fill = color; text3.visible = true; } else { text3.visible = false; } }); } initQuadTree(quadtree) { const { value: childNode } = this.contentGroup.children().next(); if (childNode) { addHitTestersToQuadtree(quadtree, childNode.children()); } } pickNodeClosestDatum(point) { return findQuadtreeMatch(this, point); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties, ctx: { localeManager } } = this; const { xKey, xName, yKey, yName, tooltip } = properties; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!dataModel || processedData?.type !== "grouped" || !xAxis || !yAxis) { return; } const groupIndex = nodeDatum.datumIndex; const group = processedData.groups[groupIndex]; const { aggregation, datumIndices, keys } = group; const [[negativeAgg, positiveAgg] = [0, 0]] = aggregation; const frequency = datumIndices.length; const domain = keys; const [rangeMin, rangeMax] = domain; const aggregatedValue = negativeAgg + positiveAgg; const datum = { data: [...dataModel.forEachDatum(this, processedData, group)], aggregatedValue, frequency, domain }; const data = [ { label: xName, fallbackLabel: xKey, value: `${xAxis.formatDatum(rangeMin)} - ${xAxis.formatDatum(rangeMax)}` }, { label: localeManager.t("seriesHistogramTooltipFrequency"), value: yAxis.formatDatum(frequency) } ]; if (yKey != null) { let label; switch (properties.aggregation) { case "sum": label = localeManager.t("seriesHistogramTooltipSum", { yName }); break; case "mean": label = localeManager.t("seriesHistogramTooltipMean", { yName }); break; case "count": label = localeManager.t("seriesHistogramTooltipCount", { yName }); break; } data.push({ label, value: yAxis.formatDatum(aggregatedValue) }); } return tooltip.formatTooltip( { symbol: this.legendItemSymbol(), data }, { seriesId, datum, title: yName, xKey, xName, yKey, yName, xRange: [rangeMin, rangeMax], frequency, ...this.getItemBaseStyle(false) } ); } legendItemSymbol() { const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { marker: { fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke3 ?? "rgba(0, 0, 0, 0)", fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (legendType !== "category") { return []; } const { id: seriesId, ctx: { legendManager }, visible } = this; const { xKey: itemId, yName, showInLegend } = this.properties; return [ { legendType: "category", id: seriesId, itemId, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }), label: { text: yName ?? itemId ?? "Frequency" }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } animateEmptyUpdateReady({ datumSelection, labelSelection }) { const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(true, this.axes, "normal")); fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], fns); seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection); } animateWaitingUpdateReady(data) { const dataDiff = this.processedData?.reduced?.diff?.[this.id]; const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(true, this.axes, "normal")); fromToMotion( this.id, "datums", this.ctx.animationManager, [data.datumSelection], fns, (_, datum) => createDatumId(datum.domain), dataDiff ); seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, data.labelSelection); } isLabelEnabled() { return this.properties.label.enabled; } computeFocusBounds({ datumIndex }) { return computeBarFocusBounds(this, this.contextNodeData?.nodeData[datumIndex]); } }; HistogramSeries.className = "HistogramSeries"; HistogramSeries.type = "histogram"; } }); // packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesModule.ts var HistogramSeriesModule; var init_histogramSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesModule.ts"() { "use strict"; init_symbols(); init_histogramSeries(); HistogramSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["cartesian"], identifier: "histogram", moduleFactory: (ctx) => new HistogramSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: [ { type: "number" /* NUMBER */, position: "bottom" /* BOTTOM */ }, { type: "number" /* NUMBER */, position: "left" /* LEFT */ } ], themeTemplate: { series: { strokeWidth: 1, fillOpacity: 1, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" } }, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR, xOffset: 3, yOffset: 3, blur: 5 } } }, paletteFactory: ({ takeColors }) => { const { fills: [fill], strokes: [stroke3] } = takeColors(1); return { fill, stroke: stroke3 }; } }; } }); // packages/ag-charts-community/src/chart/series/cartesian/lineSeriesProperties.ts var LineSeriesProperties; var init_lineSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineSeriesProperties.ts"() { "use strict"; init_validation2(); init_label(); init_seriesMarker(); init_seriesTooltip(); init_cartesianSeries(); init_interpolationProperties(); LineSeriesProperties = class extends CartesianSeriesProperties { constructor() { super(...arguments); this.stroke = "#874349"; this.strokeWidth = 2; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.interpolation = new InterpolationProperties(); this.marker = new SeriesMarker(); this.label = new Label(); this.tooltip = new SeriesTooltip(); this.connectMissingData = false; this.sparklineMode = false; } }; __decorateClass([ Validate(STRING) ], LineSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate(STRING) ], LineSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], LineSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], LineSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], LineSeriesProperties.prototype, "yFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], LineSeriesProperties.prototype, "stackGroup", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], LineSeriesProperties.prototype, "normalizedTo", 2); __decorateClass([ Validate(STRING, { optional: true }) ], LineSeriesProperties.prototype, "title", 2); __decorateClass([ Validate(COLOR_STRING) ], LineSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LineSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate(RATIO) ], LineSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], LineSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], LineSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate(OBJECT) ], LineSeriesProperties.prototype, "interpolation", 2); __decorateClass([ Validate(OBJECT) ], LineSeriesProperties.prototype, "marker", 2); __decorateClass([ Validate(OBJECT) ], LineSeriesProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], LineSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate(BOOLEAN) ], LineSeriesProperties.prototype, "connectMissingData", 2); __decorateClass([ Validate(BOOLEAN) ], LineSeriesProperties.prototype, "sparklineMode", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/lineSeries.ts var CROSS_FILTER_LINE_STROKE_OPACITY_FACTOR, LineSeries; var init_lineSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineSeries.ts"() { "use strict"; init_main(); init_fromToMotion(); init_pathMotion(); init_resetMotion(); init_group(); init_extent(); init_object(); init_dataModel(); init_processors(); init_seriesLabelUtil(); init_util(); init_cartesianSeries(); init_lineSeriesProperties(); init_lineUtil(); init_markerUtil(); init_pathUtil(); CROSS_FILTER_LINE_STROKE_OPACITY_FACTOR = 0.25; LineSeries = class extends CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, hasMarkers: true, pickModes: [ 2 /* AXIS_ALIGNED */, 1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */ ], markerSelectionGarbageCollection: false, animationResetFns: { path: buildResetPathFn({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }), label: resetLabelFn, marker: (node, datum) => ({ ...resetMarkerFn(node), ...resetMarkerPositionFn(node, datum) }) } }); this.clipFocusBox = false; this.properties = new LineSeriesProperties(); this.dataAggregationFilters = void 0; } get pickModeAxis() { return this.properties.sparklineMode ? "main" : "main-category"; } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { data, visible, seriesGrouping: { groupIndex = this.id, stackCount = 0 } = {} } = this; const { xKey, yKey, yFilterKey, connectMissingData, normalizedTo } = this.properties; const animationEnabled = !this.ctx.animationManager.isSkipped(); const xScale = this.axes["x" /* X */]?.scale; const yScale = this.axes["y" /* Y */]?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const stacked = stackCount >= 1 || normalizedTo != null; const common = { invalidValue: null }; if (connectMissingData && stacked) { common.invalidValue = 0; } if (stacked && !visible) { common.forceValue = 0; } const props = []; if (!isContinuousX || stacked) { props.push(keyProperty(xKey, xScaleType, { id: "xKey" })); } props.push( valueProperty(xKey, xScaleType, { id: "xValue" }), valueProperty(yKey, yScaleType, { id: `yValueRaw`, ...common, invalidValue: void 0 }) ); if (yFilterKey != null) { props.push(valueProperty(yFilterKey, yScaleType, { id: "yFilterRaw" })); } if (stacked) { const ids = [ `line-stack-${groupIndex}-yValues`, `line-stack-${groupIndex}-yValues-trailing`, `line-stack-${groupIndex}-yValues-marker` ]; props.push( ...groupAccumulativeValueProperty( yKey, "window", "current", { id: `yValueEnd`, ...common, groupId: ids[0] }, yScaleType ), ...groupAccumulativeValueProperty( yKey, "window-trailing", "current", { id: `yValueStart`, ...common, groupId: ids[1] }, yScaleType ), ...groupAccumulativeValueProperty( yKey, "normal", "current", { id: `yValueCumulative`, ...common, groupId: ids[2] }, yScaleType ) ); if (isDefined(normalizedTo)) { props.push(normaliseGroupTo([ids[0], ids[1], ids[2]], normalizedTo)); } } if (animationEnabled) { props.push(animationValidation(isContinuousX ? ["xValue"] : void 0)); if (this.processedData) { props.push(diff(this.id, this.processedData)); } } const { dataModel, processedData } = await this.requestDataModel(dataController, data, { props, groupByKeys: stacked, groupByData: !stacked }); this.dataAggregationFilters = this.aggregateData(dataModel, processedData); this.animationState.transition("updateData"); } xCoordinateRange(xValue, pixelSize) { const { marker } = this.properties; const x = this.axes["x" /* X */].scale.convert(xValue); const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0; return [x - r, x + r]; } yCoordinateRange(yValues, pixelSize) { const { marker } = this.properties; const y = this.axes["y" /* Y */].scale.convert(yValues[0]); const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0; return [y - r, y + r]; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!dataModel || !processedData) return []; if (direction === "x" /* X */) { const xDef = dataModel.resolveProcessedDataDefById(this, `xValue`); const domain = dataModel.getDomain(this, `xValue`, "value", processedData); if (xDef?.def.type === "value" && xDef.def.valueType === "category") { return domain; } return fixNumericExtent(extent(domain)); } const yKey = this.dataModel?.hasColumnById(this, `yValueEnd`) ? "yValueEnd" : "yValueRaw"; const yExtent = this.domainForClippedRange("y" /* Y */, [yKey], "xValue", true); return fixNumericExtent(yExtent); } getSeriesRange(_direction, visibleRange) { const yKey = this.dataModel?.hasColumnById(this, `yValueEnd`) ? "yValueEnd" : "yValueRaw"; return this.domainForVisibleRange("y" /* Y */, [yKey], "xValue", visibleRange, true); } getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) { const yKey = this.dataModel?.hasColumnById(this, `yValueEnd`) ? "yValueEnd" : "yValueRaw"; return this.countVisibleItems("xValue", [yKey], xVisibleRange, yVisibleRange, minVisibleItems); } aggregateData(_dataModel, _processedData) { return; } createNodeData() { const { dataModel, processedData, axes, dataAggregationFilters } = this; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!dataModel || !processedData || !xAxis || !yAxis) return; const { xKey, yKey, yFilterKey, xName, yName, marker, label, connectMissingData, interpolation, legendItemName } = this.properties; const stacked = this.dataModel?.hasColumnById(this, `yValueEnd`); const xScale = xAxis.scale; const yScale = yAxis.scale; const xOffset = (xScale.bandwidth ?? 0) / 2; const yOffset = (yScale.bandwidth ?? 0) / 2; const size = marker.enabled ? marker.size : 0; const rawData = processedData.dataSources.get(this.id) ?? []; const xValues = dataModel.resolveColumnById(this, `xValue`, processedData); const yValues = dataModel.resolveColumnById(this, `yValueRaw`, processedData); const yEndValues = stacked ? dataModel.resolveColumnById(this, `yValueEnd`, processedData) : void 0; const yCumulativeValues = stacked ? dataModel.resolveColumnById(this, `yValueCumulative`, processedData) : yValues; const selectionValues = yFilterKey != null ? dataModel.resolveColumnById(this, `yFilterRaw`, processedData) : void 0; const xPosition = (index) => xScale.convert(xValues[index]) + xOffset; const yPosition = (index) => yScale.convert(yCumulativeValues[index]) + yOffset; const capDefaults = { lengthRatioMultiplier: this.properties.marker.getDiameter(), lengthMax: Infinity }; const nodeData = []; let spanPoints; const handleDatum = (datumIndex) => { const datum = rawData[datumIndex]; const xDatum = xValues[datumIndex]; const yDatum = yValues[datumIndex]; const yEndDatum = yEndValues?.[datumIndex]; const selected = selectionValues?.[datumIndex]; const x = xPosition(datumIndex); const y = yPosition(datumIndex); if (!Number.isFinite(x)) return; if (yDatum != null) { const labelText = label.enabled ? this.getLabelText(label, { value: yDatum, datum, xKey, yKey, xName, yName, legendItemName }) : void 0; nodeData.push({ series: this, datum, datumIndex, yKey, xKey, point: { x, y, size }, midPoint: { x, y }, cumulativeValue: yEndDatum, yValue: yDatum, xValue: xDatum, capDefaults, labelText, selected }); } if (spanPoints == null) return; const currentSpanPoints = spanPoints[spanPoints.length - 1]; if (yDatum != null) { const spanPoint = { point: { x, y }, xDatum, yDatum }; if (Array.isArray(currentSpanPoints)) { currentSpanPoints.push(spanPoint); } else if (currentSpanPoints != null) { currentSpanPoints.skip += 1; spanPoints.push([spanPoint]); } else { spanPoints.push([spanPoint]); } } else if (!connectMissingData) { if (Array.isArray(currentSpanPoints) || currentSpanPoints == null) { spanPoints.push({ skip: 0 }); } else { currentSpanPoints.skip += 1; } } }; const [r0, r1] = xScale.range; const range4 = r1 - r0; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range4); const indices = dataAggregationFilter?.indices; let [start2, end2] = this.visibleRange("xValue", xAxis.range, indices); start2 = Math.max(start2 - 1, 0); end2 = Math.min(end2 + 1, indices?.length ?? xValues.length); if (processedData.input.count < 1e3) { start2 = 0; end2 = processedData.input.count; } if (indices == null) { spanPoints = []; } for (let i = start2; i < end2; i += 1) { handleDatum(indices?.[i] ?? i); } const strokeSpans = spanPoints?.flatMap((p) => { return Array.isArray(p) ? interpolatePoints(p, interpolation) : []; }); const strokeData = strokeSpans != null ? { itemId: yKey, spans: strokeSpans } : void 0; const crossFiltering = selectionValues?.some((selectionValue, index) => selectionValue === yValues[index]) ?? false; return { itemId: yKey, nodeData, labelData: nodeData, strokeData, scales: this.calculateScaling(), visible: this.visible, crossFiltering }; } isPathOrSelectionDirty() { return this.properties.marker.isDirty(); } updatePathNodes(opts) { const { paths: [lineNode], opacity, visible, animationEnabled } = opts; const crossFiltering = this.contextNodeData?.crossFiltering === true; lineNode.setProperties({ fill: void 0, lineJoin: "round", pointerEvents: 1 /* None */, opacity, stroke: this.properties.stroke, strokeWidth: this.getStrokeWidth(this.properties.strokeWidth), strokeOpacity: this.properties.strokeOpacity * (crossFiltering ? CROSS_FILTER_LINE_STROKE_OPACITY_FACTOR : 1), lineDash: this.properties.lineDash, lineDashOffset: this.properties.lineDashOffset }); if (!animationEnabled) { lineNode.visible = visible; } updateClipPath(this, lineNode); } getMarkerItemBaseStyle(highlighted) { const { properties } = this; const { marker } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { size: marker.size, shape: marker.shape, fill: highlightStyle?.fill ?? marker.fill, fillOpacity: highlightStyle?.fillOpacity ?? marker.fillOpacity, stroke: highlightStyle?.stroke ?? marker.stroke, strokeWidth: highlightStyle?.strokeWidth ?? marker.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? marker.strokeOpacity, lineDash: highlightStyle?.lineDash ?? marker.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? marker.lineDashOffset }; } getMarkerItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yKey, marker } = properties; const { itemStyler } = marker; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId(datumId, highlighted ? "highlight" : "node"), () => { const xDomain = this.getSeriesDomain("x" /* X */); const yDomain = this.getSeriesDomain("y" /* Y */); return itemStyler({ seriesId, ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), highlighted, ...format }); }); } updateMarkerSelection(opts) { let { nodeData } = opts; const { markerSelection } = opts; const markersEnabled = this.properties.marker.enabled || this.contextNodeData?.crossFiltering === true; nodeData = markersEnabled ? nodeData : []; if (this.properties.marker.isDirty()) { markerSelection.clear(); markerSelection.cleanup(); } return markerSelection.update(nodeData, void 0, (datum) => createDatumId(datum.xValue)); } updateMarkerNodes(opts) { const { markerSelection, isHighlight: highlighted } = opts; const { xKey, yKey, stroke: stroke3, strokeWidth, strokeOpacity, marker, highlightStyle } = this.properties; const xDomain = this.getSeriesDomain("x" /* X */); const yDomain = this.getSeriesDomain("y" /* Y */); const baseStyle = mergeDefaults(highlighted && highlightStyle.item, marker.getStyle(), { stroke: stroke3, strokeWidth, strokeOpacity }); const applyTranslation = this.ctx.animationManager.isSkipped(); markerSelection.each((node, datum) => { this.updateMarkerStyle( node, marker, { ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), highlighted }, baseStyle, { applyTranslation, selected: datum.selected } ); }); if (!highlighted) { marker.markClean(); } } updateLabelSelection(opts) { return opts.labelSelection.update(this.isLabelEnabled() ? opts.labelData : []); } updateLabelNodes(opts) { const { enabled, fontStyle, fontWeight, fontSize, fontFamily, color } = this.properties.label; opts.labelSelection.each((text3, datum) => { if (enabled && datum?.labelText) { text3.fontStyle = fontStyle; text3.fontWeight = fontWeight; text3.fontSize = fontSize; text3.fontFamily = fontFamily; text3.textAlign = "center"; text3.textBaseline = "bottom"; text3.text = datum.labelText; text3.x = datum.point.x; text3.y = datum.point.y - 10; text3.fill = color; text3.visible = true; } else { text3.visible = false; } }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { xKey, xName, yKey, yName, tooltip } = properties; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!dataModel || !processedData || !xAxis || !yAxis) { return; } const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValueRaw`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getMarkerItemBaseStyle(false); Object.assign(format, this.getMarkerItemStyleOverrides(String(datumIndex), datum, format, false)); return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), symbol: this.legendItemSymbol(), data: [{ label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(yValue) }] }, { seriesId, datum, title: yName, xKey, xName, yKey, yName, ...format, ...this.getModuleTooltipParams() } ); } legendItemSymbol() { const color0 = "rgba(0, 0, 0, 0)"; const { stroke: stroke3, strokeOpacity, strokeWidth, lineDash, marker } = this.properties; return { marker: { shape: marker.shape, fill: marker.fill ?? color0, stroke: marker.stroke ?? stroke3 ?? color0, fillOpacity: marker.fillOpacity, strokeOpacity: marker.strokeOpacity, strokeWidth: marker.strokeWidth, lineDash: marker.lineDash, lineDashOffset: marker.lineDashOffset, enabled: marker.enabled }, line: { stroke: stroke3 ?? color0, strokeOpacity, strokeWidth, lineDash } }; } getLegendData(legendType) { if (!(this.properties.isValid() && legendType === "category")) { return []; } const { id: seriesId, ctx: { legendManager }, visible } = this; const { yKey: itemId, yName, title, legendItemName, showInLegend } = this.properties; return [ { legendType: "category", id: seriesId, itemId, legendItemName, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }), label: { text: legendItemName ?? title ?? yName ?? itemId }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } updatePaths(opts) { this.updateLinePaths(opts.paths, opts.contextData); } plotNodeDataPoints(path, nodeData) { if (nodeData.length === 0) return; const initialPoint = nodeData[0].point; path.moveTo(initialPoint.x, initialPoint.y); for (let i = 1; i < nodeData.length; i += 1) { const { x, y } = nodeData[i].point; path.lineTo(x, y); } } updateLinePaths(paths, contextData) { const spans = contextData.strokeData?.spans; const [lineNode] = paths; lineNode.path.clear(); if (spans != null) { plotLinePathStroke(lineNode, spans); } else { this.plotNodeDataPoints(lineNode.path, contextData.nodeData); } lineNode.markDirty(); } animateEmptyUpdateReady(animationData) { const { markerSelection, labelSelection, annotationSelections, contextData, paths } = animationData; const { animationManager } = this.ctx; this.updateLinePaths(paths, contextData); pathSwipeInAnimation(this, animationManager, ...paths); resetMotion([markerSelection], resetMarkerPositionFn); markerSwipeScaleInAnimation(this, animationManager, markerSelection); seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection); seriesLabelFadeInAnimation(this, "annotations", animationManager, ...annotationSelections); } animateReadyResize(animationData) { const { contextData, paths } = animationData; this.updateLinePaths(paths, contextData); super.animateReadyResize(animationData); } animateWaitingUpdateReady(animationData) { const { animationManager } = this.ctx; const { markerSelection: markerSelections, labelSelection: labelSelections, annotationSelections, contextData, paths, previousContextData } = animationData; const [path] = paths; this.resetMarkerAnimation(animationData); this.resetLabelAnimation(animationData); const update = () => { this.resetPathAnimation(animationData); this.updateLinePaths(paths, contextData); }; const skip = () => { animationManager.skipCurrentBatch(); update(); }; if (contextData == null || previousContextData == null) { update(); markerFadeInAnimation(this, animationManager, "added", markerSelections); pathFadeInAnimation(this, "path_properties", animationManager, "add", path); seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections); seriesLabelFadeInAnimation(this, "annotations", animationManager, ...annotationSelections); return; } if (contextData.crossFiltering !== previousContextData.crossFiltering) { skip(); return; } const fns = prepareLinePathAnimation( contextData, previousContextData, this.processedData?.reduced?.diff?.[this.id] ); if (fns === void 0) { skip(); return; } else if (fns.status === "no-op") { return; } fromToMotion(this.id, "path_properties", animationManager, [path], fns.stroke.pathProperties); if (fns.status === "added") { this.updateLinePaths(paths, contextData); } else if (fns.status === "removed") { this.updateLinePaths(paths, previousContextData); } else { pathMotion(this.id, "path_update", animationManager, [path], fns.stroke.path); } if (fns.hasMotion) { markerFadeInAnimation(this, animationManager, void 0, markerSelections); seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections); seriesLabelFadeInAnimation(this, "annotations", animationManager, ...annotationSelections); } } isLabelEnabled() { return this.properties.label.enabled; } getBandScalePadding() { return { inner: 1, outer: 0.1 }; } nodeFactory() { return new Group(); } getFormattedMarkerStyle(datum) { const { xKey, yKey } = this.properties; const xDomain = this.getSeriesDomain("x" /* X */); const yDomain = this.getSeriesDomain("y" /* Y */); return this.getMarkerStyle(this.properties.marker, { ...datumStylerProperties(datum, xKey, yKey, xDomain, yDomain), highlighted: true }); } computeFocusBounds(opts) { return computeMarkerFocusBounds(this, opts); } }; LineSeries.className = "LineSeries"; LineSeries.type = "line"; } }); // packages/ag-charts-community/src/chart/series/cartesian/lineSeriesModule.ts var LineSeriesModule; var init_lineSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/lineSeriesModule.ts"() { "use strict"; init_util3(); init_lineSeries(); LineSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["cartesian"], identifier: "line", moduleFactory: (ctx) => new LineSeries(ctx), stackable: true, tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: "number" /* NUMBER */, position: "left" /* LEFT */ }, { type: "category" /* CATEGORY */, position: "bottom" /* BOTTOM */ } ], themeTemplate: { series: { tooltip: { position: { type: "node" } }, strokeWidth: 2, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0, interpolation: { type: "linear", tension: 1, position: "end" }, marker: { shape: "circle", size: 7, strokeWidth: 0 }, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } }, errorBar: { cap: { lengthRatio: 1 } } } }, paletteFactory: (params) => { const { marker } = markerPaletteFactory(params); return { stroke: marker.fill, marker }; } }; } }); // packages/ag-charts-community/src/chart/series/cartesian/scatterSeriesProperties.ts var ScatterSeriesLabel, ScatterSeriesProperties; var init_scatterSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/scatterSeriesProperties.ts"() { "use strict"; init_proxy(); init_validation2(); init_label(); init_seriesMarker(); init_seriesTooltip(); init_cartesianSeries(); ScatterSeriesLabel = class extends Label { constructor() { super(...arguments); this.placement = "top"; } }; __decorateClass([ Validate(LABEL_PLACEMENT) ], ScatterSeriesLabel.prototype, "placement", 2); ScatterSeriesProperties = class extends CartesianSeriesProperties { constructor() { super(...arguments); this.colorRange = ["#ffff00", "#00ff00", "#0000ff"]; this.label = new ScatterSeriesLabel(); this.tooltip = new SeriesTooltip(); // No validation. Not a part of the options contract. this.marker = new SeriesMarker(); } }; __decorateClass([ Validate(STRING) ], ScatterSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate(STRING) ], ScatterSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "xFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "yFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate(NUMBER_ARRAY, { optional: true }) ], ScatterSeriesProperties.prototype, "colorDomain", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], ScatterSeriesProperties.prototype, "colorRange", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ScatterSeriesProperties.prototype, "title", 2); __decorateClass([ ProxyProperty("marker.shape") ], ScatterSeriesProperties.prototype, "shape", 2); __decorateClass([ ProxyProperty("marker.size") ], ScatterSeriesProperties.prototype, "size", 2); __decorateClass([ ProxyProperty("marker.fill") ], ScatterSeriesProperties.prototype, "fill", 2); __decorateClass([ ProxyProperty("marker.fillOpacity") ], ScatterSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ ProxyProperty("marker.stroke") ], ScatterSeriesProperties.prototype, "stroke", 2); __decorateClass([ ProxyProperty("marker.strokeWidth") ], ScatterSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ ProxyProperty("marker.strokeOpacity") ], ScatterSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ ProxyProperty("marker.lineDash") ], ScatterSeriesProperties.prototype, "lineDash", 2); __decorateClass([ ProxyProperty("marker.lineDashOffset") ], ScatterSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ ProxyProperty("marker.itemStyler", { optional: true }) ], ScatterSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate(OBJECT) ], ScatterSeriesProperties.prototype, "label", 2); __decorateClass([ Validate(OBJECT) ], ScatterSeriesProperties.prototype, "tooltip", 2); } }); // packages/ag-charts-community/src/chart/series/cartesian/scatterSeries.ts var ScatterSeries; var init_scatterSeries = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/scatterSeries.ts"() { "use strict"; init_colorScale(); init_group(); init_extent(); init_object(); init_textMeasurer(); init_dataModel(); init_processors(); init_marker(); init_seriesLabelUtil(); init_cartesianSeries(); init_markerUtil(); init_scatterSeriesProperties(); ScatterSeries = class extends CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, pickModes: [ 2 /* AXIS_ALIGNED */, 1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */ ], pathsPerSeries: [], hasMarkers: true, markerSelectionGarbageCollection: false, animationResetFns: { marker: resetMarkerFn, label: resetLabelFn }, usesPlacedLabels: true }); this.clipFocusBox = false; this.properties = new ScatterSeriesProperties(); this.colorScale = new ColorScale(); } get pickModeAxis() { return "main-category"; } async processData(dataController) { if (!this.properties.isValid() || this.data == null || !this.visible) return; const xScale = this.axes["x" /* X */]?.scale; const yScale = this.axes["y" /* Y */]?.scale; const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const colorScaleType = this.colorScale.type; const { xKey, yKey, xFilterKey, yFilterKey, labelKey, colorKey, colorDomain, colorRange } = this.properties; const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, { props: [ valueProperty(xKey, xScaleType, { id: `xValue` }), valueProperty(yKey, yScaleType, { id: `yValue` }), ...xFilterKey != null ? [valueProperty(xFilterKey, xScaleType, { id: "xFilterValue" })] : [], ...yFilterKey != null ? [valueProperty(yFilterKey, yScaleType, { id: "yFilterValue" })] : [], ...colorKey ? [valueProperty(colorKey, colorScaleType, { id: `colorValue` })] : [], ...labelKey ? [valueProperty(labelKey, "band", { id: `labelValue` })] : [] ] }); if (colorKey) { const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, `colorValue`); this.colorScale.domain = colorDomain ?? processedData.domain.values[colorKeyIdx] ?? []; this.colorScale.range = colorRange; this.colorScale.update(); } this.animationState.transition("updateData"); } xCoordinateRange(xValue, pixelSize) { const x = this.axes["x" /* X */].scale.convert(xValue); const r = 0.5 * this.properties.size * pixelSize; return [x - r, x + r]; } yCoordinateRange(yValues, pixelSize) { const y = this.axes["y" /* Y */].scale.convert(yValues[0]); const r = 0.5 * this.properties.size * pixelSize; return [y - r, y + r]; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!processedData || !dataModel) return []; const dataValues = { ["x" /* X */]: "xValue", ["y" /* Y */]: "yValue" }; const id = dataValues[direction]; const dataDef = dataModel.resolveProcessedDataDefById(this, id); const domain = dataModel.getDomain(this, id, "value", processedData); if (dataDef?.def.type === "value" && dataDef?.def.valueType === "category") { return domain; } const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */; const crossId = dataValues[crossDirection]; const ext = this.domainForClippedRange(direction, [id], crossId, false); return fixNumericExtent(extent(ext)); } getSeriesRange(_direction, visibleRange) { return this.domainForVisibleRange("y" /* Y */, ["yValue"], "xValue", visibleRange, false); } getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) { return this.countVisibleItems("xValue", ["yValue"], xVisibleRange, yVisibleRange, minVisibleItems); } createNodeData() { const { axes, dataModel, processedData, colorScale, visible } = this; const { xKey, yKey, xFilterKey, yFilterKey, labelKey, colorKey, xName, yName, labelName, marker, label } = this.properties; const { placement } = label; const anchor = Marker.anchor(marker.shape); const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!(dataModel && processedData && visible && xAxis && yAxis)) return; const xDataValues = dataModel.resolveColumnById(this, `xValue`, processedData); const yDataValues = dataModel.resolveColumnById(this, `yValue`, processedData); const colorDataValues = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0; const labelDataValues = labelKey != null ? dataModel.resolveColumnById(this, `labelValue`, processedData) : void 0; const xFilterDataValues = xFilterKey != null ? dataModel.resolveColumnById(this, `xFilterValue`, processedData) : void 0; const yFilterDataValues = yFilterKey != null ? dataModel.resolveColumnById(this, `yFilterValue`, processedData) : void 0; const xScale = xAxis.scale; const yScale = yAxis.scale; const xOffset = (xScale.bandwidth ?? 0) / 2; const yOffset = (yScale.bandwidth ?? 0) / 2; const nodeData = []; const font3 = label.getFont(); const textMeasurer = CachedTextMeasurerPool.getMeasurer({ font: font3 }); const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const xDatum = xDataValues[datumIndex]; const yDatum = yDataValues[datumIndex]; const x = xScale.convert(xDatum) + xOffset; const y = yScale.convert(yDatum) + yOffset; const selected = xFilterDataValues != null && yFilterDataValues != null ? xFilterDataValues[datumIndex] === xDatum && yFilterDataValues[datumIndex] === yDatum : void 0; const labelText = this.getLabelText(label, { value: labelDataValues != null ? labelDataValues?.[datumIndex] : yDatum, datum, xKey, yKey, labelKey, xName, yName, labelName }); const size = textMeasurer.measureText(labelText); const fill = colorDataValues != null ? colorScale.convert(colorDataValues[datumIndex]) : void 0; nodeData.push({ series: this, itemId: yKey, yKey, xKey, datum, datumIndex, xValue: xDatum, yValue: yDatum, capDefaults: { lengthRatioMultiplier: marker.getDiameter(), lengthMax: Infinity }, point: { x, y, size: marker.size }, midPoint: { x, y }, fill, label: { text: labelText, ...size }, anchor, placement, selected }); }); return { itemId: yKey, nodeData, labelData: nodeData, scales: this.calculateScaling(), visible: this.visible }; } isPathOrSelectionDirty() { return this.properties.marker.isDirty(); } getLabelData() { if (!this.isLabelEnabled()) return []; return this.contextNodeData?.labelData ?? []; } updateMarkerSelection(opts) { const { nodeData, markerSelection } = opts; if (this.properties.marker.isDirty()) { markerSelection.clear(); markerSelection.cleanup(); } return markerSelection.update(this.properties.marker.enabled ? nodeData : []); } getMarkerItemBaseStyle(highlighted) { const { properties } = this; const { marker } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? marker.fill, fillOpacity: highlightStyle?.fillOpacity ?? marker.fillOpacity, stroke: highlightStyle?.stroke ?? marker.stroke, strokeWidth: highlightStyle?.strokeWidth ?? marker.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? marker.strokeOpacity, lineDash: highlightStyle?.lineDash ?? marker.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? marker.lineDashOffset }; } getMarkerItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yKey, labelKey, marker } = properties; const { itemStyler } = marker; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, xKey, yKey, labelKey, highlighted, ...format }); }); } updateMarkerNodes(opts) { const { markerSelection, isHighlight: highlighted } = opts; const { xKey, yKey, labelKey, marker, highlightStyle } = this.properties; const baseStyle = mergeDefaults(highlighted && highlightStyle.item, marker.getStyle()); markerSelection.each((node, datum) => { this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yKey, labelKey }, baseStyle, { selected: datum.selected }); }); if (!highlighted) { marker.markClean(); } } updatePlacedLabelData(labelData) { this.labelSelection.update( labelData.map((v) => ({ ...v.datum, point: { x: v.x, y: v.y, size: v.datum.point.size } })), (text3) => { text3.pointerEvents = 1 /* None */; } ); this.updateLabelNodes({ labelSelection: this.labelSelection }); } updateLabelNodes(opts) { const { label } = this.properties; opts.labelSelection.each((text3, datum) => { text3.text = datum.label.text; text3.fill = label.color; text3.x = datum.point?.x ?? 0; text3.y = datum.point?.y ?? 0; text3.fontStyle = label.fontStyle; text3.fontWeight = label.fontWeight; text3.fontSize = label.fontSize; text3.fontFamily = label.fontFamily; text3.textAlign = "left"; text3.textBaseline = "top"; }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { xKey, xName, yKey, yName, labelKey, labelName, title, tooltip } = properties; const xAxis = axes["x" /* X */]; const yAxis = axes["y" /* Y */]; if (!dataModel || !processedData || !xAxis || !yAxis) { return; } const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getMarkerItemBaseStyle(false); Object.assign(format, this.getMarkerItemStyleOverrides(String(datumIndex), datum, format, false)); return tooltip.formatTooltip( { symbol: this.legendItemSymbol(), title, data: [ { label: xName, fallbackLabel: xKey, value: xAxis.formatDatum(xValue) }, { label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(yValue) } ] }, { seriesId, datum, title: yName, xKey, xName, yKey, yName, labelKey, labelName, ...format, ...this.getModuleTooltipParams() } ); } legendItemSymbol() { const { shape, fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.marker; return { marker: { shape, fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke3 ?? "rgba(0, 0, 0, 0)", fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (!this.properties.isValid() || legendType !== "category") { return []; } const { yKey: itemId, yName, title, showInLegend } = this.properties; const { id: seriesId, ctx: { legendManager }, visible } = this; return [ { legendType: "category", id: seriesId, itemId, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }), label: { text: title ?? yName ?? itemId }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } animateEmptyUpdateReady(data) { const { markerSelection, labelSelection, annotationSelections } = data; markerScaleInAnimation(this, this.ctx.animationManager, markerSelection); seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection); seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, ...annotationSelections); } isLabelEnabled() { return this.properties.label.enabled; } nodeFactory() { return new Group(); } getFormattedMarkerStyle(datum) { const { xKey, yKey, labelKey } = this.properties; return this.getMarkerStyle(this.properties.marker, { datum, xKey, yKey, labelKey, highlighted: true }); } computeFocusBounds(opts) { return computeMarkerFocusBounds(this, opts); } }; ScatterSeries.className = "ScatterSeries"; ScatterSeries.type = "scatter"; } }); // packages/ag-charts-community/src/chart/series/cartesian/scatterSeriesModule.ts var ScatterSeriesModule; var init_scatterSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/cartesian/scatterSeriesModule.ts"() { "use strict"; init_util3(); init_scatterSeries(); ScatterSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["cartesian"], identifier: "scatter", moduleFactory: (ctx) => new ScatterSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: "number" /* NUMBER */, position: "bottom" /* BOTTOM */ }, { type: "number" /* NUMBER */, position: "left" /* LEFT */ } ], themeTemplate: { series: { shape: "circle", size: 7, fillOpacity: 0.8, tooltip: { position: { type: "node" } }, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } }, errorBar: { cap: { lengthRatio: 1 } } } }, paletteFactory: singleSeriesPaletteFactory }; } }); // packages/ag-charts-community/src/scene/sectorBox.ts var SectorBox; var init_sectorBox = __esm({ "packages/ag-charts-community/src/scene/sectorBox.ts"() { "use strict"; init_interpolating(); SectorBox = class _SectorBox { constructor(startAngle, endAngle, innerRadius, outerRadius) { this.startAngle = startAngle; this.endAngle = endAngle; this.innerRadius = innerRadius; this.outerRadius = outerRadius; } clone() { const { startAngle, endAngle, innerRadius, outerRadius } = this; return new _SectorBox(startAngle, endAngle, innerRadius, outerRadius); } equals(other) { return this.startAngle === other.startAngle && this.endAngle === other.endAngle && this.innerRadius === other.innerRadius && this.outerRadius === other.outerRadius; } [interpolate](other, d) { return new _SectorBox( this.startAngle * (1 - d) + other.startAngle * d, this.endAngle * (1 - d) + other.endAngle * d, this.innerRadius * (1 - d) + other.innerRadius * d, this.outerRadius * (1 - d) + other.outerRadius * d ); } }; } }); // packages/ag-charts-community/src/scene/util/sector.ts function sectorBox({ startAngle, endAngle, innerRadius, outerRadius }) { let x0 = Infinity; let y0 = Infinity; let x1 = -Infinity; let y1 = -Infinity; const addPoint = (x, y) => { x0 = Math.min(x, x0); y0 = Math.min(y, y0); x1 = Math.max(x, x1); y1 = Math.max(y, y1); }; addPoint(innerRadius * Math.cos(startAngle), innerRadius * Math.sin(startAngle)); addPoint(innerRadius * Math.cos(endAngle), innerRadius * Math.sin(endAngle)); addPoint(outerRadius * Math.cos(startAngle), outerRadius * Math.sin(startAngle)); addPoint(outerRadius * Math.cos(endAngle), outerRadius * Math.sin(endAngle)); if (isBetweenAngles(0, startAngle, endAngle)) { addPoint(outerRadius, 0); } if (isBetweenAngles(Math.PI * 0.5, startAngle, endAngle)) { addPoint(0, outerRadius); } if (isBetweenAngles(Math.PI, startAngle, endAngle)) { addPoint(-outerRadius, 0); } if (isBetweenAngles(Math.PI * 1.5, startAngle, endAngle)) { addPoint(0, -outerRadius); } return new BBox(x0, y0, x1 - x0, y1 - y0); } function isPointInSector(x, y, sector) { const radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); const { innerRadius, outerRadius } = sector; if (sector.startAngle === sector.endAngle || radius < Math.min(innerRadius, outerRadius) || radius > Math.max(innerRadius, outerRadius)) { return false; } const startAngle = normalizeAngle180(sector.startAngle); const endAngle = normalizeAngle180(sector.endAngle); const angle2 = Math.atan2(y, x); return startAngle < endAngle ? angle2 <= endAngle && angle2 >= startAngle : angle2 <= endAngle && angle2 >= -Math.PI || angle2 >= startAngle && angle2 <= Math.PI; } function lineCollidesSector(line, sector) { const { startAngle, endAngle, innerRadius, outerRadius } = sector; const outerStart = { x: outerRadius * Math.cos(startAngle), y: outerRadius * Math.sin(startAngle) }; const outerEnd = { x: outerRadius * Math.cos(endAngle), y: outerRadius * Math.sin(endAngle) }; const innerStart = innerRadius === 0 ? { x: 0, y: 0 } : { x: innerRadius * Math.cos(startAngle), y: innerRadius * Math.sin(startAngle) }; const innerEnd = innerRadius === 0 ? { x: 0, y: 0 } : { x: innerRadius * Math.cos(endAngle), y: innerRadius * Math.sin(endAngle) }; return segmentIntersection( line.start.x, line.start.y, line.end.x, line.end.y, outerStart.x, outerStart.y, innerStart.x, innerStart.y ) || segmentIntersection( line.start.x, line.start.y, line.end.x, line.end.y, outerEnd.x, outerEnd.y, innerEnd.x, innerEnd.y ) || arcIntersections( 0, 0, outerRadius, startAngle, endAngle, true, line.start.x, line.start.y, line.end.x, line.end.y ); } function boxCollidesSector(box, sector) { const topLeft = { x: box.x, y: box.y }; const topRight = { x: box.x + box.width, y: box.y }; const bottomLeft = { x: box.x, y: box.y + box.height }; const bottomRight = { x: box.x + box.width, y: box.y + box.height }; return lineCollidesSector({ start: topLeft, end: topRight }, sector) || lineCollidesSector({ start: bottomLeft, end: bottomRight }, sector); } function radiiScalingFactor(r, sweep, a, b) { if (a === 0 && b === 0) return 0; const fs1 = Math.asin(Math.abs(1 * a) / (r + 1 * a)) + Math.asin(Math.abs(1 * b) / (r + 1 * b)) - sweep; if (fs1 < 0) return 1; let start2 = 0; let end2 = 1; for (let i = 0; i < 8; i += 1) { const s = (start2 + end2) / 2; const fs = Math.asin(Math.abs(s * a) / (r + s * a)) + Math.asin(Math.abs(s * b) / (r + s * b)) - sweep; if (fs < 0) { start2 = s; } else { end2 = s; } } return start2; } function clockwiseAngle(angle2, relativeToStartAngle) { if (angleBetween(angle2, relativeToStartAngle) < delta2) { return relativeToStartAngle; } else { return normalizeAngle360(angle2 - relativeToStartAngle) + relativeToStartAngle; } } function clockwiseAngles(startAngle, endAngle, relativeToStartAngle = 0) { const fullPie = Math.abs(endAngle - startAngle) >= 2 * Math.PI; const sweepAngle = fullPie ? 2 * Math.PI : normalizeAngle360(endAngle - startAngle); startAngle = clockwiseAngle(startAngle, relativeToStartAngle); endAngle = startAngle + sweepAngle; return { startAngle, endAngle }; } function arcRadialLineIntersectionAngle(cx, cy, r, startAngle, endAngle, clipAngle) { const sinA = Math.sin(clipAngle); const cosA = Math.cos(clipAngle); const c = cx ** 2 + cy ** 2 - r ** 2; let p0x; let p0y; let p1x; let p1y; if (cosA > 0.5) { const tanA = sinA / cosA; const a = 1 + tanA ** 2; const b = -2 * (cx + cy * tanA); const d = b ** 2 - 4 * a * c; if (d < 0) return; const x0 = (-b + Math.sqrt(d)) / (2 * a); const x1 = (-b - Math.sqrt(d)) / (2 * a); p0x = x0; p0y = x0 * tanA; p1x = x1; p1y = x1 * tanA; } else { const cotA = cosA / sinA; const a = 1 + cotA ** 2; const b = -2 * (cy + cx * cotA); const d = b ** 2 - 4 * a * c; if (d < 0) return; const y0 = (-b + Math.sqrt(d)) / (2 * a); const y1 = (-b - Math.sqrt(d)) / (2 * a); p0x = y0 * cotA; p0y = y0; p1x = y1 * cotA; p1y = y1; } const normalisedX = cosA; const normalisedY = sinA; const p0DotNormalized = p0x * normalisedX + p0y * normalisedY; const p1DotNormalized = p1x * normalisedX + p1y * normalisedY; const a0 = p0DotNormalized > 0 ? clockwiseAngle(Math.atan2(p0y - cy, p0x - cx), startAngle) : NaN; const a1 = p1DotNormalized > 0 ? clockwiseAngle(Math.atan2(p1y - cy, p1x - cx), startAngle) : NaN; if (a0 >= startAngle && a0 <= endAngle) { return a0; } else if (a1 >= startAngle && a1 <= endAngle) { return a1; } } function arcCircleIntersectionAngle(cx, cy, r, startAngle, endAngle, circleR) { const d = Math.hypot(cx, cy); const d1 = (d ** 2 - r ** 2 + circleR ** 2) / (2 * d); const d2 = d - d1; const theta = Math.atan2(cy, cx); const deltaTheta = Math.acos(-d2 / r); const a0 = clockwiseAngle(theta + deltaTheta, startAngle); const a1 = clockwiseAngle(theta - deltaTheta, startAngle); if (a0 >= startAngle && a0 <= endAngle) { return a0; } else if (a1 >= startAngle && a1 <= endAngle) { return a1; } } var delta2; var init_sector = __esm({ "packages/ag-charts-community/src/scene/util/sector.ts"() { "use strict"; init_angle(); init_bbox(); init_intersection(); delta2 = 1e-6; } }); // packages/ag-charts-community/src/scene/shape/sector.ts var Arc, Sector; var init_sector2 = __esm({ "packages/ag-charts-community/src/scene/shape/sector.ts"() { "use strict"; init_sectorBox(); init_sector(); init_path(); Arc = class { constructor(cx, cy, r, a0, a1) { this.cx = cx; this.cy = cy; this.r = r; this.a0 = a0; this.a1 = a1; if (this.a0 >= this.a1) { this.a0 = NaN; this.a1 = NaN; } } isValid() { return Number.isFinite(this.a0) && Number.isFinite(this.a1); } pointAt(a) { return { x: this.cx + this.r * Math.cos(a), y: this.cy + this.r * Math.sin(a) }; } clipStart(a) { if (a == null || !this.isValid() || a < this.a0) return; this.a0 = a; if (Number.isNaN(a) || this.a0 >= this.a1) { this.a0 = NaN; this.a1 = NaN; } } clipEnd(a) { if (a == null || !this.isValid() || a > this.a1) return; this.a1 = a; if (Number.isNaN(a) || this.a0 >= this.a1) { this.a0 = NaN; this.a1 = NaN; } } }; Sector = class extends Path { constructor() { super(...arguments); this.centerX = 0; this.centerY = 0; this.innerRadius = 10; this.outerRadius = 20; this.startAngle = 0; this.endAngle = Math.PI * 2; this.clipSector = void 0; this.concentricEdgeInset = 0; this.radialEdgeInset = 0; this.startOuterCornerRadius = 0; this.endOuterCornerRadius = 0; this.startInnerCornerRadius = 0; this.endInnerCornerRadius = 0; } set inset(value) { this.concentricEdgeInset = value; this.radialEdgeInset = value; } set cornerRadius(value) { this.startOuterCornerRadius = value; this.endOuterCornerRadius = value; this.startInnerCornerRadius = value; this.endInnerCornerRadius = value; } computeBBox() { return sectorBox(this).translate(this.centerX, this.centerY); } normalizedRadii() { const { concentricEdgeInset } = this; let { innerRadius, outerRadius } = this; innerRadius = innerRadius > 0 ? innerRadius + concentricEdgeInset : 0; outerRadius = Math.max(outerRadius - concentricEdgeInset, 0); return { innerRadius, outerRadius }; } normalizedClipSector() { const { clipSector } = this; if (clipSector == null) return; const { startAngle, endAngle } = clockwiseAngles(this.startAngle, this.endAngle); const { innerRadius, outerRadius } = this.normalizedRadii(); const clipAngles = clockwiseAngles(clipSector.startAngle, clipSector.endAngle, startAngle); return new SectorBox( Math.max(startAngle, clipAngles.startAngle), Math.min(endAngle, clipAngles.endAngle), Math.max(innerRadius, clipSector.innerRadius), Math.min(outerRadius, clipSector.outerRadius) ); } getAngleOffset(radius) { return radius > 0 ? this.radialEdgeInset / radius : 0; } arc(r, angleSweep, a0, a1, outerArc, innerArc, start2, inner) { if (r <= 0) return; const { startAngle, endAngle } = clockwiseAngles(this.startAngle, this.endAngle); const { innerRadius, outerRadius } = this.normalizedRadii(); const clipSector = this.normalizedClipSector(); if (inner && innerRadius <= 0) return; const angleOffset = inner ? this.getAngleOffset(innerRadius + r) : this.getAngleOffset(outerRadius - r); const angle2 = start2 ? startAngle + angleOffset + angleSweep : endAngle - angleOffset - angleSweep; const radius = inner ? innerRadius + r : outerRadius - r; const cx = radius * Math.cos(angle2); const cy = radius * Math.sin(angle2); if (clipSector != null) { const delta4 = 1e-6; if (!start2 && !(angle2 >= startAngle - delta4 && angle2 <= clipSector.endAngle - delta4)) return; if (start2 && !(angle2 >= clipSector.startAngle + delta4 && angle2 <= endAngle - delta4)) return; if (inner && radius < clipSector.innerRadius - delta4) return; if (!inner && radius > clipSector.outerRadius + delta4) return; } const arc = new Arc(cx, cy, r, a0, a1); if (clipSector != null) { if (inner) { arc.clipStart(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.endAngle)); arc.clipEnd(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.startAngle)); } else { arc.clipStart(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.startAngle)); arc.clipEnd(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.endAngle)); } let circleClipStart; let circleClipEnd; if (start2) { circleClipStart = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.innerRadius); circleClipEnd = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.outerRadius); } else { circleClipStart = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.outerRadius); circleClipEnd = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.innerRadius); } arc.clipStart(circleClipStart); arc.clipEnd(circleClipEnd); if (circleClipStart != null) { const { x: x2, y: y2 } = arc.pointAt(circleClipStart); const theta2 = clockwiseAngle(Math.atan2(y2, x2), startAngle); if (start2) { innerArc?.clipStart(theta2); } else { outerArc.clipEnd(theta2); } } if (circleClipEnd != null) { const { x: x2, y: y2 } = arc.pointAt(circleClipEnd); const theta2 = clockwiseAngle(Math.atan2(y2, x2), startAngle); if (start2) { outerArc.clipStart(theta2); } else { innerArc?.clipEnd(theta2); } } } if (clipSector != null) { const { x: x2, y: y2 } = arc.pointAt((arc.a0 + arc.a1) / 2); if (!isPointInSector(x2, y2, clipSector)) return; } const { x, y } = arc.pointAt(start2 === inner ? arc.a0 : arc.a1); const theta = clockwiseAngle(Math.atan2(y, x), startAngle); const radialArc = inner ? innerArc : outerArc; if (start2) { radialArc?.clipStart(theta); } else { radialArc?.clipEnd(theta); } return arc; } updatePath() { const delta4 = 1e-6; const { path, centerX, centerY, concentricEdgeInset, radialEdgeInset } = this; let { startOuterCornerRadius, endOuterCornerRadius, startInnerCornerRadius, endInnerCornerRadius } = this; const { startAngle, endAngle } = clockwiseAngles(this.startAngle, this.endAngle); const { innerRadius, outerRadius } = this.normalizedRadii(); const clipSector = this.normalizedClipSector(); const sweepAngle = endAngle - startAngle; const fullPie = sweepAngle >= 2 * Math.PI - delta4; path.clear(); if (innerRadius === 0 && outerRadius === 0 || innerRadius > outerRadius) { return; } else if ((clipSector?.startAngle ?? startAngle) === (clipSector?.endAngle ?? endAngle)) { return; } else if (fullPie && this.clipSector == null && startOuterCornerRadius === 0 && endOuterCornerRadius === 0 && startInnerCornerRadius === 0 && endInnerCornerRadius === 0) { path.moveTo(centerX + outerRadius * Math.cos(startAngle), centerY + outerRadius * Math.sin(startAngle)); path.arc(centerX, centerY, outerRadius, startAngle, endAngle); if (innerRadius > concentricEdgeInset) { path.moveTo(centerX + innerRadius * Math.cos(endAngle), centerY + innerRadius * Math.sin(endAngle)); path.arc(centerX, centerY, innerRadius, endAngle, startAngle, true); } path.closePath(); return; } else if (this.clipSector == null && Math.abs(innerRadius - outerRadius) < 1e-6) { path.arc(centerX, centerY, outerRadius, startAngle, endAngle, false); path.arc(centerX, centerY, outerRadius, endAngle, startAngle, true); path.closePath(); return; } const innerAngleOffset = this.getAngleOffset(innerRadius); const outerAngleOffset = this.getAngleOffset(outerRadius); const outerAngleExceeded = sweepAngle < 2 * outerAngleOffset; if (outerAngleExceeded) return; const hasInnerSweep = (clipSector?.innerRadius ?? innerRadius) > concentricEdgeInset; const innerAngleExceeded = innerRadius < concentricEdgeInset || sweepAngle < 2 * innerAngleOffset; const radialLength = outerRadius - innerRadius; const maxRadialLength = Math.max( startOuterCornerRadius, startInnerCornerRadius, endOuterCornerRadius, endInnerCornerRadius ); const initialScalingFactor = maxRadialLength > 0 ? Math.min(radialLength / maxRadialLength, 1) : 1; startOuterCornerRadius *= initialScalingFactor; endOuterCornerRadius *= initialScalingFactor; startInnerCornerRadius *= initialScalingFactor; endInnerCornerRadius *= initialScalingFactor; const outerScalingFactor = radiiScalingFactor( outerRadius, sweepAngle - 2 * outerAngleOffset, -startOuterCornerRadius, -endOuterCornerRadius ); startOuterCornerRadius *= outerScalingFactor; endOuterCornerRadius *= outerScalingFactor; if (!innerAngleExceeded && hasInnerSweep) { const innerScalingFactor = radiiScalingFactor( innerRadius, sweepAngle - 2 * innerAngleOffset, startInnerCornerRadius, endInnerCornerRadius ); startInnerCornerRadius *= innerScalingFactor; endInnerCornerRadius *= innerScalingFactor; } else { startInnerCornerRadius = 0; endInnerCornerRadius = 0; } const maxCombinedRadialLength = Math.max( startOuterCornerRadius + startInnerCornerRadius, endOuterCornerRadius + endInnerCornerRadius ); const edgesScalingFactor = maxCombinedRadialLength > 0 ? Math.min(radialLength / maxCombinedRadialLength, 1) : 1; startOuterCornerRadius *= edgesScalingFactor; endOuterCornerRadius *= edgesScalingFactor; startInnerCornerRadius *= edgesScalingFactor; endInnerCornerRadius *= edgesScalingFactor; let startOuterCornerRadiusAngleSweep = 0; let endOuterCornerRadiusAngleSweep = 0; const startOuterCornerRadiusSweep = startOuterCornerRadius / (outerRadius - startOuterCornerRadius); const endOuterCornerRadiusSweep = endOuterCornerRadius / (outerRadius - endOuterCornerRadius); if (startOuterCornerRadiusSweep >= 0 && startOuterCornerRadiusSweep < 1 - delta4) { startOuterCornerRadiusAngleSweep = Math.asin(startOuterCornerRadiusSweep); } else { startOuterCornerRadiusAngleSweep = sweepAngle / 2; const maxStartOuterCornerRadius = outerRadius / (1 / Math.sin(startOuterCornerRadiusAngleSweep) + 1); startOuterCornerRadius = Math.min(maxStartOuterCornerRadius, startOuterCornerRadius); } if (endOuterCornerRadiusSweep >= 0 && endOuterCornerRadiusSweep < 1 - delta4) { endOuterCornerRadiusAngleSweep = Math.asin(endOuterCornerRadiusSweep); } else { endOuterCornerRadiusAngleSweep = sweepAngle / 2; const maxEndOuterCornerRadius = outerRadius / (1 / Math.sin(endOuterCornerRadiusAngleSweep) + 1); endOuterCornerRadius = Math.min(maxEndOuterCornerRadius, endOuterCornerRadius); } const startInnerCornerRadiusAngleSweep = Math.asin( startInnerCornerRadius / (innerRadius + startInnerCornerRadius) ); const endInnerCornerRadiusAngleSweep = Math.asin(endInnerCornerRadius / (innerRadius + endInnerCornerRadius)); const outerArcRadius = clipSector?.outerRadius ?? outerRadius; const outerArcRadiusOffset = this.getAngleOffset(outerArcRadius); const outerArc = new Arc( 0, 0, outerArcRadius, startAngle + outerArcRadiusOffset, endAngle - outerArcRadiusOffset ); const innerArcRadius = clipSector?.innerRadius ?? innerRadius; const innerArcRadiusOffset = this.getAngleOffset(innerArcRadius); const innerArc = hasInnerSweep ? new Arc(0, 0, innerArcRadius, startAngle + innerArcRadiusOffset, endAngle - innerArcRadiusOffset) : void 0; if (clipSector != null) { outerArc.clipStart(clipSector.startAngle); outerArc.clipEnd(clipSector.endAngle); innerArc?.clipStart(clipSector.startAngle); innerArc?.clipEnd(clipSector.endAngle); } const startOuterArc = this.arc( startOuterCornerRadius, startOuterCornerRadiusAngleSweep, startAngle - Math.PI * 0.5, startAngle + startOuterCornerRadiusAngleSweep, outerArc, innerArc, true, false ); const endOuterArc = this.arc( endOuterCornerRadius, endOuterCornerRadiusAngleSweep, endAngle - endOuterCornerRadiusAngleSweep, endAngle + Math.PI * 0.5, outerArc, innerArc, false, false ); const endInnerArc = this.arc( endInnerCornerRadius, endInnerCornerRadiusAngleSweep, endAngle + Math.PI * 0.5, endAngle + Math.PI - endInnerCornerRadiusAngleSweep, outerArc, innerArc, false, true ); const startInnerArc = this.arc( startInnerCornerRadius, startInnerCornerRadiusAngleSweep, startAngle + Math.PI + startInnerCornerRadiusAngleSweep, startAngle + Math.PI * 1.5, outerArc, innerArc, true, true ); if (innerAngleExceeded) { const x = sweepAngle < Math.PI * 0.5 ? radialEdgeInset * (1 + Math.cos(sweepAngle)) / Math.sin(sweepAngle) : NaN; let r; if (x > 0 && x < outerRadius) { r = Math.max(Math.hypot(radialEdgeInset, x), innerRadius); } else { r = radialEdgeInset; } r = Math.max(r, innerRadius); const midAngle = startAngle + sweepAngle * 0.5; path.moveTo(centerX + r * Math.cos(midAngle), centerY + r * Math.sin(midAngle)); } else if (startInnerArc?.isValid() === true || innerArc?.isValid() === true) { } else { const midAngle = startAngle + sweepAngle / 2; const cx = innerRadius * Math.cos(midAngle); const cy = innerRadius * Math.sin(midAngle); path.moveTo(centerX + cx, centerY + cy); } if (startOuterArc?.isValid() === true) { const { cx, cy, r, a0, a1 } = startOuterArc; path.arc(centerX + cx, centerY + cy, r, a0, a1); } if (outerArc.isValid()) { const { r, a0, a1 } = outerArc; path.arc(centerX, centerY, r, a0, a1); } if (endOuterArc?.isValid() === true) { const { cx, cy, r, a0, a1 } = endOuterArc; path.arc(centerX + cx, centerY + cy, r, a0, a1); } if (!innerAngleExceeded) { if (endInnerArc?.isValid() === true) { const { cx, cy, r, a0, a1 } = endInnerArc; path.arc(centerX + cx, centerY + cy, r, a0, a1); } if (innerArc?.isValid() === true) { const { r, a0, a1 } = innerArc; path.arc(centerX, centerY, r, a1, a0, true); } if (startInnerArc?.isValid() === true) { const { cx, cy, r, a0, a1 } = startInnerArc; path.arc(centerX + cx, centerY + cy, r, a0, a1); } } path.closePath(); } isPointInPath(x, y) { const { startAngle, endAngle, innerRadius, outerRadius } = this.clipSector ?? this; return isPointInSector(x - this.centerX, y - this.centerY, { startAngle, endAngle, innerRadius: Math.min(innerRadius, outerRadius), outerRadius: Math.max(innerRadius, outerRadius) }); } }; Sector.className = "Sector"; __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "centerX", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "centerY", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "innerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "outerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "startAngle", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "endAngle", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "clipSector", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "concentricEdgeInset", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "radialEdgeInset", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "startOuterCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "endOuterCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "startInnerCornerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], Sector.prototype, "endInnerCornerRadius", 2); } }); // packages/ag-charts-community/src/chart/themes/defaultColors.ts var DEFAULT_FILLS, DEFAULT_STROKES; var init_defaultColors = __esm({ "packages/ag-charts-community/src/chart/themes/defaultColors.ts"() { "use strict"; DEFAULT_FILLS = { BLUE: "#5090dc", ORANGE: "#ffa03a", GREEN: "#459d55", CYAN: "#34bfe1", YELLOW: "#e1cc00", VIOLET: "#9669cb", GRAY: "#b5b5b5", MAGENTA: "#bd5aa7", BROWN: "#8a6224", RED: "#ef5452" }; DEFAULT_STROKES = { BLUE: "#2b5c95", ORANGE: "#cc6f10", GREEN: "#1e652e", CYAN: "#18859e", YELLOW: "#a69400", VIOLET: "#603c88", GRAY: "#575757", MAGENTA: "#7d2f6d", BROWN: "#4f3508", RED: "#a82529" }; } }); // packages/ag-charts-community/src/chart/series/polar/donutSeriesProperties.ts var DonutTitle, DonutInnerLabel, DonutInnerCircle, DonutSeriesCalloutLabel, DonutSeriesSectorLabel, DonutSeriesCalloutLine, DonutSeriesProperties; var init_donutSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/polar/donutSeriesProperties.ts"() { "use strict"; init_main(); init_dropShadow(); init_properties(); init_validation2(); init_caption(); init_label(); init_defaultColors(); init_seriesProperties(); init_seriesTooltip(); DonutTitle = class extends Caption { constructor() { super(...arguments); this.showInLegend = false; } }; __decorateClass([ Validate(BOOLEAN) ], DonutTitle.prototype, "showInLegend", 2); DonutInnerLabel = class extends Label { constructor() { super(...arguments); this.spacing = 2; } set(properties, _reset) { return super.set(properties); } }; __decorateClass([ Validate(STRING) ], DonutInnerLabel.prototype, "text", 2); __decorateClass([ Validate(NUMBER) ], DonutInnerLabel.prototype, "spacing", 2); DonutInnerCircle = class extends BaseProperties { constructor() { super(...arguments); this.fill = "transparent"; this.fillOpacity = 1; } }; __decorateClass([ Validate(COLOR_STRING) ], DonutInnerCircle.prototype, "fill", 2); __decorateClass([ Validate(RATIO) ], DonutInnerCircle.prototype, "fillOpacity", 2); DonutSeriesCalloutLabel = class extends Label { constructor() { super(...arguments); this.offset = 3; this.minAngle = 0; this.minSpacing = 4; this.maxCollisionOffset = 50; this.avoidCollisions = true; } }; __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesCalloutLabel.prototype, "offset", 2); __decorateClass([ Validate(NUMBER.restrict({ min: 0, max: 360 })) ], DonutSeriesCalloutLabel.prototype, "minAngle", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesCalloutLabel.prototype, "minSpacing", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesCalloutLabel.prototype, "maxCollisionOffset", 2); __decorateClass([ Validate(BOOLEAN) ], DonutSeriesCalloutLabel.prototype, "avoidCollisions", 2); DonutSeriesSectorLabel = class extends Label { constructor() { super(...arguments); this.positionOffset = 0; this.positionRatio = 0.5; } }; __decorateClass([ Validate(NUMBER) ], DonutSeriesSectorLabel.prototype, "positionOffset", 2); __decorateClass([ Validate(RATIO) ], DonutSeriesSectorLabel.prototype, "positionRatio", 2); DonutSeriesCalloutLine = class extends BaseProperties { constructor() { super(...arguments); this.length = 10; this.strokeWidth = 1; } }; __decorateClass([ Validate(COLOR_STRING_ARRAY, { optional: true }) ], DonutSeriesCalloutLine.prototype, "colors", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesCalloutLine.prototype, "length", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesCalloutLine.prototype, "strokeWidth", 2); DonutSeriesProperties = class extends SeriesProperties { constructor() { super(...arguments); this.fills = Object.values(DEFAULT_FILLS); this.strokes = Object.values(DEFAULT_STROKES); this.fillOpacity = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.rotation = 0; this.outerRadiusOffset = 0; this.outerRadiusRatio = 1; this.strokeWidth = 1; this.sectorSpacing = 0; this.hideZeroValueSectorsInLegend = false; this.innerLabels = new PropertiesArray(DonutInnerLabel); this.title = new DonutTitle(); this.innerCircle = new DonutInnerCircle(); this.shadow = new DropShadow(); this.calloutLabel = new DonutSeriesCalloutLabel(); this.sectorLabel = new DonutSeriesSectorLabel(); this.calloutLine = new DonutSeriesCalloutLine(); this.tooltip = new SeriesTooltip(); } isValid() { const superIsValid = super.isValid(); if (this.innerRadiusRatio == null && this.innerRadiusOffset == null) { logger_exports.warnOnce( "Either an [innerRadiusRatio] or an [innerRadiusOffset] must be set to render a donut series." ); return false; } return superIsValid; } }; __decorateClass([ Validate(STRING) ], DonutSeriesProperties.prototype, "angleKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "angleName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "angleFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "radiusKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "radiusName", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], DonutSeriesProperties.prototype, "radiusMin", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], DonutSeriesProperties.prototype, "radiusMax", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "calloutLabelKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "calloutLabelName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "sectorLabelKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "sectorLabelName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], DonutSeriesProperties.prototype, "legendItemKey", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], DonutSeriesProperties.prototype, "fills", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], DonutSeriesProperties.prototype, "strokes", 2); __decorateClass([ Validate(RATIO) ], DonutSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate(RATIO) ], DonutSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], DonutSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], DonutSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate(NUMBER) ], DonutSeriesProperties.prototype, "rotation", 2); __decorateClass([ Validate(NUMBER) ], DonutSeriesProperties.prototype, "outerRadiusOffset", 2); __decorateClass([ Validate(RATIO) ], DonutSeriesProperties.prototype, "outerRadiusRatio", 2); __decorateClass([ Validate(NUMBER, { optional: true }) ], DonutSeriesProperties.prototype, "innerRadiusOffset", 2); __decorateClass([ Validate(RATIO, { optional: true }) ], DonutSeriesProperties.prototype, "innerRadiusRatio", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], DonutSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate(NUMBER) ], DonutSeriesProperties.prototype, "sectorSpacing", 2); __decorateClass([ Validate(BOOLEAN) ], DonutSeriesProperties.prototype, "hideZeroValueSectorsInLegend", 2); __decorateClass([ Validate(OBJECT_ARRAY) ], DonutSeriesProperties.prototype, "innerLabels", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "title", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "innerCircle", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "shadow", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "calloutLabel", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "sectorLabel", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "calloutLine", 2); __decorateClass([ Validate(OBJECT) ], DonutSeriesProperties.prototype, "tooltip", 2); } }); // packages/ag-charts-community/src/chart/series/polar/pieUtil.ts function preparePieSeriesAnimationFunctions(initialLoad, rotationDegrees, scaleFn, oldScaleFn) { const scale2 = [scaleFn.convert(0), scaleFn.convert(1)]; const oldScale = [oldScaleFn.convert(0), oldScaleFn.convert(1)]; const rotation = Math.PI / -2 + toRadians(rotationDegrees); const phase = initialLoad ? "initial" : "update"; const scaleToNewRadius = ({ radius }) => { return { innerRadius: scale2[0], outerRadius: scale2[0] + (scale2[1] - scale2[0]) * radius }; }; const scaleToOldRadius = ({ radius }) => { return { innerRadius: oldScale[0], outerRadius: oldScale[0] + (oldScale[1] - oldScale[0]) * radius }; }; const fromFn = (sect, datum, status, { prevFromProps }) => { let { startAngle, endAngle, innerRadius, outerRadius } = sect; let { fill, stroke: stroke3 } = datum.sectorFormat; if (status === "unknown" || status === "added" && !prevFromProps) { startAngle = rotation; endAngle = rotation; innerRadius = datum.innerRadius; outerRadius = datum.outerRadius; } else if (status === "added" && prevFromProps) { startAngle = prevFromProps.endAngle ?? rotation; endAngle = prevFromProps.endAngle ?? rotation; innerRadius = prevFromProps.innerRadius ?? datum.innerRadius; outerRadius = prevFromProps.outerRadius ?? datum.outerRadius; } if (status === "added" && !initialLoad) { const radii = scaleToOldRadius(datum); innerRadius = radii.innerRadius; outerRadius = radii.outerRadius; } if (status === "updated") { fill = sect.fill ?? fill; stroke3 = (typeof sect.stroke === "string" ? sect.stroke : void 0) ?? stroke3; } return { startAngle, endAngle, innerRadius, outerRadius, fill, stroke: stroke3, phase }; }; const toFn = (_sect, datum, status, { prevLive }) => { let { startAngle, endAngle, innerRadius, outerRadius } = datum; const { stroke: stroke3, fill } = datum.sectorFormat; if (status === "removed" && prevLive) { startAngle = prevLive.datum?.endAngle; endAngle = prevLive.datum?.endAngle; } else if (status === "removed" && !prevLive) { startAngle = rotation; endAngle = rotation; } if (status === "removed") { const radii = scaleToNewRadius(datum); innerRadius = radii.innerRadius; outerRadius = radii.outerRadius; } return { startAngle, endAngle, outerRadius, innerRadius, stroke: stroke3, fill }; }; const innerCircleFromFn = (node, _) => { return { size: node.previousDatum?.radius ?? node.size ?? 0, phase }; }; const innerCircleToFn = (_, datum) => { return { size: datum.radius ?? 0 }; }; return { nodes: { toFn, fromFn }, innerCircle: { fromFn: innerCircleFromFn, toFn: innerCircleToFn } }; } function resetPieSelectionsFn(_node, datum) { return { startAngle: datum.startAngle, endAngle: datum.endAngle, innerRadius: datum.innerRadius, outerRadius: datum.outerRadius, fill: datum.sectorFormat.fill, stroke: datum.sectorFormat.stroke }; } function pickByMatchingAngle(series, point) { const dy2 = point.y - series.centerY; const dx2 = point.x - series.centerX; const angle2 = Math.atan2(dy2, dx2); const sectors = series.getItemNodes(); for (const sector of sectors) { if (sector.datum.missing === true) continue; if (isBetweenAngles(angle2, sector.startAngle, sector.endAngle)) { const radius = Math.sqrt(dx2 * dx2 + dy2 * dy2); let distance2 = 0; if (radius < sector.innerRadius) { distance2 = sector.innerRadius - radius; } else if (radius > sector.outerRadius) { distance2 = radius - sector.outerRadius; } return { datum: sector.datum, distance: distance2 }; } } return void 0; } var init_pieUtil = __esm({ "packages/ag-charts-community/src/chart/series/polar/pieUtil.ts"() { "use strict"; init_angle(); } }); // packages/ag-charts-community/src/chart/series/polar/polarZIndexMap.ts var PolarZIndexMap; var init_polarZIndexMap = __esm({ "packages/ag-charts-community/src/chart/series/polar/polarZIndexMap.ts"() { "use strict"; PolarZIndexMap = /* @__PURE__ */ ((PolarZIndexMap3) => { PolarZIndexMap3[PolarZIndexMap3["BACKGROUND"] = 0] = "BACKGROUND"; PolarZIndexMap3[PolarZIndexMap3["FOREGROUND"] = 1] = "FOREGROUND"; PolarZIndexMap3[PolarZIndexMap3["HIGHLIGHT"] = 2] = "HIGHLIGHT"; PolarZIndexMap3[PolarZIndexMap3["LABEL"] = 3] = "LABEL"; return PolarZIndexMap3; })(PolarZIndexMap || {}); } }); // packages/ag-charts-community/src/chart/series/polar/polarSeries.ts var PolarSeries; var init_polarSeries = __esm({ "packages/ag-charts-community/src/chart/series/polar/polarSeries.ts"() { "use strict"; init_resetMotion(); init_group(); init_selection(); init_path(); init_text(); init_stateMachine(); init_dataModelSeries(); PolarSeries = class extends DataModelSeries { constructor({ useLabelLayer = false, pickModes = [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */], canHaveAxes = false, animationResetFns, ...opts }) { super({ ...opts, useLabelLayer, pickModes, directionKeys: { ["x" /* X */]: ["angleKey"], ["y" /* Y */]: ["radiusKey"] }, directionNames: { ["x" /* X */]: ["angleName"], ["y" /* Y */]: ["radiusName"] }, canHaveAxes }); this.itemGroup = this.contentGroup.appendChild(new Group()); this.nodeData = []; this.itemSelection = Selection.select( this.itemGroup, () => this.nodeFactory(), false ); this.labelSelection = Selection.select( this.labelGroup, () => this.labelFactory(), false ); this.highlightSelection = Selection.select( this.highlightGroup, () => this.nodeFactory() ); this.highlightLabelSelection = Selection.select( this.highlightLabel, () => this.labelFactory() ); /** * The center of the polar series (for example, the center of a pie). * If the polar chart has multiple series, all of them will have their * center set to the same value as a result of the polar chart layout. * The center coordinates are not supposed to be set by the user. */ this.centerX = 0; this.centerY = 0; /** * The maximum radius the series can use. * This value is set automatically as a result of the polar chart layout * and is not supposed to be set by the user. */ this.radius = 0; this.animationResetFns = animationResetFns; this.animationState = new StateMachine( "empty", { empty: { update: { target: "ready", action: (data) => this.animateEmptyUpdateReady(data) }, reset: "empty", skip: "ready" }, ready: { updateData: "waiting", clear: "clearing", highlight: (data) => this.animateReadyHighlight(data), highlightMarkers: (data) => this.animateReadyHighlightMarkers(data), resize: (data) => this.animateReadyResize(data), reset: "empty", skip: "ready" }, waiting: { update: { target: "ready", action: (data) => this.animateWaitingUpdateReady(data) }, reset: "empty", skip: "ready" }, clearing: { update: { target: "empty", action: (data) => this.animateClearingUpdateEmpty(data) }, reset: "empty", skip: "ready" } }, () => this.checkProcessedDataAnimatable() ); } getItemNodes() { return [...this.itemGroup.children()]; } getNodeData() { return this.nodeData; } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [index, 1 /* FOREGROUND */]; this.highlightGroup.zIndex = [index, 2 /* HIGHLIGHT */]; this.labelGroup.zIndex = [index, 3 /* LABEL */]; return true; } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } else if (phase === "ready") { this.animationState.transition("skip"); } } labelFactory() { const text3 = new Text(); text3.pointerEvents = 1 /* None */; return text3; } addChartEventListeners() { this.destroyFns.push( this.ctx.chartEventManager?.addListener("legend-item-click", (event) => this.onLegendItemClick(event)) ); } getInnerRadius() { return 0; } computeLabelsBBox(_options, _seriesRect) { return null; } resetAllAnimation() { const { item, label } = this.animationResetFns ?? {}; this.ctx.animationManager.stopByAnimationGroupId(this.id); if (item) { resetMotion([this.itemSelection, this.highlightSelection], item); } if (label) { resetMotion([this.labelSelection, this.highlightLabelSelection], label); } this.itemSelection.cleanup(); this.labelSelection.cleanup(); this.highlightSelection.cleanup(); this.highlightLabelSelection.cleanup(); } animateEmptyUpdateReady(_data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(); } animateWaitingUpdateReady(_data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(); } animateReadyHighlight(_data) { const { item, label } = this.animationResetFns ?? {}; if (item) { resetMotion([this.highlightSelection], item); } if (label) { resetMotion([this.highlightLabelSelection], label); } } animateReadyHighlightMarkers(_data) { } animateReadyResize(_data) { this.resetAllAnimation(); } animateClearingUpdateEmpty(_data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(); } computeFocusBounds(opts) { const datum = this.getNodeData()?.[opts.datumIndex]; if (datum !== void 0) { return this.itemSelection.select((node) => node instanceof Path && node.datum === datum)[0]; } return void 0; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } }; } }); // packages/ag-charts-community/src/chart/series/polar/donutSeries.ts var DonutSeriesNodeEvent, DonutSeries; var init_donutSeries = __esm({ "packages/ag-charts-community/src/chart/series/polar/donutSeries.ts"() { "use strict"; init_main(); init_fromToMotion(); init_linearScale(); init_bbox(); init_group(); init_selection(); init_line(); init_sector2(); init_text(); init_sector(); init_angle(); init_format_util(); init_json(); init_number(); init_object(); init_dataModel(); init_processors(); init_marker(); init_series(); init_seriesLabelUtil(); init_donutSeriesProperties(); init_pieUtil(); init_polarSeries(); DonutSeriesNodeEvent = class extends SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.angleKey = series.properties.angleKey; this.radiusKey = series.properties.radiusKey; this.calloutLabelKey = series.properties.calloutLabelKey; this.sectorLabelKey = series.properties.sectorLabelKey; } }; DonutSeries = class extends PolarSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */], useLabelLayer: true, animationResetFns: { item: resetPieSelectionsFn, label: resetLabelFn } }); this.properties = new DonutSeriesProperties(); this.phantomNodeData = void 0; this.backgroundGroup = new TranslatableGroup({ name: `${this.id}-background`, zIndex: 0 /* BACKGROUND */ }); this.noVisibleData = false; this.previousRadiusScale = new LinearScale(); this.radiusScale = new LinearScale(); this.phantomGroup = this.backgroundGroup.appendChild(new Group({ name: "phantom" })); this.phantomSelection = Selection.select( this.phantomGroup, () => this.nodeFactory(), false ); this.calloutLabelGroup = this.contentGroup.appendChild(new Group({ name: "pieCalloutLabels" })); this.calloutLabelSelection = new Selection( this.calloutLabelGroup, Group ); // AG-6193 If the sum of all datums is 0, then we'll draw 1 or 2 rings to represent the empty series. this.zerosumRingsGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-zerosumRings` })); this.zerosumOuterRing = this.zerosumRingsGroup.appendChild(new Marker({ shape: "circle" })); this.zerosumInnerRing = this.zerosumRingsGroup.appendChild(new Marker({ shape: "circle" })); this.innerLabelsGroup = this.contentGroup.appendChild(new Group({ name: "innerLabels" })); this.innerCircleGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-innerCircle` })); this.innerLabelsSelection = Selection.select(this.innerLabelsGroup, Text); this.innerCircleSelection = Selection.select( this.innerCircleGroup, () => new Marker({ shape: "circle" }) ); this.surroundingRadius = void 0; this.NodeEvent = DonutSeriesNodeEvent; this.angleScale = new LinearScale(); this.angleScale.domain = [0, 1]; this.angleScale.range = [-Math.PI, Math.PI].map((angle2) => angle2 + Math.PI / 2); this.phantomGroup.opacity = 0.2; } get calloutNodeData() { return this.phantomNodeData ?? this.nodeData; } attachSeries(seriesContentNode, seriesNode, annotationNode) { super.attachSeries(seriesContentNode, seriesNode, annotationNode); seriesContentNode?.appendChild(this.backgroundGroup); } detachSeries(seriesContentNode, seriesNode, annotationNode) { super.detachSeries(seriesContentNode, seriesNode, annotationNode); seriesContentNode?.removeChild(this.backgroundGroup); } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.backgroundGroup.zIndex = [0 /* BACKGROUND */, index]; return true; } nodeFactory() { return new Sector(); } getSeriesDomain(direction) { if (direction === "x" /* X */) { return this.angleScale.domain; } else { return this.radiusScale.domain; } } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { visible, id: seriesId } = this; const { angleKey, angleFilterKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties; const validSector = (_value, _datum, index) => { return visible && this.ctx.legendManager.getItemEnabled({ seriesId, itemId: index }); }; const animationEnabled = !this.ctx.animationManager.isSkipped(); const extraKeyProps = []; const extraProps = []; if (legendItemKey) { extraKeyProps.push(keyProperty(legendItemKey, "band", { id: `legendItemKey` })); } else if (calloutLabelKey) { extraKeyProps.push(keyProperty(calloutLabelKey, "band", { id: `calloutLabelKey` })); } else if (sectorLabelKey) { extraKeyProps.push(keyProperty(sectorLabelKey, "band", { id: `sectorLabelKey` })); } const radiusScaleType = this.radiusScale.type; const angleScaleType = this.angleScale.type; if (radiusKey) { extraProps.push( rangedValueProperty(radiusKey, { id: "radiusValue", min: this.properties.radiusMin ?? 0, max: this.properties.radiusMax }), valueProperty(radiusKey, radiusScaleType, { id: `radiusRaw` }), // Raw value pass-through. normalisePropertyTo("radiusValue", [0, 1], 1, this.properties.radiusMin ?? 0, this.properties.radiusMax) ); } if (calloutLabelKey) { extraProps.push(valueProperty(calloutLabelKey, "band", { id: `calloutLabelValue` })); } if (sectorLabelKey) { extraProps.push(valueProperty(sectorLabelKey, "band", { id: `sectorLabelValue` })); } if (legendItemKey) { extraProps.push(valueProperty(legendItemKey, "band", { id: `legendItemValue` })); } if (angleFilterKey) { extraProps.push( accumulativeValueProperty(angleFilterKey, angleScaleType, { id: `angleFilterValue`, onlyPositive: true, validation: validSector, invalidValue: 0 }), valueProperty(angleFilterKey, angleScaleType, { id: `angleFilterRaw` }), normalisePropertyTo("angleFilterValue", [0, 1], 0, 0) ); } if (animationEnabled && this.processedData && extraKeyProps.length > 0) { extraProps.push(diff(this.id, this.processedData)); } extraProps.push(animationValidation()); await this.requestDataModel(dataController, this.data, { props: [ ...extraKeyProps, accumulativeValueProperty(angleKey, angleScaleType, { id: `angleValue`, onlyPositive: true, validation: validSector, invalidValue: 0 }), valueProperty(angleKey, angleScaleType, { id: `angleRaw` }), // Raw value pass-through. normalisePropertyTo("angleValue", [0, 1], 0, 0), ...extraProps ] }); for (const valueDef of this.processedData?.defs?.values ?? []) { const { id, missing, property } = valueDef; const missCount = getMissCount(this, missing); if (id !== "angleRaw" && missCount > 0) { logger_exports.warnOnce( `no value was found for the key '${String(property)}' on ${missCount} data element${missCount > 1 ? "s" : ""}` ); } } this.animationState.transition("updateData"); } maybeRefreshNodeData() { if (!this.nodeDataRefresh) return; const { nodeData = [], phantomNodeData } = this.createNodeData() ?? {}; this.nodeData = nodeData; this.phantomNodeData = phantomNodeData; this.nodeDataRefresh = false; } getProcessedDataValues(dataModel, processedData) { const angleValues = dataModel.resolveColumnById(this, `angleValue`, processedData); const angleRawValues = dataModel.resolveColumnById(this, `angleRaw`, processedData); const angleFilterValues = this.properties.angleFilterKey != null ? dataModel.resolveColumnById(this, `angleFilterValue`, processedData) : void 0; const angleFilterRawValues = this.properties.angleFilterKey != null ? dataModel.resolveColumnById(this, `angleFilterRaw`, processedData) : void 0; const radiusValues = this.properties.radiusKey ? dataModel.resolveColumnById(this, `radiusValue`, processedData) : void 0; const radiusRawValues = this.properties.radiusKey ? dataModel.resolveColumnById(this, `radiusRaw`, processedData) : void 0; const calloutLabelValues = this.properties.calloutLabelKey ? dataModel.resolveColumnById(this, `calloutLabelValue`, processedData) : void 0; const sectorLabelValues = this.properties.sectorLabelKey ? dataModel.resolveColumnById(this, `sectorLabelValue`, processedData) : void 0; const legendItemValues = this.properties.legendItemKey ? dataModel.resolveColumnById(this, `legendItemValue`, processedData) : void 0; return { angleValues, angleRawValues, angleFilterValues, angleFilterRawValues, radiusValues, radiusRawValues, calloutLabelValues, sectorLabelValues, legendItemValues }; } createNodeData() { const { id: seriesId, processedData, dataModel, angleScale, ctx: { legendManager }, visible } = this; const { rotation, innerRadiusRatio } = this.properties; if (!this.properties.isValid()) { this.zerosumOuterRing.visible = true; this.zerosumInnerRing.visible = true; return { itemId: seriesId, nodeData: [], labelData: [] }; } if (!dataModel || processedData?.type !== "ungrouped") return; const { angleValues, angleRawValues, angleFilterValues, angleFilterRawValues, radiusValues, radiusRawValues, calloutLabelValues, sectorLabelValues, legendItemValues } = this.getProcessedDataValues(dataModel, processedData); const useFilterAngles = angleFilterRawValues?.some((filterRawValue, index) => { return filterRawValue > angleRawValues[index]; }) ?? false; let currentStart = 0; let sum2 = 0; const nodes = []; const phantomNodes = angleFilterRawValues != null ? [] : void 0; const rawData = processedData.dataSources.get(this.id) ?? []; const invalidData = processedData.invalidData?.get(this.id); rawData.forEach((datum, datumIndex) => { if (invalidData?.[datumIndex] === true) return; const currentValue = useFilterAngles ? angleFilterValues[datumIndex] : angleValues[datumIndex]; const crossFilterScale = angleFilterRawValues != null && !useFilterAngles ? Math.sqrt(angleFilterRawValues[datumIndex] / angleRawValues[datumIndex]) : 1; const startAngle = angleScale.convert(currentStart) + toRadians(rotation); currentStart = currentValue; sum2 += currentValue; const endAngle = angleScale.convert(currentStart) + toRadians(rotation); const span = Math.abs(endAngle - startAngle); const midAngle = startAngle + span / 2; const angleValue = angleRawValues[datumIndex]; const radiusRaw = radiusValues?.[datumIndex] ?? 1; const radius = radiusRaw * crossFilterScale; const radiusValue = radiusRawValues?.[datumIndex]; const legendItemValue = legendItemValues?.[datumIndex]; const nodeLabels = this.getLabels( datum, midAngle, span, true, calloutLabelValues?.[datumIndex], sectorLabelValues?.[datumIndex], legendItemValue ); const sectorFormat = this.getSectorFormat(datum, datumIndex, false); const node = { itemId: datumIndex, series: this, datum, datumIndex, angleValue, midAngle, midCos: Math.cos(midAngle), midSin: Math.sin(midAngle), startAngle, endAngle, radius, innerRadius: Math.max(this.radiusScale.convert(0), 0), outerRadius: Math.max(this.radiusScale.convert(radius), 0), sectorFormat, radiusValue, legendItemValue, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }), focusable: true, ...nodeLabels }; nodes.push(node); if (phantomNodes != null) { phantomNodes.push({ ...node, radius: 1, innerRadius: Math.max(this.radiusScale.convert(0), 0), outerRadius: Math.max(this.radiusScale.convert(1), 0), focusable: false }); } }); this.zerosumOuterRing.visible = sum2 === 0; this.zerosumInnerRing.visible = sum2 === 0 && innerRadiusRatio != null && innerRadiusRatio !== 1 && innerRadiusRatio > 0; return { itemId: seriesId, nodeData: nodes, labelData: nodes, phantomNodeData: phantomNodes }; } getLabels(datum, midAngle, span, skipDisabled, calloutLabelValue, sectorLabelValue, legendItemValue) { const { calloutLabel, sectorLabel, legendItemKey } = this.properties; const calloutLabelKey = !skipDisabled || calloutLabel.enabled ? this.properties.calloutLabelKey : void 0; const sectorLabelKey = !skipDisabled || sectorLabel.enabled ? this.properties.sectorLabelKey : void 0; if (!calloutLabelKey && !sectorLabelKey && !legendItemKey) { return {}; } const labelFormatterParams = { datum, angleKey: this.properties.angleKey, angleName: this.properties.angleName, radiusKey: this.properties.radiusKey, radiusName: this.properties.radiusName, calloutLabelKey: this.properties.calloutLabelKey, calloutLabelName: this.properties.calloutLabelName, sectorLabelKey: this.properties.sectorLabelKey, sectorLabelName: this.properties.sectorLabelName, legendItemKey: this.properties.legendItemKey }; const result = {}; if (calloutLabelKey && span >= toRadians(calloutLabel.minAngle)) { result.calloutLabel = { ...this.getTextAlignment(midAngle), text: this.getLabelText(calloutLabel, { ...labelFormatterParams, value: calloutLabelValue }), hidden: false, collisionTextAlign: void 0, collisionOffsetY: 0, box: void 0 }; } if (sectorLabelKey) { result.sectorLabel = { text: this.getLabelText(sectorLabel, { ...labelFormatterParams, value: sectorLabelValue }) }; } if (legendItemKey != null && legendItemValue != null) { result.legendItem = { key: legendItemKey, text: legendItemValue }; } return result; } getTextAlignment(midAngle) { const quadrantTextOpts = [ { textAlign: "center", textBaseline: "bottom" }, { textAlign: "left", textBaseline: "middle" }, { textAlign: "center", textBaseline: "hanging" }, { textAlign: "right", textBaseline: "middle" } ]; const midAngle180 = normalizeAngle180(midAngle); const quadrantStart = -0.75 * Math.PI; const quadrantOffset = midAngle180 - quadrantStart; const quadrant = Math.floor(quadrantOffset / (Math.PI / 2)); const quadrantIndex = mod(quadrant, quadrantTextOpts.length); return quadrantTextOpts[quadrantIndex]; } getSectorFormat(datum, datumIndex, highlighted) { const { angleKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey, fills, strokes, itemStyler } = this.properties; const defaultStroke = strokes[datumIndex % strokes.length]; const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius } = mergeDefaults( highlighted && this.properties.highlightStyle.item, { fill: fills.length > 0 ? fills[datumIndex % fills.length] : void 0, stroke: defaultStroke, strokeWidth: this.getStrokeWidth(this.properties.strokeWidth), strokeOpacity: this.getOpacity() }, this.properties ); let format; if (itemStyler) { format = this.cachedDatumCallback( this.getDatumId(datum, datumIndex) + (highlighted ? "-highlight" : "-hide"), () => itemStyler({ datum, angleKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius, highlighted, seriesId: this.id }) ); } return { fill: format?.fill ?? fill, fillOpacity: format?.fillOpacity ?? fillOpacity, stroke: format?.stroke ?? stroke3, strokeWidth: format?.strokeWidth ?? strokeWidth, strokeOpacity: format?.strokeOpacity ?? strokeOpacity, lineDash: format?.lineDash ?? lineDash, lineDashOffset: format?.lineDashOffset ?? lineDashOffset, cornerRadius: format?.cornerRadius ?? cornerRadius }; } getInnerRadius() { const { radius } = this; const { innerRadiusRatio = 1, innerRadiusOffset = 0 } = this.properties; const innerRadius = radius * innerRadiusRatio + innerRadiusOffset; if (innerRadius === radius || innerRadius < 0) { return 0; } return innerRadius; } getOuterRadius() { const { outerRadiusRatio, outerRadiusOffset } = this.properties; return Math.max(this.radius * outerRadiusRatio + outerRadiusOffset, 0); } updateRadiusScale(resize) { const newRange = [this.getInnerRadius(), this.getOuterRadius()]; this.radiusScale.range = newRange; if (resize) { this.previousRadiusScale.range = newRange; } const setRadii = (d) => ({ ...d, innerRadius: Math.max(this.radiusScale.convert(0), 0), outerRadius: Math.max(this.radiusScale.convert(d.radius), 0) }); this.nodeData = this.nodeData.map(setRadii); this.phantomNodeData = this.phantomNodeData?.map(setRadii); } getTitleTranslationY() { const outerRadius = Math.max(0, this.radiusScale.range[1]); if (outerRadius === 0) { return NaN; } const spacing = this.properties.title?.spacing ?? 0; const titleOffset = 2 + spacing; const dy2 = Math.max(0, -outerRadius); return -outerRadius - titleOffset - dy2; } update({ seriesRect }) { const { title } = this.properties; const newNodeDataDependencies = { seriesRectWidth: seriesRect?.width, seriesRectHeight: seriesRect?.height }; const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null; if (resize) { this._nodeDataDependencies = newNodeDataDependencies; } this.maybeRefreshNodeData(); this.updateTitleNodes(); this.updateRadiusScale(resize); this.contentGroup.translationX = this.centerX; this.contentGroup.translationY = this.centerY; this.highlightGroup.translationX = this.centerX; this.highlightGroup.translationY = this.centerY; this.backgroundGroup.translationX = this.centerX; this.backgroundGroup.translationY = this.centerY; if (this.labelGroup) { this.labelGroup.translationX = this.centerX; this.labelGroup.translationY = this.centerY; } if (title) { const dy2 = this.getTitleTranslationY(); title.node.y = isFinite(dy2) ? dy2 : 0; const titleBox = title.node.getBBox(); title.node.visible = title.enabled && isFinite(dy2) && !this.bboxIntersectsSurroundingSeries(titleBox); } for (const circle of [this.zerosumInnerRing, this.zerosumOuterRing]) { circle.fillOpacity = 0; circle.stroke = this.properties.calloutLabel.color; circle.strokeWidth = 1; circle.strokeOpacity = 1; } this.updateNodeMidPoint(); this.updateSelections(); this.updateNodes(seriesRect); } updateTitleNodes() { const { oldTitle } = this; const { title } = this.properties; if (oldTitle !== title) { if (oldTitle) { this.labelGroup?.removeChild(oldTitle.node); } if (title) { title.node.textBaseline = "bottom"; this.labelGroup?.appendChild(title.node); } this.oldTitle = title; } } updateNodeMidPoint() { const setMidPoint = (d) => { const radius = d.innerRadius + (d.outerRadius - d.innerRadius) / 2; d.midPoint = { x: d.midCos * Math.max(0, radius), y: d.midSin * Math.max(0, radius) }; }; this.nodeData.forEach(setMidPoint); this.phantomNodeData?.forEach(setMidPoint); } updateSelections() { this.updateGroupSelection(); this.updateInnerCircleSelection(); } updateGroupSelection() { const { itemSelection, highlightSelection, phantomSelection, highlightLabelSelection, calloutLabelSelection, labelSelection, innerLabelsSelection } = this; const highlightedNodeData = this.nodeData.map((datum) => ({ ...datum, // Allow mutable sectorFormat, so formatted sector styles can be updated and varied // between normal and highlighted cases. sectorFormat: { ...datum.sectorFormat } })); const update = (selection, nodeData) => { selection.update(nodeData, void 0, (datum) => this.getDatumId(datum.datum, datum.datumIndex)); if (this.ctx.animationManager.isSkipped()) { selection.cleanup(); } }; update(itemSelection, this.nodeData); update(highlightSelection, highlightedNodeData); update(phantomSelection, this.phantomNodeData ?? []); calloutLabelSelection.update(this.calloutNodeData, (group) => { const line = new Line(); line.tag = 0 /* Callout */; line.pointerEvents = 1 /* None */; group.appendChild(line); const text3 = new Text(); text3.tag = 1 /* Label */; text3.pointerEvents = 1 /* None */; group.appendChild(text3); }); labelSelection.update(this.nodeData); highlightLabelSelection.update(highlightedNodeData); innerLabelsSelection.update(this.properties.innerLabels, (node) => { node.pointerEvents = 1 /* None */; }); } updateInnerCircleSelection() { const { innerCircle } = this.properties; let radius = 0; const innerRadius = this.getInnerRadius(); if (innerRadius > 0) { const circleRadius = Math.min(innerRadius, this.getOuterRadius()); const antiAliasingPadding = 1; radius = Math.ceil(circleRadius * 2 + antiAliasingPadding); } const datums = innerCircle ? [{ radius }] : []; this.innerCircleSelection.update(datums); } updateNodes(seriesRect) { const highlightedDatum = this.ctx.highlightManager.getActiveHighlight(); const { visible } = this; this.backgroundGroup.visible = visible; this.contentGroup.visible = visible; this.highlightGroup.visible = visible && highlightedDatum?.series === this; this.highlightLabel.visible = visible && highlightedDatum?.series === this; this.labelGroup.visible = visible; this.contentGroup.opacity = this.getOpacity(); this.innerCircleSelection.each((node, { radius }) => { node.setProperties({ fill: this.properties.innerCircle?.fill, opacity: this.properties.innerCircle?.fillOpacity, size: radius }); }); const animationDisabled = this.ctx.animationManager.isSkipped(); const updateSectorFn = (sector, datum, _index, isDatumHighlighted) => { const format = this.getSectorFormat(datum.datum, datum.itemId, isDatumHighlighted); datum.sectorFormat.fill = format.fill; datum.sectorFormat.stroke = format.stroke; if (animationDisabled) { sector.startAngle = datum.startAngle; sector.endAngle = datum.endAngle; sector.innerRadius = datum.innerRadius; sector.outerRadius = datum.outerRadius; } if (isDatumHighlighted || animationDisabled) { sector.fill = format.fill; sector.stroke = format.stroke; } sector.strokeWidth = format.strokeWidth; sector.fillOpacity = format.fillOpacity; sector.strokeOpacity = format.strokeOpacity; sector.lineDash = format.lineDash; sector.lineDashOffset = format.lineDashOffset; sector.cornerRadius = format.cornerRadius; sector.fillShadow = this.properties.shadow; const inset = Math.max( (this.properties.sectorSpacing + (format.stroke != null ? format.strokeWidth : 0)) / 2, 0 ); sector.inset = inset; sector.lineJoin = this.properties.sectorSpacing >= 0 || inset > 0 ? "miter" : "round"; }; this.itemSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false)); this.highlightSelection.each((node, datum, index) => { updateSectorFn(node, datum, index, true); node.visible = datum.itemId === highlightedDatum?.itemId; }); this.phantomSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false)); this.updateCalloutLineNodes(); this.updateCalloutLabelNodes(seriesRect); this.updateSectorLabelNodes(); this.updateInnerLabelNodes(); this.updateZerosumRings(); this.animationState.transition("update"); } updateCalloutLineNodes() { const { calloutLine } = this.properties; const calloutLength = calloutLine.length; const calloutStrokeWidth = calloutLine.strokeWidth; const calloutColors = calloutLine.colors ?? this.properties.strokes; const { offset: offset4 } = this.properties.calloutLabel; this.calloutLabelSelection.selectByTag(0 /* Callout */).forEach((line, index) => { const datum = line.datum; const { calloutLabel: label, outerRadius } = datum; if (label?.text && !label.hidden && outerRadius !== 0) { line.visible = true; line.strokeWidth = calloutStrokeWidth; line.stroke = calloutColors[index % calloutColors.length]; line.fill = void 0; const x1 = datum.midCos * outerRadius; const y1 = datum.midSin * outerRadius; let x2 = datum.midCos * (outerRadius + calloutLength); let y2 = datum.midSin * (outerRadius + calloutLength); const isMoved = label.collisionTextAlign ?? label.collisionOffsetY !== 0; if (isMoved && label.box != null) { const box = label.box; let cx = x2; let cy = y2; if (x2 < box.x) { cx = box.x; } else if (x2 > box.x + box.width) { cx = box.x + box.width; } if (y2 < box.y) { cy = box.y; } else if (y2 > box.y + box.height) { cy = box.y + box.height; } const dx2 = cx - x2; const dy2 = cy - y2; const length2 = Math.sqrt(Math.pow(dx2, 2) + Math.pow(dy2, 2)); const paddedLength = length2 - offset4; if (paddedLength > 0) { x2 = x2 + dx2 * paddedLength / length2; y2 = y2 + dy2 * paddedLength / length2; } } line.x1 = x1; line.y1 = y1; line.x2 = x2; line.y2 = y2; } else { line.visible = false; } }); } getLabelOverflow(text3, box, seriesRect) { const seriesLeft = -this.centerX; const seriesRight = seriesLeft + seriesRect.width; const seriesTop = -this.centerY; const seriesBottom = seriesTop + seriesRect.height; const errPx = 1; let visibleTextPart = 1; if (box.x + errPx < seriesLeft) { visibleTextPart = (box.x + box.width - seriesLeft) / box.width; } else if (box.x + box.width - errPx > seriesRight) { visibleTextPart = (seriesRight - box.x) / box.width; } const hasVerticalOverflow = box.y + errPx < seriesTop || box.y + box.height - errPx > seriesBottom; const textLength = visibleTextPart === 1 ? text3.length : Math.floor(text3.length * visibleTextPart) - 1; const hasSurroundingSeriesOverflow = this.bboxIntersectsSurroundingSeries(box); return { textLength, hasVerticalOverflow, hasSurroundingSeriesOverflow }; } bboxIntersectsSurroundingSeries(box) { const { surroundingRadius } = this; if (surroundingRadius == null) { return false; } const corners = [ { x: box.x, y: box.y }, { x: box.x + box.width, y: box.y }, { x: box.x + box.width, y: box.y + box.height }, { x: box.x, y: box.y + box.height } ]; const sur2 = surroundingRadius ** 2; return corners.some((corner) => corner.x ** 2 + corner.y ** 2 > sur2); } computeCalloutLabelCollisionOffsets() { const { radiusScale } = this; const { calloutLabel, calloutLine } = this.properties; const { offset: offset4, minSpacing } = calloutLabel; const innerRadius = radiusScale.convert(0); const shouldSkip = (datum) => { const label = datum.calloutLabel; return !label || datum.outerRadius === 0; }; const fullData = this.calloutNodeData; const data = fullData.filter((t) => !shouldSkip(t)); data.forEach((datum) => { const label = datum.calloutLabel; if (label == null) return; label.hidden = false; label.collisionTextAlign = void 0; label.collisionOffsetY = 0; }); if (data.length <= 1) { return; } const leftLabels = data.filter((d) => d.midCos < 0).sort((a, b) => a.midSin - b.midSin); const rightLabels = data.filter((d) => d.midCos >= 0).sort((a, b) => a.midSin - b.midSin); const topLabels = data.filter((d) => d.midSin < 0 && d.calloutLabel?.textAlign === "center").sort((a, b) => a.midCos - b.midCos); const bottomLabels = data.filter((d) => d.midSin >= 0 && d.calloutLabel?.textAlign === "center").sort((a, b) => a.midCos - b.midCos); const getTextBBox = (datum) => { const label = datum.calloutLabel; if (label == null) return BBox.zero.clone(); const labelRadius = datum.outerRadius + calloutLine.length + offset4; const x = datum.midCos * labelRadius; const y = datum.midSin * labelRadius + label.collisionOffsetY; const textAlign = label.collisionTextAlign ?? label.textAlign; const textBaseline = label.textBaseline; return Text.computeBBox(label.text, x, y, { font: this.properties.calloutLabel, textAlign, textBaseline }); }; const avoidNeighbourYCollision = (label, next, direction) => { const box = getTextBBox(label).grow(minSpacing / 2); const other = getTextBBox(next).grow(minSpacing / 2); const collidesOrBehind = box.x < other.x + other.width && box.x + box.width > other.x && (direction === "to-top" ? box.y < other.y + other.height : box.y + box.height > other.y); if (collidesOrBehind) { next.calloutLabel.collisionOffsetY = direction === "to-top" ? box.y - other.y - other.height : box.y + box.height - other.y; } }; const avoidYCollisions = (labels) => { const midLabel = labels.slice().sort((a, b) => Math.abs(a.midSin) - Math.abs(b.midSin))[0]; const midIndex = labels.indexOf(midLabel); for (let i = midIndex - 1; i >= 0; i--) { const prev = labels[i + 1]; const next = labels[i]; avoidNeighbourYCollision(prev, next, "to-top"); } for (let i = midIndex + 1; i < labels.length; i++) { const prev = labels[i - 1]; const next = labels[i]; avoidNeighbourYCollision(prev, next, "to-bottom"); } }; const avoidXCollisions = (labels) => { const labelsCollideLabelsByY = data.some((datum) => datum.calloutLabel.collisionOffsetY !== 0); const boxes = labels.map((label) => getTextBBox(label)); const paddedBoxes = boxes.map((box) => box.clone().grow(minSpacing / 2)); let labelsCollideLabelsByX = false; for (let i = 0; i < paddedBoxes.length && !labelsCollideLabelsByX; i++) { const box = paddedBoxes[i]; for (let j = i + 1; j < labels.length; j++) { const other = paddedBoxes[j]; if (box.collidesBBox(other)) { labelsCollideLabelsByX = true; break; } } } const sectors = fullData.map((datum) => { const { startAngle, endAngle, outerRadius } = datum; return { startAngle, endAngle, innerRadius, outerRadius }; }); const labelsCollideSectors = boxes.some((box) => { return sectors.some((sector) => boxCollidesSector(box, sector)); }); if (!labelsCollideLabelsByX && !labelsCollideLabelsByY && !labelsCollideSectors) { return; } labels.filter((d) => d.calloutLabel.textAlign === "center").forEach((d) => { const label = d.calloutLabel; if (d.midCos < 0) { label.collisionTextAlign = "right"; } else if (d.midCos > 0) { label.collisionTextAlign = "left"; } else { label.collisionTextAlign = "center"; } }); }; avoidYCollisions(leftLabels); avoidYCollisions(rightLabels); avoidXCollisions(topLabels); avoidXCollisions(bottomLabels); } updateCalloutLabelNodes(seriesRect) { const { radiusScale } = this; const { calloutLabel, calloutLine } = this.properties; const calloutLength = calloutLine.length; const { offset: offset4, color } = calloutLabel; const tempTextNode = new Text(); this.calloutLabelSelection.selectByTag(1 /* Label */).forEach((text3) => { const { datum } = text3; const label = datum.calloutLabel; const radius = radiusScale.convert(datum.radius); const outerRadius = Math.max(0, radius); if (!label?.text || outerRadius === 0 || label.hidden) { text3.visible = false; return; } const labelRadius = outerRadius + calloutLength + offset4; const x = datum.midCos * labelRadius; const y = datum.midSin * labelRadius + label.collisionOffsetY; const align2 = { textAlign: label.collisionTextAlign ?? label.textAlign, textBaseline: label.textBaseline }; tempTextNode.text = label.text; tempTextNode.x = x; tempTextNode.y = y; tempTextNode.setFont(this.properties.calloutLabel); tempTextNode.setAlign(align2); const box = tempTextNode.getBBox(); let displayText = label.text; let visible = true; if (calloutLabel.avoidCollisions) { const { textLength, hasVerticalOverflow } = this.getLabelOverflow(label.text, box, seriesRect); displayText = label.text.length === textLength ? label.text : `${label.text.substring(0, textLength)}\u2026`; visible = !hasVerticalOverflow; } text3.text = displayText; text3.x = x; text3.y = y; text3.setFont(this.properties.calloutLabel); text3.setAlign(align2); text3.fill = color; text3.visible = visible; }); } computeLabelsBBox(options, seriesRect) { const { calloutLabel, calloutLine } = this.properties; const calloutLength = calloutLine.length; const { offset: offset4, maxCollisionOffset, minSpacing } = calloutLabel; if (!calloutLabel.avoidCollisions) { return null; } this.maybeRefreshNodeData(); this.updateRadiusScale(false); this.computeCalloutLabelCollisionOffsets(); const textBoxes = []; const text3 = new Text(); let titleBox; const { title } = this.properties; if (title?.text && title.enabled) { const dy2 = this.getTitleTranslationY(); if (isFinite(dy2)) { text3.text = title.text; text3.x = 0; text3.y = dy2; text3.setFont(title); text3.setAlign({ textBaseline: "bottom", textAlign: "center" }); titleBox = text3.getBBox(); textBoxes.push(titleBox); } } this.calloutNodeData.forEach((datum) => { const label = datum.calloutLabel; if (!label || datum.outerRadius === 0) { return null; } const labelRadius = datum.outerRadius + calloutLength + offset4; const x = datum.midCos * labelRadius; const y = datum.midSin * labelRadius + label.collisionOffsetY; text3.text = label.text; text3.x = x; text3.y = y; text3.setFont(this.properties.calloutLabel); text3.setAlign({ textAlign: label.collisionTextAlign ?? label.textAlign, textBaseline: label.textBaseline }); const box = text3.getBBox(); label.box = box; if (Math.abs(label.collisionOffsetY) > maxCollisionOffset) { label.hidden = true; return; } if (titleBox) { const seriesTop = -this.centerY; const titleCleanArea = new BBox( titleBox.x - minSpacing, seriesTop, titleBox.width + 2 * minSpacing, titleBox.y + titleBox.height + minSpacing - seriesTop ); if (box.collidesBBox(titleCleanArea)) { label.hidden = true; return; } } if (options.hideWhenNecessary) { const { textLength, hasVerticalOverflow, hasSurroundingSeriesOverflow } = this.getLabelOverflow( label.text, box, seriesRect ); const isTooShort = label.text.length > 2 && textLength < 2; if (hasVerticalOverflow || isTooShort || hasSurroundingSeriesOverflow) { label.hidden = true; return; } } label.hidden = false; textBoxes.push(box); }); if (textBoxes.length === 0) { return null; } return BBox.merge(textBoxes); } updateSectorLabelNodes() { const { radiusScale } = this; const innerRadius = radiusScale.convert(0); const { fontSize, fontStyle, fontWeight, fontFamily, positionOffset, positionRatio, color } = this.properties.sectorLabel; const updateSectorLabel = (text3, datum) => { const { sectorLabel, outerRadius } = datum; let isTextVisible = false; if (sectorLabel && outerRadius !== 0) { const labelRadius = innerRadius * (1 - positionRatio) + outerRadius * positionRatio + positionOffset; text3.fill = color; text3.fontStyle = fontStyle; text3.fontWeight = fontWeight; text3.fontSize = fontSize; text3.fontFamily = fontFamily; text3.text = sectorLabel.text; text3.x = datum.midCos * labelRadius; text3.y = datum.midSin * labelRadius; text3.textAlign = "center"; text3.textBaseline = "middle"; const bbox = text3.getBBox(); const corners = [ [bbox.x, bbox.y], [bbox.x + bbox.width, bbox.y], [bbox.x + bbox.width, bbox.y + bbox.height], [bbox.x, bbox.y + bbox.height] ]; const { startAngle, endAngle } = datum; const sectorBounds = { startAngle, endAngle, innerRadius, outerRadius }; if (corners.every(([x, y]) => isPointInSector(x, y, sectorBounds))) { isTextVisible = true; } } text3.visible = isTextVisible; }; this.labelSelection.each(updateSectorLabel); this.highlightLabelSelection.each(updateSectorLabel); } updateInnerLabelNodes() { const textBBoxes = []; const margins = []; this.innerLabelsSelection.each((text3, datum) => { const { fontStyle, fontWeight, fontSize, fontFamily, color } = datum; text3.fontStyle = fontStyle; text3.fontWeight = fontWeight; text3.fontSize = fontSize; text3.fontFamily = fontFamily; text3.text = datum.text; text3.x = 0; text3.y = 0; text3.fill = color; text3.textAlign = "center"; text3.textBaseline = "alphabetic"; textBBoxes.push(text3.getBBox()); margins.push(datum.spacing); }); const getMarginTop = (index) => index === 0 ? 0 : margins[index]; const getMarginBottom = (index) => index === margins.length - 1 ? 0 : margins[index]; const totalHeight = textBBoxes.reduce((sum2, bbox, i) => { return sum2 + bbox.height + getMarginTop(i) + getMarginBottom(i); }, 0); const totalWidth = Math.max(...textBBoxes.map((bbox) => bbox.width)); const innerRadius = this.getInnerRadius(); const labelRadius = Math.sqrt(Math.pow(totalWidth / 2, 2) + Math.pow(totalHeight / 2, 2)); const labelsVisible = labelRadius <= (innerRadius > 0 ? innerRadius : this.getOuterRadius()); const textBottoms = []; for (let i = 0, prev = -totalHeight / 2; i < textBBoxes.length; i++) { const bbox = textBBoxes[i]; const bottom = bbox.height + prev + getMarginTop(i); textBottoms.push(bottom); prev = bottom + getMarginBottom(i); } this.innerLabelsSelection.each((text3, _datum, index) => { text3.y = textBottoms[index]; text3.visible = labelsVisible; }); } updateZerosumRings() { this.zerosumOuterRing.size = this.getOuterRadius() * 2; this.zerosumInnerRing.size = this.getInnerRadius() * 2; } pickNodeClosestDatum(point) { return pickByMatchingAngle(this, point); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { legendItemKey, calloutLabelKey, calloutLabelName, sectorLabelKey, sectorLabelName, angleKey, angleName, radiusKey, radiusName, tooltip } = properties; const title = this.properties.title.text; if (!dataModel || !processedData) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const { angleRawValues, legendItemValues, calloutLabelValues, sectorLabelValues } = this.getProcessedDataValues( dataModel, processedData ); const angleRawValue = angleRawValues[datumIndex]; const label = legendItemValues?.[datumIndex] ?? (calloutLabelKey === angleKey ? void 0 : calloutLabelValues?.[datumIndex]) ?? (sectorLabelKey === angleKey ? void 0 : sectorLabelValues?.[datumIndex]) ?? angleName; return tooltip.formatTooltip( { title, symbol: this.legendItemSymbol(datumIndex), data: [ { label, fallbackLabel: angleKey, value: formatValue(angleRawValue, 3) } ] }, { seriesId, datum, title: angleName, legendItemKey, calloutLabelKey, calloutLabelName, sectorLabelKey, sectorLabelName, angleKey, angleName, radiusKey, radiusName, ...this.getSectorFormat(datum, datumIndex, false) } ); } legendItemSymbol(datumIndex) { const datum = this.processedData?.dataSources.get(this.id)?.[datumIndex]; const sectorFormat = this.getSectorFormat(datum, datumIndex, false); return { marker: { fill: sectorFormat.fill, stroke: sectorFormat.stroke, fillOpacity: this.properties.fillOpacity, strokeOpacity: this.properties.strokeOpacity, strokeWidth: this.properties.strokeWidth, lineDash: this.properties.lineDash, lineDashOffset: this.properties.lineDashOffset } }; } getLegendData(legendType) { const { visible, processedData, dataModel, id: seriesId, ctx: { legendManager } } = this; if (!dataModel || !processedData || !this.properties.isValid() || legendType !== "category") { return []; } const { angleKey, calloutLabelKey, sectorLabelKey, legendItemKey, showInLegend } = this.properties; if (!legendItemKey && (!calloutLabelKey || calloutLabelKey === angleKey) && (!sectorLabelKey || sectorLabelKey === angleKey)) return []; const { angleRawValues, calloutLabelValues, sectorLabelValues, legendItemValues } = this.getProcessedDataValues( dataModel, processedData ); const titleText = this.properties.title?.showInLegend && this.properties.title.text; const legendData = []; const hideZeros = this.properties.hideZeroValueSectorsInLegend; const rawData = processedData.dataSources.get(this.id); const invalidData = processedData.invalidData?.get(this.id); for (let datumIndex = 0; datumIndex < processedData.input.count; datumIndex++) { const datum = rawData?.[datumIndex]; const angleRawValue = angleRawValues[datumIndex]; if (invalidData?.[datumIndex] === true || hideZeros && angleRawValue === 0) { continue; } const labelParts = []; if (titleText) { labelParts.push(titleText); } const labels = this.getLabels( datum, 2 * Math.PI, 2 * Math.PI, false, calloutLabelValues?.[datumIndex], sectorLabelValues?.[datumIndex], legendItemValues?.[datumIndex] ); if (legendItemKey && labels.legendItem !== void 0) { labelParts.push(labels.legendItem.text); } else if (calloutLabelKey && calloutLabelKey !== angleKey && labels.calloutLabel?.text !== void 0) { labelParts.push(labels.calloutLabel?.text); } else if (sectorLabelKey && sectorLabelKey !== angleKey && labels.sectorLabel?.text !== void 0) { labelParts.push(labels.sectorLabel?.text); } if (labelParts.length === 0) continue; legendData.push({ legendType: "category", id: seriesId, datum, itemId: datumIndex, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }), label: { text: labelParts.join(" - ") }, symbol: this.legendItemSymbol(datumIndex), legendItemName: legendItemKey != null ? datum[legendItemKey] : void 0, hideInLegend: !showInLegend }); } return legendData; } // Used for grid setLegendState(enabledItems) { const { id: seriesId, ctx: { legendManager, updateService } } = this; enabledItems.forEach((enabled, itemId) => legendManager.toggleItem({ enabled, seriesId, itemId })); legendManager.update(); updateService.update(4 /* SERIES_UPDATE */); } animateEmptyUpdateReady(_data) { const { animationManager } = this.ctx; const fns = preparePieSeriesAnimationFunctions( true, this.properties.rotation, this.radiusScale, this.previousRadiusScale ); fromToMotion( this.id, "nodes", animationManager, [this.itemSelection, this.highlightSelection, this.phantomSelection], fns.nodes, (_, datum) => this.getDatumId(datum.datum, datum.datumIndex) ); fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle); seriesLabelFadeInAnimation(this, "callout", animationManager, this.calloutLabelSelection); seriesLabelFadeInAnimation(this, "sector", animationManager, this.labelSelection); seriesLabelFadeInAnimation(this, "highlight", animationManager, this.highlightLabelSelection); seriesLabelFadeInAnimation(this, "inner", animationManager, this.innerLabelsSelection); this.previousRadiusScale.range = this.radiusScale.range; } animateWaitingUpdateReady() { const { itemSelection, highlightSelection, phantomSelection, processedData, radiusScale, previousRadiusScale } = this; const { animationManager } = this.ctx; const dataDiff = processedData?.reduced?.diff?.[this.id]; this.ctx.animationManager.stopByAnimationGroupId(this.id); const supportedDiff = (dataDiff?.moved.size ?? 0) === 0; const hasKeys = (processedData?.defs.keys.length ?? 0) > 0; const hasUniqueKeys = processedData?.reduced?.animationValidation?.uniqueKeys ?? true; if (!supportedDiff || !hasKeys || !hasUniqueKeys) { this.ctx.animationManager.skipCurrentBatch(); } const noVisibleData = !this.nodeData.some((n) => n.enabled); const fns = preparePieSeriesAnimationFunctions( false, this.properties.rotation, radiusScale, previousRadiusScale ); fromToMotion( this.id, "nodes", animationManager, [itemSelection, highlightSelection, phantomSelection], fns.nodes, (_, datum) => this.getDatumId(datum.datum, datum.datumIndex), dataDiff ); fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle); seriesLabelFadeInAnimation(this, "callout", this.ctx.animationManager, this.calloutLabelSelection); seriesLabelFadeInAnimation(this, "sector", this.ctx.animationManager, this.labelSelection); seriesLabelFadeInAnimation(this, "highlight", this.ctx.animationManager, this.highlightLabelSelection); if (this.noVisibleData !== noVisibleData) { this.noVisibleData = noVisibleData; seriesLabelFadeInAnimation(this, "inner", this.ctx.animationManager, this.innerLabelsSelection); } this.previousRadiusScale.range = this.radiusScale.range; } animateClearingUpdateEmpty() { const { itemSelection, highlightSelection, phantomSelection, radiusScale, previousRadiusScale } = this; const { animationManager } = this.ctx; const fns = preparePieSeriesAnimationFunctions( false, this.properties.rotation, radiusScale, previousRadiusScale ); fromToMotion( this.id, "nodes", animationManager, [itemSelection, highlightSelection, phantomSelection], fns.nodes, (_, datum) => this.getDatumId(datum.datum, datum.datumIndex) ); fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle); seriesLabelFadeOutAnimation(this, "callout", this.ctx.animationManager, this.calloutLabelSelection); seriesLabelFadeOutAnimation(this, "sector", this.ctx.animationManager, this.labelSelection); seriesLabelFadeOutAnimation(this, "highlight", this.ctx.animationManager, this.highlightLabelSelection); seriesLabelFadeOutAnimation(this, "inner", this.ctx.animationManager, this.innerLabelsSelection); this.previousRadiusScale.range = this.radiusScale.range; } getDatumId(datum, datumIndex) { const { calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties; if (!this.processedData?.reduced?.animationValidation?.uniqueKeys) { return `${datumIndex}`; } if (legendItemKey) { return createDatumId(datum[legendItemKey]); } else if (calloutLabelKey) { return createDatumId(datum[calloutLabelKey]); } else if (sectorLabelKey) { return createDatumId(datum[sectorLabelKey]); } return `${datumIndex}`; } }; DonutSeries.className = "DonutSeries"; DonutSeries.type = "donut"; } }); // packages/ag-charts-community/src/chart/series/polar/donutTheme.ts var donutTheme; var init_donutTheme = __esm({ "packages/ag-charts-community/src/chart/series/polar/donutTheme.ts"() { "use strict"; init_symbols(); donutTheme = { series: { title: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [1.1666666666666667 /* LARGE */] }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "subtleTextColor" }, spacing: 5 }, calloutLabel: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, offset: 3, minAngle: 1e-3 }, sectorLabel: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "backgroundColor" }, positionOffset: 0, positionRatio: 0.5 }, calloutLine: { length: 10, strokeWidth: 2 }, fillOpacity: 1, strokeOpacity: 1, strokeWidth: 0, lineDash: [0], lineDashOffset: 0, rotation: 0, sectorSpacing: 1, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR, xOffset: 3, yOffset: 3, blur: 5 }, innerLabels: { fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, spacing: 2 } }, legend: { enabled: true } }; } }); // packages/ag-charts-community/src/chart/series/polar/pieTheme.ts var pieTheme, piePaletteFactory; var init_pieTheme = __esm({ "packages/ag-charts-community/src/chart/series/polar/pieTheme.ts"() { "use strict"; init_symbols(); pieTheme = { series: { title: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [1.1666666666666667 /* LARGE */] }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "subtleTextColor" }, spacing: 5 }, calloutLabel: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, offset: 3, minAngle: 1e-3 }, sectorLabel: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "backgroundColor" }, positionOffset: 0, positionRatio: 0.5 }, calloutLine: { length: 10, strokeWidth: 2 }, fillOpacity: 1, strokeOpacity: 1, strokeWidth: 0, lineDash: [0], lineDashOffset: 0, rotation: 0, sectorSpacing: 1, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR, xOffset: 3, yOffset: 3, blur: 5 } }, legend: { enabled: true } }; piePaletteFactory = ({ takeColors, colorsCount }) => { const { fills, strokes } = takeColors(colorsCount); return { fills, strokes, calloutLine: { colors: strokes } }; }; } }); // packages/ag-charts-community/src/chart/series/polar/donutSeriesModule.ts var DonutSeriesModule; var init_donutSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/polar/donutSeriesModule.ts"() { "use strict"; init_donutSeries(); init_donutTheme(); init_pieTheme(); DonutSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["polar"], identifier: "donut", moduleFactory: (ctx) => new DonutSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: donutTheme, paletteFactory: piePaletteFactory }; } }); // packages/ag-charts-community/src/chart/series/polar/pieSeriesProperties.ts var PieTitle, PieSeriesCalloutLabel, PieSeriesSectorLabel, PieSeriesCalloutLine, PieSeriesProperties; var init_pieSeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/polar/pieSeriesProperties.ts"() { "use strict"; init_dropShadow(); init_properties(); init_validation2(); init_caption(); init_label(); init_defaultColors(); init_seriesProperties(); init_seriesTooltip(); PieTitle = class extends Caption { constructor() { super(...arguments); this.showInLegend = false; } }; __decorateClass([ Validate(BOOLEAN) ], PieTitle.prototype, "showInLegend", 2); PieSeriesCalloutLabel = class extends Label { constructor() { super(...arguments); this.offset = 3; this.minAngle = 0; this.minSpacing = 4; this.maxCollisionOffset = 50; this.avoidCollisions = true; } }; __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesCalloutLabel.prototype, "offset", 2); __decorateClass([ Validate(NUMBER.restrict({ min: 0, max: 360 })) ], PieSeriesCalloutLabel.prototype, "minAngle", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesCalloutLabel.prototype, "minSpacing", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesCalloutLabel.prototype, "maxCollisionOffset", 2); __decorateClass([ Validate(BOOLEAN) ], PieSeriesCalloutLabel.prototype, "avoidCollisions", 2); PieSeriesSectorLabel = class extends Label { constructor() { super(...arguments); this.positionOffset = 0; this.positionRatio = 0.5; } }; __decorateClass([ Validate(NUMBER) ], PieSeriesSectorLabel.prototype, "positionOffset", 2); __decorateClass([ Validate(RATIO) ], PieSeriesSectorLabel.prototype, "positionRatio", 2); PieSeriesCalloutLine = class extends BaseProperties { constructor() { super(...arguments); this.length = 10; this.strokeWidth = 1; } }; __decorateClass([ Validate(COLOR_STRING_ARRAY, { optional: true }) ], PieSeriesCalloutLine.prototype, "colors", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesCalloutLine.prototype, "length", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesCalloutLine.prototype, "strokeWidth", 2); PieSeriesProperties = class extends SeriesProperties { constructor() { super(...arguments); this.fills = Object.values(DEFAULT_FILLS); this.strokes = Object.values(DEFAULT_STROKES); this.fillOpacity = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.rotation = 0; this.outerRadiusOffset = 0; this.outerRadiusRatio = 1; this.strokeWidth = 1; this.sectorSpacing = 0; this.hideZeroValueSectorsInLegend = false; this.title = new PieTitle(); this.shadow = new DropShadow(); this.calloutLabel = new PieSeriesCalloutLabel(); this.sectorLabel = new PieSeriesSectorLabel(); this.calloutLine = new PieSeriesCalloutLine(); this.tooltip = new SeriesTooltip(); } }; __decorateClass([ Validate(STRING) ], PieSeriesProperties.prototype, "angleKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "angleName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "angleFilterKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "radiusKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "radiusName", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], PieSeriesProperties.prototype, "radiusMin", 2); __decorateClass([ Validate(POSITIVE_NUMBER, { optional: true }) ], PieSeriesProperties.prototype, "radiusMax", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "calloutLabelKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "calloutLabelName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "sectorLabelKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "sectorLabelName", 2); __decorateClass([ Validate(STRING, { optional: true }) ], PieSeriesProperties.prototype, "legendItemKey", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], PieSeriesProperties.prototype, "fills", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], PieSeriesProperties.prototype, "strokes", 2); __decorateClass([ Validate(RATIO) ], PieSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate(RATIO) ], PieSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate(LINE_DASH) ], PieSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate(FUNCTION, { optional: true }) ], PieSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate(NUMBER) ], PieSeriesProperties.prototype, "rotation", 2); __decorateClass([ Validate(NUMBER) ], PieSeriesProperties.prototype, "outerRadiusOffset", 2); __decorateClass([ Validate(RATIO) ], PieSeriesProperties.prototype, "outerRadiusRatio", 2); __decorateClass([ Validate(POSITIVE_NUMBER) ], PieSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate(NUMBER) ], PieSeriesProperties.prototype, "sectorSpacing", 2); __decorateClass([ Validate(BOOLEAN) ], PieSeriesProperties.prototype, "hideZeroValueSectorsInLegend", 2); __decorateClass([ Validate(OBJECT) ], PieSeriesProperties.prototype, "title", 2); __decorateClass([ Validate(OBJECT) ], PieSeriesProperties.prototype, "shadow", 2); __decorateClass([ Validate(OBJECT) ], PieSeriesProperties.prototype, "calloutLabel", 2); __decorateClass([ Validate(OBJECT) ], PieSeriesProperties.prototype, "sectorLabel", 2); __decorateClass([ Validate(OBJECT) ], PieSeriesProperties.prototype, "calloutLine", 2); __decorateClass([ Validate(OBJECT) ], PieSeriesProperties.prototype, "tooltip", 2); } }); // packages/ag-charts-community/src/chart/series/polar/pieSeries.ts var PieSeriesNodeEvent, PieSeries; var init_pieSeries = __esm({ "packages/ag-charts-community/src/chart/series/polar/pieSeries.ts"() { "use strict"; init_main(); init_fromToMotion(); init_linearScale(); init_bbox(); init_group(); init_selection(); init_line(); init_sector2(); init_text(); init_sector(); init_angle(); init_format_util(); init_json(); init_number(); init_object(); init_dataModel(); init_processors(); init_marker(); init_series(); init_seriesLabelUtil(); init_pieSeriesProperties(); init_pieUtil(); init_polarSeries(); PieSeriesNodeEvent = class extends SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.angleKey = series.properties.angleKey; this.radiusKey = series.properties.radiusKey; this.calloutLabelKey = series.properties.calloutLabelKey; this.sectorLabelKey = series.properties.sectorLabelKey; } }; PieSeries = class extends PolarSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */], useLabelLayer: true, animationResetFns: { item: resetPieSelectionsFn, label: resetLabelFn } }); this.properties = new PieSeriesProperties(); this.phantomNodeData = void 0; this.backgroundGroup = new TranslatableGroup({ name: `${this.id}-background`, zIndex: 0 /* BACKGROUND */ }); this.previousRadiusScale = new LinearScale(); this.radiusScale = new LinearScale(); this.phantomGroup = this.backgroundGroup.appendChild(new Group({ name: "phantom" })); this.phantomSelection = Selection.select( this.phantomGroup, () => this.nodeFactory(), false ); this.calloutLabelGroup = this.contentGroup.appendChild(new Group({ name: "pieCalloutLabels" })); this.calloutLabelSelection = new Selection( this.calloutLabelGroup, Group ); // AG-6193 If the sum of all datums is 0, then we'll draw 1 or 2 rings to represent the empty series. this.zerosumRingsGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-zerosumRings` })); this.zerosumOuterRing = this.zerosumRingsGroup.appendChild(new Marker({ shape: "circle" })); this.surroundingRadius = void 0; this.NodeEvent = PieSeriesNodeEvent; this.angleScale = new LinearScale(); this.angleScale.domain = [0, 1]; this.angleScale.range = [-Math.PI, Math.PI].map((angle2) => angle2 + Math.PI / 2); this.phantomGroup.opacity = 0.2; } get calloutNodeData() { return this.phantomNodeData ?? this.nodeData; } attachSeries(seriesContentNode, seriesNode, annotationNode) { super.attachSeries(seriesContentNode, seriesNode, annotationNode); seriesContentNode.appendChild(this.backgroundGroup); } detachSeries(seriesContentNode, seriesNode, annotationNode) { super.detachSeries(seriesContentNode, seriesNode, annotationNode); seriesContentNode?.removeChild(this.backgroundGroup); } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.backgroundGroup.zIndex = [0 /* BACKGROUND */, index]; return true; } nodeFactory() { const sector = new Sector(); sector.miterLimit = 1e9; return sector; } getSeriesDomain(direction) { if (direction === "x" /* X */) { return this.angleScale.domain; } else { return this.radiusScale.domain; } } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { visible, id: seriesId, ctx: { legendManager } } = this; const { angleKey, angleFilterKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties; const validSector = (_value, _datum, index) => { return visible && legendManager.getItemEnabled({ seriesId, itemId: index }); }; const animationEnabled = !this.ctx.animationManager.isSkipped(); const extraKeyProps = []; const extraProps = []; if (legendItemKey) { extraKeyProps.push(keyProperty(legendItemKey, "band", { id: `legendItemKey` })); } else if (calloutLabelKey) { extraKeyProps.push(keyProperty(calloutLabelKey, "band", { id: `calloutLabelKey` })); } else if (sectorLabelKey) { extraKeyProps.push(keyProperty(sectorLabelKey, "band", { id: `sectorLabelKey` })); } const radiusScaleType = this.radiusScale.type; const angleScaleType = this.angleScale.type; if (radiusKey) { extraProps.push( rangedValueProperty(radiusKey, { id: "radiusValue", min: this.properties.radiusMin ?? 0, max: this.properties.radiusMax }), valueProperty(radiusKey, radiusScaleType, { id: `radiusRaw` }), // Raw value pass-through. normalisePropertyTo("radiusValue", [0, 1], 1, this.properties.radiusMin ?? 0, this.properties.radiusMax) ); } if (calloutLabelKey) { extraProps.push(valueProperty(calloutLabelKey, "band", { id: `calloutLabelValue` })); } if (sectorLabelKey) { extraProps.push(valueProperty(sectorLabelKey, "band", { id: `sectorLabelValue` })); } if (legendItemKey) { extraProps.push(valueProperty(legendItemKey, "band", { id: `legendItemValue` })); } if (angleFilterKey) { extraProps.push( accumulativeValueProperty(angleFilterKey, angleScaleType, { id: `angleFilterValue`, onlyPositive: true, validation: validSector, invalidValue: 0 }), valueProperty(angleFilterKey, angleScaleType, { id: `angleFilterRaw` }), normalisePropertyTo("angleFilterValue", [0, 1], 0, 0) ); } if (animationEnabled && this.processedData?.reduced?.animationValidation?.uniqueKeys && extraKeyProps.length > 0) { extraProps.push(diff(this.id, this.processedData)); } extraProps.push(animationValidation()); await this.requestDataModel(dataController, this.data, { props: [ ...extraKeyProps, accumulativeValueProperty(angleKey, angleScaleType, { id: `angleValue`, onlyPositive: true, validation: validSector, invalidValue: 0 }), valueProperty(angleKey, angleScaleType, { id: `angleRaw` }), // Raw value pass-through. normalisePropertyTo("angleValue", [0, 1], 0, 0), ...extraProps ] }); for (const valueDef of this.processedData?.defs?.values ?? []) { const { id, missing, property } = valueDef; const missCount = getMissCount(this, missing); if (id !== "angleRaw" && missCount > 0) { logger_exports.warnOnce( `no value was found for the key '${String(property)}' on ${missCount} data element${missCount > 1 ? "s" : ""}` ); } } this.animationState.transition("updateData"); } maybeRefreshNodeData() { if (!this.nodeDataRefresh) return; const { nodeData = [], phantomNodeData } = this.createNodeData() ?? {}; this.nodeData = nodeData; this.phantomNodeData = phantomNodeData; this.nodeDataRefresh = false; } getProcessedDataValues(dataModel, processedData) { const angleValues = dataModel.resolveColumnById(this, `angleValue`, processedData); const angleRawValues = dataModel.resolveColumnById(this, `angleRaw`, processedData); const angleFilterValues = this.properties.angleFilterKey != null ? dataModel.resolveColumnById(this, `angleFilterValue`, processedData) : void 0; const angleFilterRawValues = this.properties.angleFilterKey != null ? dataModel.resolveColumnById(this, `angleFilterRaw`, processedData) : void 0; const radiusValues = this.properties.radiusKey ? dataModel.resolveColumnById(this, `radiusValue`, processedData) : void 0; const radiusRawValues = this.properties.radiusKey ? dataModel.resolveColumnById(this, `radiusRaw`, processedData) : void 0; const calloutLabelValues = this.properties.calloutLabelKey ? dataModel.resolveColumnById(this, `calloutLabelValue`, processedData) : void 0; const sectorLabelValues = this.properties.sectorLabelKey ? dataModel.resolveColumnById(this, `sectorLabelValue`, processedData) : void 0; const legendItemValues = this.properties.legendItemKey ? dataModel.resolveColumnById(this, `legendItemValue`, processedData) : void 0; return { angleValues, angleRawValues, angleFilterValues, angleFilterRawValues, radiusValues, radiusRawValues, calloutLabelValues, sectorLabelValues, legendItemValues }; } createNodeData() { const { id: seriesId, processedData, dataModel, angleScale, ctx: { legendManager }, visible } = this; const { rotation } = this.properties; if (!dataModel || processedData?.type !== "ungrouped") return; const { angleValues, angleRawValues, angleFilterValues, angleFilterRawValues, radiusValues, radiusRawValues, calloutLabelValues, sectorLabelValues, legendItemValues } = this.getProcessedDataValues(dataModel, processedData); const useFilterAngles = angleFilterRawValues?.some((filterRawValue, index) => { return filterRawValue > angleRawValues[index]; }) ?? false; let currentStart = 0; let sum2 = 0; const nodes = []; const phantomNodes = angleFilterRawValues != null ? [] : void 0; const rawData = processedData.dataSources.get(this.id) ?? []; const invalidData = processedData.invalidData?.get(this.id); rawData.forEach((datum, datumIndex) => { if (invalidData?.[datumIndex] === true) return; const currentValue = useFilterAngles ? angleFilterValues[datumIndex] : angleValues[datumIndex]; const crossFilterScale = angleFilterRawValues != null && !useFilterAngles ? Math.sqrt(angleFilterRawValues[datumIndex] / angleRawValues[datumIndex]) : 1; const startAngle = angleScale.convert(currentStart) + toRadians(rotation); currentStart = currentValue; sum2 += currentValue; const endAngle = angleScale.convert(currentStart) + toRadians(rotation); const span = Math.abs(endAngle - startAngle); const midAngle = startAngle + span / 2; const angleValue = angleRawValues[datumIndex]; const radiusRaw = radiusValues?.[datumIndex] ?? 1; const radius = radiusRaw * crossFilterScale; const radiusValue = radiusRawValues?.[datumIndex]; const legendItemValue = legendItemValues?.[datumIndex]; const nodeLabels = this.getLabels( datum, midAngle, span, true, calloutLabelValues?.[datumIndex], sectorLabelValues?.[datumIndex], legendItemValue ); const sectorFormat = this.getSectorFormat(datum, datumIndex, false); const node = { itemId: datumIndex, series: this, datum, datumIndex, angleValue, midAngle, midCos: Math.cos(midAngle), midSin: Math.sin(midAngle), startAngle, endAngle, radius, innerRadius: Math.max(this.radiusScale.convert(0), 0), outerRadius: Math.max(this.radiusScale.convert(radius), 0), sectorFormat, radiusValue, legendItemValue, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }), ...nodeLabels }; nodes.push(node); if (phantomNodes != null) { phantomNodes.push({ ...node, radius: 1, innerRadius: Math.max(this.radiusScale.convert(0), 0), outerRadius: Math.max(this.radiusScale.convert(1), 0) }); } }); this.zerosumOuterRing.visible = sum2 === 0; return { itemId: seriesId, nodeData: nodes, labelData: nodes, phantomNodeData: phantomNodes }; } getLabels(datum, midAngle, span, skipDisabled, calloutLabelValue, sectorLabelValue, legendItemValue) { const { calloutLabel, sectorLabel, legendItemKey } = this.properties; const calloutLabelKey = !skipDisabled || calloutLabel.enabled ? this.properties.calloutLabelKey : void 0; const sectorLabelKey = !skipDisabled || sectorLabel.enabled ? this.properties.sectorLabelKey : void 0; if (!calloutLabelKey && !sectorLabelKey && !legendItemKey) { return {}; } const labelFormatterParams = { datum, angleKey: this.properties.angleKey, angleName: this.properties.angleName, radiusKey: this.properties.radiusKey, radiusName: this.properties.radiusName, calloutLabelKey: this.properties.calloutLabelKey, calloutLabelName: this.properties.calloutLabelName, sectorLabelKey: this.properties.sectorLabelKey, sectorLabelName: this.properties.sectorLabelName, legendItemKey: this.properties.legendItemKey }; const result = {}; if (calloutLabelKey && span >= toRadians(calloutLabel.minAngle)) { result.calloutLabel = { ...this.getTextAlignment(midAngle), text: this.getLabelText(calloutLabel, { ...labelFormatterParams, value: calloutLabelValue }), hidden: false, collisionTextAlign: void 0, collisionOffsetY: 0, box: void 0 }; } if (sectorLabelKey) { result.sectorLabel = { text: this.getLabelText(sectorLabel, { ...labelFormatterParams, value: sectorLabelValue }) }; } if (legendItemKey != null && legendItemValue != null) { result.legendItem = { key: legendItemKey, text: legendItemValue }; } return result; } getTextAlignment(midAngle) { const quadrantTextOpts = [ { textAlign: "center", textBaseline: "bottom" }, { textAlign: "left", textBaseline: "middle" }, { textAlign: "center", textBaseline: "hanging" }, { textAlign: "right", textBaseline: "middle" } ]; const midAngle180 = normalizeAngle180(midAngle); const quadrantStart = -0.75 * Math.PI; const quadrantOffset = midAngle180 - quadrantStart; const quadrant = Math.floor(quadrantOffset / (Math.PI / 2)); const quadrantIndex = mod(quadrant, quadrantTextOpts.length); return quadrantTextOpts[quadrantIndex]; } getSectorFormat(datum, datumIndex, highlighted) { const { angleKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey, fills, strokes, itemStyler } = this.properties; const defaultStroke = strokes[datumIndex % strokes.length]; const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius } = mergeDefaults( highlighted && this.properties.highlightStyle.item, { fill: fills.length > 0 ? fills[datumIndex % fills.length] : void 0, stroke: defaultStroke, strokeWidth: this.getStrokeWidth(this.properties.strokeWidth), strokeOpacity: this.getOpacity() }, this.properties ); let format; if (itemStyler) { format = this.cachedDatumCallback( this.getDatumId(datum, datumIndex) + (highlighted ? "-highlight" : "-hide"), () => itemStyler({ datum, angleKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey, fill, strokeOpacity, stroke: stroke3, strokeWidth, fillOpacity, lineDash, lineDashOffset, cornerRadius, highlighted, seriesId: this.id }) ); } return { fill: format?.fill ?? fill, fillOpacity: format?.fillOpacity ?? fillOpacity, stroke: format?.stroke ?? stroke3, strokeWidth: format?.strokeWidth ?? strokeWidth, strokeOpacity: format?.strokeOpacity ?? strokeOpacity, lineDash: format?.lineDash ?? lineDash, lineDashOffset: format?.lineDashOffset ?? lineDashOffset, cornerRadius: format?.cornerRadius ?? cornerRadius }; } getOuterRadius() { return Math.max(this.radius * this.properties.outerRadiusRatio + this.properties.outerRadiusOffset, 0); } updateRadiusScale(resize) { const newRange = [0, this.getOuterRadius()]; this.radiusScale.range = newRange; if (resize) { this.previousRadiusScale.range = newRange; } const setRadii = (d) => ({ ...d, innerRadius: Math.max(this.radiusScale.convert(0), 0), outerRadius: Math.max(this.radiusScale.convert(d.radius), 0) }); this.nodeData = this.nodeData.map(setRadii); this.phantomNodeData = this.phantomNodeData?.map(setRadii); } getTitleTranslationY() { const outerRadius = Math.max(0, this.radiusScale.range[1]); if (outerRadius === 0) { return NaN; } const spacing = this.properties.title?.spacing ?? 0; const titleOffset = 2 + spacing; const dy2 = Math.max(0, -outerRadius); return -outerRadius - titleOffset - dy2; } update({ seriesRect }) { const { title } = this.properties; const newNodeDataDependencies = { seriesRectWidth: seriesRect?.width, seriesRectHeight: seriesRect?.height }; const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null; if (resize) { this._nodeDataDependencies = newNodeDataDependencies; } this.maybeRefreshNodeData(); this.updateTitleNodes(); this.updateRadiusScale(resize); this.contentGroup.translationX = this.centerX; this.contentGroup.translationY = this.centerY; this.highlightGroup.translationX = this.centerX; this.highlightGroup.translationY = this.centerY; this.backgroundGroup.translationX = this.centerX; this.backgroundGroup.translationY = this.centerY; if (this.labelGroup) { this.labelGroup.translationX = this.centerX; this.labelGroup.translationY = this.centerY; } if (title) { const dy2 = this.getTitleTranslationY(); title.node.y = isFinite(dy2) ? dy2 : 0; const titleBox = title.node.getBBox(); title.node.visible = title.enabled && isFinite(dy2) && !this.bboxIntersectsSurroundingSeries(titleBox); } this.zerosumOuterRing.fillOpacity = 0; this.zerosumOuterRing.stroke = this.properties.calloutLabel.color; this.zerosumOuterRing.strokeWidth = 1; this.zerosumOuterRing.strokeOpacity = 1; this.updateNodeMidPoint(); this.updateSelections(); this.updateNodes(seriesRect); } updateTitleNodes() { const { oldTitle } = this; const { title } = this.properties; if (oldTitle !== title) { if (oldTitle) { this.labelGroup?.removeChild(oldTitle.node); } if (title) { title.node.textBaseline = "bottom"; this.labelGroup?.appendChild(title.node); } this.oldTitle = title; } } updateNodeMidPoint() { const setMidPoint = (d) => { const radius = d.innerRadius + (d.outerRadius - d.innerRadius) / 2; d.midPoint = { x: d.midCos * Math.max(0, radius), y: d.midSin * Math.max(0, radius) }; }; this.nodeData.forEach(setMidPoint); this.phantomNodeData?.forEach(setMidPoint); } updateSelections() { const { itemSelection, highlightSelection, phantomSelection, highlightLabelSelection, calloutLabelSelection, labelSelection } = this; const highlightedNodeData = this.nodeData.map((datum) => ({ ...datum, // Allow mutable sectorFormat, so formatted sector styles can be updated and varied // between normal and highlighted cases. sectorFormat: { ...datum.sectorFormat } })); const update = (selection, nodeData) => { selection.update(nodeData, void 0, (datum) => this.getDatumId(datum.datum, datum.datumIndex)); if (this.ctx.animationManager.isSkipped()) { selection.cleanup(); } }; update(itemSelection, this.nodeData); update(highlightSelection, highlightedNodeData); update(phantomSelection, this.phantomNodeData ?? []); calloutLabelSelection.update(this.calloutNodeData, (group) => { const line = new Line(); line.tag = 0 /* Callout */; line.pointerEvents = 1 /* None */; group.appendChild(line); const text3 = new Text(); text3.tag = 1 /* Label */; text3.pointerEvents = 1 /* None */; group.appendChild(text3); }); labelSelection.update(this.nodeData); highlightLabelSelection.update(highlightedNodeData); } updateNodes(seriesRect) { const highlightedDatum = this.ctx.highlightManager.getActiveHighlight(); const { visible } = this; this.backgroundGroup.visible = visible; this.contentGroup.visible = visible; this.highlightGroup.visible = visible && highlightedDatum?.series === this; this.highlightLabel.visible = visible && highlightedDatum?.series === this; if (this.labelGroup) { this.labelGroup.visible = visible; } this.contentGroup.opacity = this.getOpacity(); const animationDisabled = this.ctx.animationManager.isSkipped(); const updateSectorFn = (sector, datum, _index, isDatumHighlighted) => { const format = this.getSectorFormat(datum.datum, datum.itemId, isDatumHighlighted); datum.sectorFormat.fill = format.fill; datum.sectorFormat.stroke = format.stroke; if (animationDisabled) { sector.startAngle = datum.startAngle; sector.endAngle = datum.endAngle; sector.innerRadius = datum.innerRadius; sector.outerRadius = datum.outerRadius; } if (isDatumHighlighted || animationDisabled) { sector.fill = format.fill; sector.stroke = format.stroke; } sector.strokeWidth = format.strokeWidth; sector.fillOpacity = format.fillOpacity; sector.strokeOpacity = format.strokeOpacity; sector.lineDash = format.lineDash; sector.lineDashOffset = format.lineDashOffset; sector.cornerRadius = format.cornerRadius; sector.fillShadow = this.properties.shadow; const inset = Math.max( (this.properties.sectorSpacing + (format.stroke != null ? format.strokeWidth : 0)) / 2, 0 ); sector.inset = inset; sector.lineJoin = this.properties.sectorSpacing >= 0 || inset > 0 ? "miter" : "round"; }; this.itemSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false)); this.highlightSelection.each((node, datum, index) => { updateSectorFn(node, datum, index, true); node.visible = datum.itemId === highlightedDatum?.itemId; }); this.phantomSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false)); this.updateCalloutLineNodes(); this.updateCalloutLabelNodes(seriesRect); this.updateSectorLabelNodes(); this.updateZerosumRings(); this.animationState.transition("update"); } updateCalloutLineNodes() { const { calloutLine } = this.properties; const calloutLength = calloutLine.length; const calloutStrokeWidth = calloutLine.strokeWidth; const calloutColors = calloutLine.colors ?? this.properties.strokes; const { offset: offset4 } = this.properties.calloutLabel; this.calloutLabelSelection.selectByTag(0 /* Callout */).forEach((line, index) => { const datum = line.datum; const { calloutLabel: label, outerRadius } = datum; if (label?.text && !label.hidden && outerRadius !== 0) { line.visible = true; line.strokeWidth = calloutStrokeWidth; line.stroke = calloutColors[index % calloutColors.length]; line.fill = void 0; const x1 = datum.midCos * outerRadius; const y1 = datum.midSin * outerRadius; let x2 = datum.midCos * (outerRadius + calloutLength); let y2 = datum.midSin * (outerRadius + calloutLength); const isMoved = label.collisionTextAlign ?? label.collisionOffsetY !== 0; if (isMoved && label.box != null) { const box = label.box; let cx = x2; let cy = y2; if (x2 < box.x) { cx = box.x; } else if (x2 > box.x + box.width) { cx = box.x + box.width; } if (y2 < box.y) { cy = box.y; } else if (y2 > box.y + box.height) { cy = box.y + box.height; } const dx2 = cx - x2; const dy2 = cy - y2; const length2 = Math.sqrt(Math.pow(dx2, 2) + Math.pow(dy2, 2)); const paddedLength = length2 - offset4; if (paddedLength > 0) { x2 = x2 + dx2 * paddedLength / length2; y2 = y2 + dy2 * paddedLength / length2; } } line.x1 = x1; line.y1 = y1; line.x2 = x2; line.y2 = y2; } else { line.visible = false; } }); } getLabelOverflow(text3, box, seriesRect) { const seriesLeft = -this.centerX; const seriesRight = seriesLeft + seriesRect.width; const seriesTop = -this.centerY; const seriesBottom = seriesTop + seriesRect.height; const errPx = 1; let visibleTextPart = 1; if (box.x + errPx < seriesLeft) { visibleTextPart = (box.x + box.width - seriesLeft) / box.width; } else if (box.x + box.width - errPx > seriesRight) { visibleTextPart = (seriesRight - box.x) / box.width; } const hasVerticalOverflow = box.y + errPx < seriesTop || box.y + box.height - errPx > seriesBottom; const textLength = visibleTextPart === 1 ? text3.length : Math.floor(text3.length * visibleTextPart) - 1; const hasSurroundingSeriesOverflow = this.bboxIntersectsSurroundingSeries(box); return { textLength, hasVerticalOverflow, hasSurroundingSeriesOverflow }; } bboxIntersectsSurroundingSeries(box) { const { surroundingRadius } = this; if (surroundingRadius == null) { return false; } const corners = [ { x: box.x, y: box.y }, { x: box.x + box.width, y: box.y }, { x: box.x + box.width, y: box.y + box.height }, { x: box.x, y: box.y + box.height } ]; const sur2 = surroundingRadius ** 2; return corners.some((corner) => corner.x ** 2 + corner.y ** 2 > sur2); } computeCalloutLabelCollisionOffsets() { const { radiusScale } = this; const { calloutLabel, calloutLine } = this.properties; const { offset: offset4, minSpacing } = calloutLabel; const innerRadius = radiusScale.convert(0); const shouldSkip = (datum) => { const label = datum.calloutLabel; return !label || datum.outerRadius === 0; }; const fullData = this.calloutNodeData; const data = fullData.filter((t) => !shouldSkip(t)); data.forEach((datum) => { const label = datum.calloutLabel; if (label == null) return; label.hidden = false; label.collisionTextAlign = void 0; label.collisionOffsetY = 0; }); if (data.length <= 1) { return; } const leftLabels = data.filter((d) => d.midCos < 0).sort((a, b) => a.midSin - b.midSin); const rightLabels = data.filter((d) => d.midCos >= 0).sort((a, b) => a.midSin - b.midSin); const topLabels = data.filter((d) => d.midSin < 0 && d.calloutLabel?.textAlign === "center").sort((a, b) => a.midCos - b.midCos); const bottomLabels = data.filter((d) => d.midSin >= 0 && d.calloutLabel?.textAlign === "center").sort((a, b) => a.midCos - b.midCos); const getTextBBox = (datum) => { const label = datum.calloutLabel; if (label == null) return BBox.zero.clone(); const labelRadius = datum.outerRadius + calloutLine.length + offset4; const x = datum.midCos * labelRadius; const y = datum.midSin * labelRadius + label.collisionOffsetY; const textAlign = label.collisionTextAlign ?? label.textAlign; const textBaseline = label.textBaseline; return Text.computeBBox(label.text, x, y, { font: this.properties.calloutLabel, textAlign, textBaseline }); }; const avoidNeighbourYCollision = (label, next, direction) => { const box = getTextBBox(label).grow(minSpacing / 2); const other = getTextBBox(next).grow(minSpacing / 2); const collidesOrBehind = box.x < other.x + other.width && box.x + box.width > other.x && (direction === "to-top" ? box.y < other.y + other.height : box.y + box.height > other.y); if (collidesOrBehind) { next.calloutLabel.collisionOffsetY = direction === "to-top" ? box.y - other.y - other.height : box.y + box.height - other.y; } }; const avoidYCollisions = (labels) => { const midLabel = labels.slice().sort((a, b) => Math.abs(a.midSin) - Math.abs(b.midSin))[0]; const midIndex = labels.indexOf(midLabel); for (let i = midIndex - 1; i >= 0; i--) { const prev = labels[i + 1]; const next = labels[i]; avoidNeighbourYCollision(prev, next, "to-top"); } for (let i = midIndex + 1; i < labels.length; i++) { const prev = labels[i - 1]; const next = labels[i]; avoidNeighbourYCollision(prev, next, "to-bottom"); } }; const avoidXCollisions = (labels) => { const labelsCollideLabelsByY = data.some((datum) => datum.calloutLabel.collisionOffsetY !== 0); const boxes = labels.map((label) => getTextBBox(label)); const paddedBoxes = boxes.map((box) => box.clone().grow(minSpacing / 2)); let labelsCollideLabelsByX = false; for (let i = 0; i < paddedBoxes.length && !labelsCollideLabelsByX; i++) { const box = paddedBoxes[i]; for (let j = i + 1; j < labels.length; j++) { const other = paddedBoxes[j]; if (box.collidesBBox(other)) { labelsCollideLabelsByX = true; break; } } } const sectors = fullData.map((datum) => { const { startAngle, endAngle, outerRadius } = datum; return { startAngle, endAngle, innerRadius, outerRadius }; }); const labelsCollideSectors = boxes.some((box) => { return sectors.some((sector) => boxCollidesSector(box, sector)); }); if (!labelsCollideLabelsByX && !labelsCollideLabelsByY && !labelsCollideSectors) { return; } labels.filter((d) => d.calloutLabel.textAlign === "center").forEach((d) => { const label = d.calloutLabel; if (d.midCos < 0) { label.collisionTextAlign = "right"; } else if (d.midCos > 0) { label.collisionTextAlign = "left"; } else { label.collisionTextAlign = "center"; } }); }; avoidYCollisions(leftLabels); avoidYCollisions(rightLabels); avoidXCollisions(topLabels); avoidXCollisions(bottomLabels); } updateCalloutLabelNodes(seriesRect) { const { radiusScale } = this; const { calloutLabel, calloutLine } = this.properties; const calloutLength = calloutLine.length; const { offset: offset4, color } = calloutLabel; const tempTextNode = new Text(); this.calloutLabelSelection.selectByTag(1 /* Label */).forEach((text3) => { const { datum } = text3; const label = datum.calloutLabel; const radius = radiusScale.convert(datum.radius); const outerRadius = Math.max(0, radius); if (!label?.text || outerRadius === 0 || label.hidden) { text3.visible = false; return; } const labelRadius = outerRadius + calloutLength + offset4; const x = datum.midCos * labelRadius; const y = datum.midSin * labelRadius + label.collisionOffsetY; const align2 = { textAlign: label.collisionTextAlign ?? label.textAlign, textBaseline: label.textBaseline }; tempTextNode.text = label.text; tempTextNode.x = x; tempTextNode.y = y; tempTextNode.setFont(this.properties.calloutLabel); tempTextNode.setAlign(align2); const box = tempTextNode.getBBox(); let displayText = label.text; let visible = true; if (calloutLabel.avoidCollisions) { const { textLength, hasVerticalOverflow } = this.getLabelOverflow(label.text, box, seriesRect); displayText = label.text.length === textLength ? label.text : `${label.text.substring(0, textLength)}\u2026`; visible = !hasVerticalOverflow; } text3.text = displayText; text3.x = x; text3.y = y; text3.setFont(this.properties.calloutLabel); text3.setAlign(align2); text3.fill = color; text3.visible = visible; }); } computeLabelsBBox(options, seriesRect) { const { calloutLabel, calloutLine } = this.properties; const calloutLength = calloutLine.length; const { offset: offset4, maxCollisionOffset, minSpacing } = calloutLabel; if (!calloutLabel.avoidCollisions) { return null; } this.maybeRefreshNodeData(); this.updateRadiusScale(false); this.computeCalloutLabelCollisionOffsets(); const textBoxes = []; const text3 = new Text(); let titleBox; const { title } = this.properties; if (title?.text && title.enabled) { const dy2 = this.getTitleTranslationY(); if (isFinite(dy2)) { text3.text = title.text; text3.x = 0; text3.y = dy2; text3.setFont(title); text3.setAlign({ textBaseline: "bottom", textAlign: "center" }); titleBox = text3.getBBox(); textBoxes.push(titleBox); } } this.calloutNodeData.forEach((datum) => { const label = datum.calloutLabel; if (!label || datum.outerRadius === 0) { return null; } const labelRadius = datum.outerRadius + calloutLength + offset4; const x = datum.midCos * labelRadius; const y = datum.midSin * labelRadius + label.collisionOffsetY; text3.text = label.text; text3.x = x; text3.y = y; text3.setFont(this.properties.calloutLabel); text3.setAlign({ textAlign: label.collisionTextAlign ?? label.textAlign, textBaseline: label.textBaseline }); const box = text3.getBBox(); label.box = box; if (Math.abs(label.collisionOffsetY) > maxCollisionOffset) { label.hidden = true; return; } if (titleBox) { const seriesTop = -this.centerY; const titleCleanArea = new BBox( titleBox.x - minSpacing, seriesTop, titleBox.width + 2 * minSpacing, titleBox.y + titleBox.height + minSpacing - seriesTop ); if (box.collidesBBox(titleCleanArea)) { label.hidden = true; return; } } if (options.hideWhenNecessary) { const { textLength, hasVerticalOverflow, hasSurroundingSeriesOverflow } = this.getLabelOverflow( label.text, box, seriesRect ); const isTooShort = label.text.length > 2 && textLength < 2; if (hasVerticalOverflow || isTooShort || hasSurroundingSeriesOverflow) { label.hidden = true; return; } } label.hidden = false; textBoxes.push(box); }); if (textBoxes.length === 0) { return null; } return BBox.merge(textBoxes); } updateSectorLabelNodes() { const { radiusScale } = this; const innerRadius = radiusScale.convert(0); const { fontSize, fontStyle, fontWeight, fontFamily, positionOffset, positionRatio, color } = this.properties.sectorLabel; const isDonut = innerRadius > 0; const singleVisibleSector = this.ctx.legendManager.getData(this.id)?.filter((d) => d.enabled).length === 1; const updateSectorLabel = (text3, datum) => { const { sectorLabel, outerRadius, startAngle, endAngle } = datum; let isTextVisible = false; if (sectorLabel && outerRadius !== 0) { const labelRadius = innerRadius * (1 - positionRatio) + outerRadius * positionRatio + positionOffset; text3.fill = color; text3.fontStyle = fontStyle; text3.fontWeight = fontWeight; text3.fontSize = fontSize; text3.fontFamily = fontFamily; text3.text = sectorLabel.text; const shouldPutTextInCenter = !isDonut && singleVisibleSector; if (shouldPutTextInCenter) { text3.x = 0; text3.y = 0; } else { text3.x = datum.midCos * labelRadius; text3.y = datum.midSin * labelRadius; } text3.textAlign = "center"; text3.textBaseline = "middle"; const bbox = text3.getBBox(); const corners = [ [bbox.x, bbox.y], [bbox.x + bbox.width, bbox.y], [bbox.x + bbox.width, bbox.y + bbox.height], [bbox.x, bbox.y + bbox.height] ]; const sectorBounds = { startAngle, endAngle, innerRadius, outerRadius }; if (corners.every(([x, y]) => isPointInSector(x, y, sectorBounds))) { isTextVisible = true; } } text3.visible = isTextVisible; }; this.labelSelection.each(updateSectorLabel); this.highlightLabelSelection.each(updateSectorLabel); } updateZerosumRings() { this.zerosumOuterRing.size = this.getOuterRadius() * 2; } pickNodeClosestDatum(point) { return pickByMatchingAngle(this, point); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { legendItemKey, calloutLabelKey, calloutLabelName, sectorLabelKey, sectorLabelName, angleKey, angleName, radiusKey, radiusName, tooltip } = properties; const title = this.properties.title.text; if (!dataModel || !processedData) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const { angleRawValues, legendItemValues, calloutLabelValues, sectorLabelValues } = this.getProcessedDataValues( dataModel, processedData ); const angleRawValue = angleRawValues[datumIndex]; const label = legendItemValues?.[datumIndex] ?? (calloutLabelKey === angleKey ? void 0 : calloutLabelValues?.[datumIndex]) ?? (sectorLabelKey === angleKey ? void 0 : sectorLabelValues?.[datumIndex]) ?? angleName; return tooltip.formatTooltip( { title, symbol: this.legendItemSymbol(datumIndex), data: [ { label, fallbackLabel: angleKey, value: formatValue(angleRawValue, 3) } ] }, { seriesId, datum, title: angleName, legendItemKey, calloutLabelKey, calloutLabelName, sectorLabelKey, sectorLabelName, angleKey, angleName, radiusKey, radiusName, ...this.getSectorFormat(datum, datumIndex, false) } ); } legendItemSymbol(datumIndex) { const datum = this.processedData?.dataSources.get(this.id)?.[datumIndex]; const sectorFormat = this.getSectorFormat(datum, datumIndex, false); return { marker: { fill: sectorFormat.fill, stroke: sectorFormat.stroke, fillOpacity: this.properties.fillOpacity, strokeOpacity: this.properties.strokeOpacity, strokeWidth: this.properties.strokeWidth, lineDash: this.properties.lineDash, lineDashOffset: this.properties.lineDashOffset } }; } getLegendData(legendType) { const { id: seriesId, visible, processedData, dataModel, ctx: { legendManager } } = this; if (!dataModel || !processedData || legendType !== "category") { return []; } const { angleKey, calloutLabelKey, sectorLabelKey, legendItemKey, showInLegend } = this.properties; if (!legendItemKey && (!calloutLabelKey || calloutLabelKey === angleKey) && (!sectorLabelKey || sectorLabelKey === angleKey)) { return []; } const { calloutLabelValues, sectorLabelValues, legendItemValues, angleRawValues } = this.getProcessedDataValues( dataModel, processedData ); const titleText = this.properties.title?.showInLegend && this.properties.title.text; const legendData = []; const hideZeros = this.properties.hideZeroValueSectorsInLegend; const rawData = processedData.dataSources.get(this.id); const invalidData = processedData.invalidData?.get(this.id); for (let datumIndex = 0; datumIndex < processedData.input.count; datumIndex++) { const datum = rawData?.[datumIndex]; const angleRawValue = angleRawValues[datumIndex]; if (invalidData?.[datumIndex] === true || hideZeros && angleRawValue === 0) { continue; } const labelParts = []; if (titleText) { labelParts.push(titleText); } const labels = this.getLabels( datum, 2 * Math.PI, 2 * Math.PI, false, calloutLabelValues?.[datumIndex], sectorLabelValues?.[datumIndex], legendItemValues?.[datumIndex] ); if (legendItemKey && labels.legendItem !== void 0) { labelParts.push(labels.legendItem.text); } else if (calloutLabelKey && calloutLabelKey !== angleKey && labels.calloutLabel?.text !== void 0) { labelParts.push(labels.calloutLabel?.text); } else if (sectorLabelKey && sectorLabelKey !== angleKey && labels.sectorLabel?.text !== void 0) { labelParts.push(labels.sectorLabel?.text); } if (labelParts.length === 0) continue; legendData.push({ legendType: "category", id: seriesId, datum, itemId: datumIndex, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }), label: { text: labelParts.join(" - ") }, symbol: this.legendItemSymbol(datumIndex), legendItemName: legendItemKey != null ? datum[legendItemKey] : void 0, hideInLegend: !showInLegend }); } return legendData; } // Used for grid setLegendState(enabledItems) { const { id: seriesId, ctx: { legendManager, updateService } } = this; enabledItems.forEach((enabled, itemId) => legendManager.toggleItem({ enabled, seriesId, itemId })); legendManager.update(); updateService.update(4 /* SERIES_UPDATE */); } animateEmptyUpdateReady(_data) { const { animationManager } = this.ctx; const fns = preparePieSeriesAnimationFunctions( true, this.properties.rotation, this.radiusScale, this.previousRadiusScale ); fromToMotion( this.id, "nodes", animationManager, [this.itemSelection, this.highlightSelection, this.phantomSelection], fns.nodes, (_, datum) => this.getDatumId(datum.datum, datum.datumIndex) ); seriesLabelFadeInAnimation(this, "callout", animationManager, this.calloutLabelSelection); seriesLabelFadeInAnimation(this, "sector", animationManager, this.labelSelection); seriesLabelFadeInAnimation(this, "highlight", animationManager, this.highlightLabelSelection); this.previousRadiusScale.range = this.radiusScale.range; } animateWaitingUpdateReady() { const { itemSelection, highlightSelection, phantomSelection, processedData, radiusScale, previousRadiusScale } = this; const { animationManager } = this.ctx; const dataDiff = processedData?.reduced?.diff?.[this.id]; this.ctx.animationManager.stopByAnimationGroupId(this.id); const supportedDiff = (dataDiff?.moved.size ?? 0) === 0; const hasKeys = (processedData?.defs.keys.length ?? 0) > 0; const hasUniqueKeys = processedData?.reduced?.animationValidation?.uniqueKeys ?? true; if (!supportedDiff || !hasKeys || !hasUniqueKeys) { this.ctx.animationManager.skipCurrentBatch(); } const fns = preparePieSeriesAnimationFunctions( false, this.properties.rotation, radiusScale, previousRadiusScale ); fromToMotion( this.id, "nodes", animationManager, [itemSelection, highlightSelection, phantomSelection], fns.nodes, (_, datum) => this.getDatumId(datum.datum, datum.datumIndex), dataDiff ); seriesLabelFadeInAnimation(this, "callout", this.ctx.animationManager, this.calloutLabelSelection); seriesLabelFadeInAnimation(this, "sector", this.ctx.animationManager, this.labelSelection); seriesLabelFadeInAnimation(this, "highlight", this.ctx.animationManager, this.highlightLabelSelection); this.previousRadiusScale.range = this.radiusScale.range; } animateClearingUpdateEmpty() { const { itemSelection, highlightSelection, phantomSelection, radiusScale, previousRadiusScale } = this; const { animationManager } = this.ctx; const fns = preparePieSeriesAnimationFunctions( false, this.properties.rotation, radiusScale, previousRadiusScale ); fromToMotion( this.id, "nodes", animationManager, [itemSelection, highlightSelection, phantomSelection], fns.nodes, (_, datum) => this.getDatumId(datum.datum, datum.datumIndex) ); seriesLabelFadeOutAnimation(this, "callout", this.ctx.animationManager, this.calloutLabelSelection); seriesLabelFadeOutAnimation(this, "sector", this.ctx.animationManager, this.labelSelection); seriesLabelFadeOutAnimation(this, "highlight", this.ctx.animationManager, this.highlightLabelSelection); this.previousRadiusScale.range = this.radiusScale.range; } getDatumId(datum, datumIndex) { const { calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties; if (!this.processedData?.reduced?.animationValidation?.uniqueKeys) { return `${datumIndex}`; } if (legendItemKey) { return createDatumId(datum[legendItemKey]); } else if (calloutLabelKey) { return createDatumId(datum[calloutLabelKey]); } else if (sectorLabelKey) { return createDatumId(datum[sectorLabelKey]); } return `${datumIndex}`; } }; PieSeries.className = "PieSeries"; PieSeries.type = "pie"; } }); // packages/ag-charts-community/src/chart/series/polar/pieSeriesModule.ts var PieSeriesModule; var init_pieSeriesModule = __esm({ "packages/ag-charts-community/src/chart/series/polar/pieSeriesModule.ts"() { "use strict"; init_pieSeries(); init_pieTheme(); PieSeriesModule = { type: "series", optionsKey: "series[]", packageType: "community", chartTypes: ["polar"], identifier: "pie", moduleFactory: (ctx) => new PieSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: pieTheme, paletteFactory: piePaletteFactory }; } }); // packages/ag-charts-community/src/chart/factory/registerInbuiltModules.ts function registerInbuiltModules() { moduleRegistry.register( BackgroundModule, CommunityLegendModule, LocaleModule, AreaSeriesModule, BarSeriesModule, BubbleSeriesModule, LineSeriesModule, ScatterSeriesModule, DonutSeriesModule, PieSeriesModule, HistogramSeriesModule ); for (const AxisConstructor of [NumberAxis, CategoryAxis, TimeAxis, GroupedCategoryAxis, LogAxis]) { axisRegistry.register(AxisConstructor.type, { moduleFactory: (ctx) => new AxisConstructor(ctx) }); } } var init_registerInbuiltModules = __esm({ "packages/ag-charts-community/src/chart/factory/registerInbuiltModules.ts"() { "use strict"; init_localeModule(); init_module(); init_categoryAxis(); init_groupedCategoryAxis(); init_logAxis(); init_numberAxis(); init_timeAxis(); init_backgroundModule(); init_legendModule(); init_areaSeriesModule(); init_barSeriesModule(); init_bubbleSeriesModule(); init_histogramSeriesModule(); init_lineSeriesModule(); init_scatterSeriesModule(); init_donutSeriesModule(); init_pieSeriesModule(); init_axisRegistry(); } }); // packages/ag-charts-community/src/chart/factory/setupModules.ts function setupModules() { for (const m of moduleRegistry.modules) { if (m.packageType === "enterprise" && !verifyIfModuleExpected(m)) { logger_exports.errorOnce("Unexpected enterprise module registered: " + m.identifier); } if (m.type === "root" && m.themeTemplate) { for (const chartType of m.chartTypes) { chartDefaults.set(chartType, m.themeTemplate); } } if (m.type === "series") { if (m.chartTypes.length > 1) { throw new Error(`AG Charts - Module definition error: ${m.identifier}`); } seriesRegistry.register(m.identifier, m); } if (m.type === "series-option" && m.themeTemplate) { for (const seriesType of m.seriesTypes) { seriesRegistry.setThemeTemplate(seriesType, m.themeTemplate); } } if (m.type === "axis-option" && m.themeTemplate) { for (const axisType of m.axisTypes) { const axisTypeTheme = axisRegistry.getThemeTemplate(axisType); const theme = mergeDefaults(m.themeTemplate, axisTypeTheme); axisRegistry.setThemeTemplate(axisType, theme); } } if (m.type === "axis") { axisRegistry.register(m.identifier, m); } if (m.type === "legend") { legendRegistry.register(m.identifier, m); } } if (moduleRegistry.hasEnterpriseModules()) { const expectedButUnused = getUnusedExpectedModules(); if (expectedButUnused.length > 0) { logger_exports.errorOnce("Enterprise modules expected but not registered: ", expectedButUnused); } } } var init_setupModules = __esm({ "packages/ag-charts-community/src/chart/factory/setupModules.ts"() { "use strict"; init_main(); init_module(); init_object(); init_axisRegistry(); init_chartTypes(); init_expectedEnterpriseModules(); init_legendRegistry(); init_seriesRegistry(); } }); // packages/ag-charts-community/src/chart/axis/polarAxis.ts var PolarAxis; var init_polarAxis = __esm({ "packages/ag-charts-community/src/chart/axis/polarAxis.ts"() { "use strict"; init_validation2(); init_axis(); init_axisUtil(); PolarAxis = class extends Axis { constructor() { super(...arguments); this.shape = "polygon"; this.innerRadiusRatio = 0; this.defaultTickMinSpacing = 20; } updatePosition() { super.updatePosition(); const selectionCtx = prepareAxisAnimationContext(this); const resetAxisFn = resetAxisSelectionFn(selectionCtx); this.axisGroup.setProperties(this.getAxisTransform()); this.gridLineGroupSelection.each(resetAxisFn); this.tickLineGroupSelection.each(resetAxisFn); this.tickLabelGroupSelection.each(resetAxisLabelSelectionFn()); } computeLabelsBBox(_options, _seriesRect) { return null; } computeRange() { } getAxisLinePoints() { return void 0; } }; __decorateClass([ Validate(UNION(["polygon", "circle"], "a polar axis shape")) ], PolarAxis.prototype, "shape", 2); __decorateClass([ Validate(RATIO) ], PolarAxis.prototype, "innerRadiusRatio", 2); } }); // packages/ag-charts-community/src/chart/polarChart.ts function isPolarSeries(series) { return series instanceof PolarSeries; } function isPolarAxis(axis) { return axis instanceof PolarAxis; } var PolarChart; var init_polarChart = __esm({ "packages/ag-charts-community/src/chart/polarChart.ts"() { "use strict"; init_main(); init_bbox(); init_padding(); init_polarAxis(); init_chart(); init_polarSeries(); PolarChart = class extends Chart { constructor(options, resources) { super(options, resources); this.padding = new Padding(40); this.ctx.axisManager.axisGroup.zIndex = 6 /* AXIS_FOREGROUND */; } getChartType() { return "polar"; } async performLayout(ctx) { const { layoutBox } = ctx; layoutBox.shrink(this.seriesArea.padding.toJson()); const seriesRect = layoutBox.clone(); this.seriesRect = seriesRect; this.animationRect = seriesRect; this.seriesRoot.translationX = seriesRect.x; this.seriesRoot.translationY = seriesRect.y; await this.computeCircle(seriesRect); this.axes.forEach((axis) => axis.update()); this.ctx.layoutManager.emitLayoutComplete(ctx, { series: { visible: true, rect: seriesRect, paddedRect: seriesRect } }); } updateAxes(seriesBox, cx, cy, radius) { const angleAxis = this.axes.find((axis) => axis.direction === "x" /* X */); const radiusAxis = this.axes.find((axis) => axis.direction === "y" /* Y */); if (!(angleAxis instanceof PolarAxis) || !(radiusAxis instanceof PolarAxis)) return; const angleScale = angleAxis.scale; const innerRadiusRatio = radiusAxis.innerRadiusRatio; angleAxis.innerRadiusRatio = innerRadiusRatio; angleAxis.computeRange(); angleAxis.gridLength = radius; radiusAxis.gridAngles = angleScale.ticks({ nice: angleAxis.nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity })?.map((value) => angleScale.convert(value)); radiusAxis.gridRange = angleAxis.range; radiusAxis.range = [radius, radius * innerRadiusRatio]; [angleAxis, radiusAxis].forEach((axis) => { axis.translation.x = seriesBox.x + cx; axis.translation.y = seriesBox.y + cy; axis.calculateLayout(); }); } async computeCircle(seriesBox) { const polarSeries = this.series.filter(isPolarSeries); const polarAxes = this.axes.filter(isPolarAxis); const setSeriesCircle = (cx, cy, r) => { this.updateAxes(seriesBox, cx, cy, r); polarSeries.forEach((series) => { series.centerX = cx; series.centerY = cy; series.radius = r; }); const pieSeries = polarSeries.filter((s) => s.type === "donut" || s.type === "pie"); if (pieSeries.length > 1) { const innerRadii = pieSeries.map((series) => { const innerRadius = series.getInnerRadius(); return { series, innerRadius }; }).sort((a, b) => a.innerRadius - b.innerRadius); innerRadii.at(-1).series.surroundingRadius = void 0; for (let i = 0; i < innerRadii.length - 1; i++) { innerRadii[i].series.surroundingRadius = innerRadii[i + 1].innerRadius; } } }; const centerX = seriesBox.width / 2; const centerY = seriesBox.height / 2; const initialRadius = Math.max(0, Math.min(seriesBox.width, seriesBox.height) / 2); let radius = initialRadius; setSeriesCircle(centerX, centerY, radius); const shake = async ({ hideWhenNecessary = false } = {}) => { const labelBoxes = []; for (const series of iterate(polarAxes, polarSeries)) { const box = await series.computeLabelsBBox({ hideWhenNecessary }, seriesBox); if (box) { labelBoxes.push(box); } } if (labelBoxes.length === 0) { setSeriesCircle(centerX, centerY, initialRadius); return; } const labelBox = BBox.merge(labelBoxes); const refined = this.refineCircle(labelBox, radius, seriesBox); setSeriesCircle(refined.centerX, refined.centerY, refined.radius); radius = refined.radius; }; await shake(); await shake(); await shake(); await shake({ hideWhenNecessary: true }); await shake({ hideWhenNecessary: true }); for (const series of iterate(polarAxes, polarSeries)) { await series.computeLabelsBBox({ hideWhenNecessary: true }, seriesBox); } return { radius, centerX, centerY }; } refineCircle(labelsBox, radius, seriesBox) { const minCircleRatio = 0.5; const circleLeft = -radius; const circleTop = -radius; const circleRight = radius; const circleBottom = radius; let padLeft = Math.max(0, circleLeft - labelsBox.x); let padTop = Math.max(0, circleTop - labelsBox.y); let padRight = Math.max(0, labelsBox.x + labelsBox.width - circleRight); let padBottom = Math.max(0, labelsBox.y + labelsBox.height - circleBottom); padLeft = padRight = Math.max(padLeft, padRight); padTop = padBottom = Math.max(padTop, padBottom); const availCircleWidth = seriesBox.width - padLeft - padRight; const availCircleHeight = seriesBox.height - padTop - padBottom; let newRadius = Math.min(availCircleWidth, availCircleHeight) / 2; const minHorizontalRadius = minCircleRatio * seriesBox.width / 2; const minVerticalRadius = minCircleRatio * seriesBox.height / 2; const minRadius = Math.min(minHorizontalRadius, minVerticalRadius); if (newRadius < minRadius) { newRadius = minRadius; const horizontalPadding = padLeft + padRight; const verticalPadding = padTop + padBottom; if (2 * newRadius + verticalPadding > seriesBox.height) { const padHeight = seriesBox.height - 2 * newRadius; if (Math.min(padTop, padBottom) * 2 > padHeight) { padTop = padHeight / 2; padBottom = padHeight / 2; } else if (padTop > padBottom) { padTop = padHeight - padBottom; } else { padBottom = padHeight - padTop; } } if (2 * newRadius + horizontalPadding > seriesBox.width) { const padWidth = seriesBox.width - 2 * newRadius; if (Math.min(padLeft, padRight) * 2 > padWidth) { padLeft = padWidth / 2; padRight = padWidth / 2; } else if (padLeft > padRight) { padLeft = padWidth - padRight; } else { padRight = padWidth - padLeft; } } } const newWidth = padLeft + 2 * newRadius + padRight; const newHeight = padTop + 2 * newRadius + padBottom; return { centerX: (seriesBox.width - newWidth) / 2 + padLeft + newRadius, centerY: (seriesBox.height - newHeight) / 2 + padTop + newRadius, radius: newRadius }; } }; PolarChart.className = "PolarChart"; PolarChart.type = "polar"; } }); // packages/ag-charts-community/src/chart/polarChartModule.ts var PolarChartModule; var init_polarChartModule = __esm({ "packages/ag-charts-community/src/chart/polarChartModule.ts"() { "use strict"; init_types(); init_polarChart(); PolarChartModule = { type: "chart", name: "polar", detect: isAgPolarChartOptions, create(options, resources) { return new PolarChart(options, resources); } }; } }); // packages/ag-charts-community/src/module/enterpriseModule.ts var enterpriseModule; var init_enterpriseModule = __esm({ "packages/ag-charts-community/src/module/enterpriseModule.ts"() { "use strict"; enterpriseModule = { isEnterprise: false }; } }); // packages/ag-charts-types/src/api/initialStateOptions.ts var init_initialStateOptions = __esm({ "packages/ag-charts-types/src/api/initialStateOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/api/agCharts.ts var init_agCharts = __esm({ "packages/ag-charts-types/src/api/agCharts.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/annotationsOptions.ts var init_annotationsOptions = __esm({ "packages/ag-charts-types/src/chart/annotationsOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/axisOptions.ts var init_axisOptions = __esm({ "packages/ag-charts-types/src/chart/axisOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/callbackOptions.ts var init_callbackOptions = __esm({ "packages/ag-charts-types/src/chart/callbackOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/chartOptions.ts var init_chartOptions = __esm({ "packages/ag-charts-types/src/chart/chartOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/chartToolbarOptions.ts var init_chartToolbarOptions = __esm({ "packages/ag-charts-types/src/chart/chartToolbarOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/contextMenuOptions.ts var init_contextMenuOptions = __esm({ "packages/ag-charts-types/src/chart/contextMenuOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/crossLineOptions.ts var init_crossLineOptions = __esm({ "packages/ag-charts-types/src/chart/crossLineOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/crosshairOptions.ts var init_crosshairOptions = __esm({ "packages/ag-charts-types/src/chart/crosshairOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/dropShadowOptions.ts var init_dropShadowOptions = __esm({ "packages/ag-charts-types/src/chart/dropShadowOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/errorBarOptions.ts var AgErrorBarSupportedSeriesTypes; var init_errorBarOptions = __esm({ "packages/ag-charts-types/src/chart/errorBarOptions.ts"() { "use strict"; AgErrorBarSupportedSeriesTypes = ["bar", "line", "scatter"]; } }); // packages/ag-charts-types/src/chart/eventOptions.ts var init_eventOptions = __esm({ "packages/ag-charts-types/src/chart/eventOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/gradientLegendOptions.ts var init_gradientLegendOptions = __esm({ "packages/ag-charts-types/src/chart/gradientLegendOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/icons.ts var init_icons = __esm({ "packages/ag-charts-types/src/chart/icons.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/labelOptions.ts var init_labelOptions = __esm({ "packages/ag-charts-types/src/chart/labelOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/legendOptions.ts var init_legendOptions = __esm({ "packages/ag-charts-types/src/chart/legendOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/localeOptions.ts var init_localeOptions = __esm({ "packages/ag-charts-types/src/chart/localeOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/navigatorOptions.ts var __MINI_CHART_SERIES_OPTIONS, __VERIFY_MINI_CHART_SERIES_OPTIONS; var init_navigatorOptions = __esm({ "packages/ag-charts-types/src/chart/navigatorOptions.ts"() { "use strict"; __MINI_CHART_SERIES_OPTIONS = void 0; __VERIFY_MINI_CHART_SERIES_OPTIONS = void 0; __VERIFY_MINI_CHART_SERIES_OPTIONS = __MINI_CHART_SERIES_OPTIONS; } }); // packages/ag-charts-types/src/chart/polarAxisOptions.ts var init_polarAxisOptions = __esm({ "packages/ag-charts-types/src/chart/polarAxisOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/rangesOptions.ts var init_rangesOptions = __esm({ "packages/ag-charts-types/src/chart/rangesOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/themeOptions.ts var __THEME_OVERRIDES, __VERIFY_THEME_OVERRIDES; var init_themeOptions = __esm({ "packages/ag-charts-types/src/chart/themeOptions.ts"() { "use strict"; __THEME_OVERRIDES = void 0; __VERIFY_THEME_OVERRIDES = void 0; __VERIFY_THEME_OVERRIDES = __THEME_OVERRIDES; } }); // packages/ag-charts-types/src/chart/tooltipOptions.ts var AgTooltipPositionType; var init_tooltipOptions = __esm({ "packages/ag-charts-types/src/chart/tooltipOptions.ts"() { "use strict"; AgTooltipPositionType = /* @__PURE__ */ ((AgTooltipPositionType2) => { AgTooltipPositionType2["POINTER"] = "pointer"; AgTooltipPositionType2["NODE"] = "node"; AgTooltipPositionType2["TOP"] = "top"; AgTooltipPositionType2["RIGHT"] = "right"; AgTooltipPositionType2["BOTTOM"] = "bottom"; AgTooltipPositionType2["LEFT"] = "left"; AgTooltipPositionType2["TOP_LEFT"] = "top-left"; AgTooltipPositionType2["TOP_RIGHT"] = "top-right"; AgTooltipPositionType2["BOTTOM_RIGHT"] = "bottom-right"; AgTooltipPositionType2["BOTTOM_LEFT"] = "bottom-left"; return AgTooltipPositionType2; })(AgTooltipPositionType || {}); } }); // packages/ag-charts-types/src/chart/types.ts var init_types2 = __esm({ "packages/ag-charts-types/src/chart/types.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chart/zoomOptions.ts var init_zoomOptions = __esm({ "packages/ag-charts-types/src/chart/zoomOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/chartBuilderOptions.ts var init_chartBuilderOptions = __esm({ "packages/ag-charts-types/src/chartBuilderOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/integratedCharts.ts var init_integratedCharts = __esm({ "packages/ag-charts-types/src/integratedCharts.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/financial/financialOptions.ts var init_financialOptions = __esm({ "packages/ag-charts-types/src/presets/financial/financialOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/financial/priceVolumeOptions.ts var init_priceVolumeOptions = __esm({ "packages/ag-charts-types/src/presets/financial/priceVolumeOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/gauge/commonOptions.ts var __THEMEABLE_OPTIONS, __VERIFY_THEMEABLE_OPTIONS, __AXIS_LABEL_OPTIONS, __VERIFY_AXIS_LABEL_OPTIONS; var init_commonOptions = __esm({ "packages/ag-charts-types/src/presets/gauge/commonOptions.ts"() { "use strict"; __THEMEABLE_OPTIONS = void 0; __VERIFY_THEMEABLE_OPTIONS = void 0; __VERIFY_THEMEABLE_OPTIONS = __THEMEABLE_OPTIONS; __AXIS_LABEL_OPTIONS = void 0; __VERIFY_AXIS_LABEL_OPTIONS = void 0; __VERIFY_AXIS_LABEL_OPTIONS = __AXIS_LABEL_OPTIONS; } }); // packages/ag-charts-types/src/presets/gauge/gaugeOptions.ts var init_gaugeOptions = __esm({ "packages/ag-charts-types/src/presets/gauge/gaugeOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/gauge/linearGaugeOptions.ts var init_linearGaugeOptions = __esm({ "packages/ag-charts-types/src/presets/gauge/linearGaugeOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/gauge/radialGaugeOptions.ts var init_radialGaugeOptions = __esm({ "packages/ag-charts-types/src/presets/gauge/radialGaugeOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/sparkline/sparklineAxisOptions.ts var init_sparklineAxisOptions = __esm({ "packages/ag-charts-types/src/presets/sparkline/sparklineAxisOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/sparkline/sparklineOptions.ts var init_sparklineOptions = __esm({ "packages/ag-charts-types/src/presets/sparkline/sparklineOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/presets/presetOptions.ts var init_presetOptions = __esm({ "packages/ag-charts-types/src/presets/presetOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/areaOptions.ts var init_areaOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/areaOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/barOptions.ts var init_barOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/barOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/boxPlotOptions.ts var init_boxPlotOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/boxPlotOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/bubbleOptions.ts var init_bubbleOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/bubbleOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/candlestickOptions.ts var init_candlestickOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/candlestickOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/cartesianOptions.ts var init_cartesianOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/cartesianOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/cartesianSeriesTooltipOptions.ts var init_cartesianSeriesTooltipOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/cartesianSeriesTooltipOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/cartesianSeriesTypes.ts var init_cartesianSeriesTypes = __esm({ "packages/ag-charts-types/src/series/cartesian/cartesianSeriesTypes.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/commonOptions.ts var init_commonOptions2 = __esm({ "packages/ag-charts-types/src/series/cartesian/commonOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/coneFunnelOptions.ts var init_coneFunnelOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/coneFunnelOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/funnelOptions.ts var init_funnelOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/funnelOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/heatmapOptions.ts var init_heatmapOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/heatmapOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/histogramOptions.ts var init_histogramOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/histogramOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/lineOptions.ts var init_lineOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/lineOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/ohlcBaseOptions.ts var init_ohlcBaseOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/ohlcBaseOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/ohlcOptions.ts var init_ohlcOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/ohlcOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/rangeAreaOptions.ts var init_rangeAreaOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/rangeAreaOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/rangeBarOptions.ts var init_rangeBarOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/rangeBarOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/scatterOptions.ts var init_scatterOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/scatterOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/cartesian/waterfallOptions.ts var init_waterfallOptions = __esm({ "packages/ag-charts-types/src/series/cartesian/waterfallOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/flow-proportion/chordOptions.ts var init_chordOptions = __esm({ "packages/ag-charts-types/src/series/flow-proportion/chordOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/flow-proportion/flowProportionOptions.ts var init_flowProportionOptions = __esm({ "packages/ag-charts-types/src/series/flow-proportion/flowProportionOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/flow-proportion/sankeyOptions.ts var init_sankeyOptions = __esm({ "packages/ag-charts-types/src/series/flow-proportion/sankeyOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/standalone/pyramidOptions.ts var init_pyramidOptions = __esm({ "packages/ag-charts-types/src/series/standalone/pyramidOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/standalone/standaloneOptions.ts var init_standaloneOptions = __esm({ "packages/ag-charts-types/src/series/standalone/standaloneOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/hierarchy/hierarchyOptions.ts var init_hierarchyOptions = __esm({ "packages/ag-charts-types/src/series/hierarchy/hierarchyOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/hierarchy/sunburstOptions.ts var init_sunburstOptions = __esm({ "packages/ag-charts-types/src/series/hierarchy/sunburstOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/hierarchy/treemapOptions.ts var init_treemapOptions = __esm({ "packages/ag-charts-types/src/series/hierarchy/treemapOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/interpolationOptions.ts var init_interpolationOptions = __esm({ "packages/ag-charts-types/src/series/interpolationOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/markerOptions.ts var init_markerOptions = __esm({ "packages/ag-charts-types/src/series/markerOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/donutOptions.ts var init_donutOptions = __esm({ "packages/ag-charts-types/src/series/polar/donutOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/nightingaleOptions.ts var init_nightingaleOptions = __esm({ "packages/ag-charts-types/src/series/polar/nightingaleOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/pieOptions.ts var init_pieOptions = __esm({ "packages/ag-charts-types/src/series/polar/pieOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/polarOptions.ts var init_polarOptions = __esm({ "packages/ag-charts-types/src/series/polar/polarOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/radarAreaOptions.ts var init_radarAreaOptions = __esm({ "packages/ag-charts-types/src/series/polar/radarAreaOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/radarLineOptions.ts var init_radarLineOptions = __esm({ "packages/ag-charts-types/src/series/polar/radarLineOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/radarOptions.ts var init_radarOptions = __esm({ "packages/ag-charts-types/src/series/polar/radarOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/radialBarOptions.ts var init_radialBarOptions = __esm({ "packages/ag-charts-types/src/series/polar/radialBarOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/radialColumnOptions.ts var init_radialColumnOptions = __esm({ "packages/ag-charts-types/src/series/polar/radialColumnOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/polar/radialOptions.ts var init_radialOptions = __esm({ "packages/ag-charts-types/src/series/polar/radialOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/seriesOptions.ts var init_seriesOptions = __esm({ "packages/ag-charts-types/src/series/seriesOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/topology/mapLineBackgroundOptions.ts var init_mapLineBackgroundOptions = __esm({ "packages/ag-charts-types/src/series/topology/mapLineBackgroundOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/topology/mapLineOptions.ts var init_mapLineOptions = __esm({ "packages/ag-charts-types/src/series/topology/mapLineOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/topology/mapMarkerOptions.ts var init_mapMarkerOptions = __esm({ "packages/ag-charts-types/src/series/topology/mapMarkerOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/topology/mapShapeBackgroundOptions.ts var init_mapShapeBackgroundOptions = __esm({ "packages/ag-charts-types/src/series/topology/mapShapeBackgroundOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/topology/mapShapeOptions.ts var init_mapShapeOptions = __esm({ "packages/ag-charts-types/src/series/topology/mapShapeOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/series/topology/topologyOptions.ts var init_topologyOptions = __esm({ "packages/ag-charts-types/src/series/topology/topologyOptions.ts"() { "use strict"; } }); // packages/ag-charts-types/src/main.ts var init_main3 = __esm({ "packages/ag-charts-types/src/main.ts"() { "use strict"; init_initialStateOptions(); init_agCharts(); init_annotationsOptions(); init_axisOptions(); init_callbackOptions(); init_chartOptions(); init_chartToolbarOptions(); init_contextMenuOptions(); init_crossLineOptions(); init_crosshairOptions(); init_dropShadowOptions(); init_errorBarOptions(); init_eventOptions(); init_gradientLegendOptions(); init_icons(); init_labelOptions(); init_legendOptions(); init_localeOptions(); init_navigatorOptions(); init_polarAxisOptions(); init_rangesOptions(); init_themeOptions(); init_tooltipOptions(); init_types2(); init_zoomOptions(); init_chartBuilderOptions(); init_integratedCharts(); init_financialOptions(); init_priceVolumeOptions(); init_commonOptions(); init_gaugeOptions(); init_linearGaugeOptions(); init_radialGaugeOptions(); init_sparklineAxisOptions(); init_sparklineOptions(); init_presetOptions(); init_areaOptions(); init_barOptions(); init_boxPlotOptions(); init_bubbleOptions(); init_candlestickOptions(); init_cartesianOptions(); init_cartesianSeriesTooltipOptions(); init_cartesianSeriesTypes(); init_commonOptions2(); init_coneFunnelOptions(); init_funnelOptions(); init_heatmapOptions(); init_histogramOptions(); init_lineOptions(); init_ohlcBaseOptions(); init_ohlcOptions(); init_rangeAreaOptions(); init_rangeBarOptions(); init_scatterOptions(); init_waterfallOptions(); init_chordOptions(); init_flowProportionOptions(); init_sankeyOptions(); init_pyramidOptions(); init_standaloneOptions(); init_hierarchyOptions(); init_sunburstOptions(); init_treemapOptions(); init_interpolationOptions(); init_markerOptions(); init_donutOptions(); init_nightingaleOptions(); init_pieOptions(); init_polarOptions(); init_radarAreaOptions(); init_radarLineOptions(); init_radarOptions(); init_radialBarOptions(); init_radialColumnOptions(); init_radialOptions(); init_seriesOptions(); init_mapLineBackgroundOptions(); init_mapLineOptions(); init_mapMarkerOptions(); init_mapShapeBackgroundOptions(); init_mapShapeOptions(); init_topologyOptions(); } }); // packages/ag-charts-community/src/api/preset/presetUtils.ts function pickProps(opts, values) { const out = {}; for (const [key, value] of Object.entries(values)) { if (value !== IGNORED_PROP && Object.hasOwn(opts, key)) { out[key] = value; } } return out; } var IGNORED_PROP; var init_presetUtils = __esm({ "packages/ag-charts-community/src/api/preset/presetUtils.ts"() { "use strict"; IGNORED_PROP = Symbol("IGNORED_PROP"); } }); // packages/ag-charts-community/src/api/preset/gauge.ts function pickTooltipProps(tooltip) { if (tooltip === void 0) return void 0; const { enabled, showArrow, range: range4, position, delay, wrapping } = tooltip; const result = { enabled, showArrow, range: range4, position, delay, wrapping }; return Object.fromEntries(Object.entries(result).filter(([_, value]) => value !== void 0)); } function isRadialGauge(opts) { return opts.type === "radial-gauge"; } function isLinearGauge(opts) { return opts.type === "linear-gauge"; } function radialGaugeOptions(opts) { const { animation, background, container, contextMenu, footnote, height: height2, listeners, locale, minHeight, minWidth, overrideDevicePixelRatio, padding, subtitle, theme, title, width: width2, type, cursor, nodeClickRange, tooltip, value, scale: scale2 = {}, startAngle, endAngle, highlightStyle, segmentation, bar, needle, targets, outerRadius, innerRadius, outerRadiusRatio, innerRadiusRatio, cornerRadius, cornerMode, label, secondaryLabel, spacing, ...rest } = opts; const { fills: scaleFills, fillMode: scaleFillMode, fill: scaleFill, fillOpacity: scaleFillOpacity, stroke: scaleStroke, strokeWidth: scaleStrokeWidth, strokeOpacity: scaleStrokeOpacity, lineDash: scaleLineDash, lineDashOffset: scaleLineDashOffset, min: scaleMin = 0, max: scaleMax = 1, interval: scaleInterval = {}, label: scaleLabel = {} } = scale2; const chartOpts = pickProps(opts, { animation, background, container, contextMenu, footnote, height: height2, listeners, locale, minHeight, minWidth, overrideDevicePixelRatio, padding, subtitle, theme, title, tooltip: pickTooltipProps(tooltip), width: width2 }); const scaleOpts = pickProps(scale2, { fills: scaleFills, fillMode: scaleFillMode, fill: scaleFill, fillOpacity: scaleFillOpacity, stroke: scaleStroke, strokeWidth: scaleStrokeWidth, strokeOpacity: scaleStrokeOpacity, lineDash: scaleLineDash, lineDashOffset: scaleLineDashOffset }); const seriesOpts = pickProps(opts, { startAngle: IGNORED_PROP, endAngle: IGNORED_PROP, needle: needle != null ? { enabled: true, ...needle } : IGNORED_PROP, scale: scaleOpts, type, cursor, nodeClickRange, listeners, tooltip, value, highlightStyle, segmentation, bar, targets, outerRadius, innerRadius, outerRadiusRatio, innerRadiusRatio, cornerRadius, cornerMode, label, secondaryLabel, spacing, ...rest }); const axesOpts = [ { type: "angle-number", min: scaleMin, max: scaleMax, startAngle, endAngle, interval: scaleInterval ?? {}, label: scaleLabel ?? {} }, { type: "radius-number" } ]; return { ...chartOpts, series: [seriesOpts], axes: axesOpts }; } function linearGaugeOptions(opts) { const { animation, background, container, contextMenu, footnote, height: height2, listeners, locale, minHeight, minWidth, overrideDevicePixelRatio, padding, subtitle, theme, title, width: width2, type, cursor, nodeClickRange, tooltip, value, scale: scale2 = {}, direction = "vertical", thickness, highlightStyle, segmentation, bar, targets, cornerRadius, cornerMode, label, ...rest } = opts; const { fills: scaleFills, fillMode: scaleFillMode, fill: scaleFill, fillOpacity: scaleFillOpacity, stroke: scaleStroke, strokeWidth: scaleStrokeWidth, strokeOpacity: scaleStrokeOpacity, lineDash: scaleLineDash, lineDashOffset: scaleLineDashOffset, min: scaleMin = 0, max: scaleMax = 1, interval: scaleInterval = {}, label: scaleLabel = {} } = scale2; const chartOpts = pickProps(opts, { animation, background, container, contextMenu, footnote, height: height2, listeners, locale, minHeight, minWidth, overrideDevicePixelRatio, padding, subtitle, theme, title, tooltip: pickTooltipProps(tooltip), width: width2 }); const scaleOpts = pickProps(scale2, { fills: scaleFills, fillMode: scaleFillMode, fill: scaleFill, fillOpacity: scaleFillOpacity, stroke: scaleStroke, strokeWidth: scaleStrokeWidth, strokeOpacity: scaleStrokeOpacity, lineDash: scaleLineDash, lineDashOffset: scaleLineDashOffset }); const seriesOpts = pickProps(opts, { scale: scaleOpts, type, cursor, nodeClickRange, listeners, tooltip, value, direction, thickness, highlightStyle, segmentation, bar, targets, cornerRadius, cornerMode, label, ...rest }); const { placement: labelPlacement, ...axisLabel3 } = scaleLabel; let mainAxisPosition; let crossAxisPosition; const horizontal = direction === "horizontal"; if (horizontal) { mainAxisPosition = labelPlacement === "before" ? "top" : "bottom"; crossAxisPosition = "left"; } else { mainAxisPosition = labelPlacement === "after" ? "right" : "left"; crossAxisPosition = "bottom"; } const mainAxis = { type: "number", position: mainAxisPosition, min: scaleMin, max: scaleMax, reverse: !horizontal, interval: scaleInterval, label: axisLabel3, nice: false }; const crossAxis = { type: "number", position: crossAxisPosition, min: 0, max: 1, label: { enabled: false } }; const axesOpts = horizontal ? [mainAxis, crossAxis] : [crossAxis, mainAxis]; return { ...chartOpts, series: [seriesOpts], axes: axesOpts }; } function applyThemeDefaults(opts, presetTheme) { if (presetTheme == null) return opts; const { targets: targetsTheme, ...gaugeTheme } = presetTheme; opts = mergeDefaults(opts, gaugeTheme); if (opts.targets != null && targetsTheme != null) { opts.targets = mergeArrayDefaults(opts.targets, targetsTheme); } return opts; } function gauge(opts, presetTheme) { if (isRadialGauge(opts)) { const radialGaugeOpts = applyThemeDefaults(opts, presetTheme); return radialGaugeOptions(radialGaugeOpts); } else if (isLinearGauge(opts)) { const linearGaugeOpts = applyThemeDefaults(opts, presetTheme); return linearGaugeOptions(linearGaugeOpts); } const { animation, background, container, contextMenu, footnote, height: height2, listeners, locale, minHeight, minWidth, padding, subtitle, theme, title, tooltip, width: width2 } = opts; return pickProps(opts, { animation, background, container, contextMenu, footnote, height: height2, listeners, locale, minHeight, minWidth, padding, subtitle, theme, title, tooltip, width: width2 }); } var init_gauge = __esm({ "packages/ag-charts-community/src/api/preset/gauge.ts"() { "use strict"; init_main3(); init_object(); init_presetUtils(); } }); // packages/ag-charts-community/src/api/preset/priceVolumePresetTheme.ts var stroke, handle, axisLabel, lineText, font, text, measurerStatistics, measurer, annotationsTheme; var init_priceVolumePresetTheme = __esm({ "packages/ag-charts-community/src/api/preset/priceVolumePresetTheme.ts"() { "use strict"; init_symbols(); stroke = { stroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR }; handle = { fill: DEFAULT_ANNOTATION_HANDLE_FILL }; axisLabel = { color: "white", fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR }; lineText = { color: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR }; font = { color: DEFAULT_TEXT_ANNOTATION_COLOR, fontSize: { $rem: [1.1666666666666667 /* LARGE */] }, fontFamily: { $ref: "fontFamily" } }; text = { ...font, textAlign: "left" }; measurerStatistics = { ...font, fontSize: { $ref: "fontSize" }, color: DEFAULT_ANNOTATION_STATISTICS_COLOR, fill: DEFAULT_ANNOTATION_STATISTICS_FILL, stroke: DEFAULT_ANNOTATION_STATISTICS_STROKE, strokeWidth: 1, divider: { stroke: DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, strokeWidth: 1, strokeOpacity: 0.5 } }; measurer = { ...stroke, background: { fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2 }, handle: { ...handle }, text: { ...lineText }, statistics: { ...measurerStatistics } }; annotationsTheme = { // Lines line: { ...stroke, handle: { ...handle }, text: { ...lineText } }, "horizontal-line": { ...stroke, handle: { ...handle }, axisLabel: { ...axisLabel }, text: { ...lineText } }, "vertical-line": { ...stroke, handle: { ...handle }, axisLabel: { ...axisLabel }, text: { ...lineText } }, // Channels "disjoint-channel": { ...stroke, background: { fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2 }, handle: { ...handle }, text: { ...lineText } }, "parallel-channel": { ...stroke, background: { fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2 }, handle: { ...handle }, text: { ...lineText } }, // Fibonnaccis "fibonacci-retracement": { ...stroke, strokes: DEFAULT_FIBONACCI_STROKES, rangeStroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, handle: { ...handle }, text: { ...lineText, position: "center" }, label: { ...font, color: void 0, fontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 10 / 12] }] } } }, "fibonacci-retracement-trend-based": { ...stroke, strokes: DEFAULT_FIBONACCI_STROKES, rangeStroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, handle: { ...handle }, text: { ...lineText, position: "center" }, label: { ...font, color: void 0, fontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 10 / 12] }] } } }, // Texts callout: { ...stroke, ...text, color: { $ref: "textColor" }, handle: { ...handle }, fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2 }, comment: { ...text, color: "white", fontWeight: 700, handle: { ...handle }, fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR }, note: { ...text, color: DEFAULT_TEXTBOX_COLOR, fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, stroke: { $ref: "backgroundColor" }, strokeWidth: 1, strokeOpacity: 1, handle: { ...handle }, background: { fill: DEFAULT_TEXTBOX_FILL, stroke: DEFAULT_TEXTBOX_STROKE, strokeWidth: 1 } }, text: { ...text, handle: { ...handle } }, // Shapes arrow: { ...stroke, handle: { ...handle }, text: { ...lineText } }, "arrow-up": { fill: PALETTE_UP_FILL, handle: { ...handle, stroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR } }, "arrow-down": { fill: PALETTE_DOWN_FILL, handle: { ...handle, stroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR } }, // Measurers "date-range": { ...measurer }, "price-range": { ...measurer }, "date-price-range": { ...measurer }, "quick-date-price-range": { up: { ...stroke, fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2, handle: { ...handle }, statistics: { ...measurerStatistics, color: "#fff", fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, strokeWidth: 0, divider: { stroke: "#fff", strokeWidth: 1, strokeOpacity: 0.5 } } }, down: { ...stroke, stroke: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, fill: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, fillOpacity: 0.2, handle: { ...handle, stroke: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE }, statistics: { ...measurerStatistics, color: "#fff", fill: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, strokeWidth: 0, divider: { stroke: "#fff", strokeWidth: 1, strokeOpacity: 0.5 } } } } }; } }); // packages/ag-charts-community/src/api/preset/priceVolumePreset.ts function fromTheme(theme, cb) { if (isObject(theme)) { return cb(theme); } } function priceVolume(opts, _presetTheme, getTheme) { const { dateKey = "date", highKey = "high", openKey = "open", lowKey = "low", closeKey = "close", volumeKey = "volume", chartType = "candlestick", navigator = false, volume = true, rangeButtons = true, statusBar = true, toolbar: toolbar2 = true, zoom = true, theme, data, ...unusedOpts } = opts; const priceSeries = createPriceSeries(theme, chartType, dateKey, highKey, lowKey, openKey, closeKey); const volumeSeries = createVolumeSeries(theme, getTheme, openKey, closeKey, volume, volumeKey); const miniChart = volume ? { miniChart: { enabled: navigator, series: [ { type: "line", xKey: dateKey, yKey: volumeKey, marker: { enabled: false } } ] }, height: 40, minHandle: { height: 46 }, maxHandle: { height: 46 } } : null; const navigatorOpts = { navigator: { enabled: navigator, ...miniChart } }; const axesButtonsEnabled = typeof theme === "string" ? true : theme?.overrides?.common?.annotations?.axesButtons?.enabled ?? true; const annotationOpts = { annotations: { enabled: toolbar2, optionsToolbar: { enabled: toolbar2 }, snap: true, axesButtons: { enabled: axesButtonsEnabled }, toolbar: { enabled: toolbar2, buttons: toolbarButtons, // @ts-expect-error undocumented option padding: 0 }, data, xKey: dateKey, volumeKey: volume ? volumeKey : void 0 } }; const statusBarOpts = statusBar ? { statusBar: { enabled: true, data, highKey, openKey, lowKey, closeKey, volumeKey: volume ? volumeKey : void 0 } } : null; const zoomOpts = { zoom: { enabled: zoom, autoScaling: { enabled: true }, // @ts-expect-error undocumented option enableIndependentAxes: true } }; const toolbarOpts = { ranges: { enabled: rangeButtons } }; const volumeAxis = volume ? [ { type: "number", position: "left", keys: [volumeKey], label: { enabled: false }, crosshair: { enabled: false }, gridLine: { enabled: false }, nice: false, // @ts-expect-error undocumented option layoutConstraints: { stacked: false, width: 20, unit: "percentage", align: "end" } } ] : []; return { theme: { baseTheme: typeof theme === "string" ? theme : "ag-financial", ...mergeDefaults(typeof theme === "object" ? theme : null, { overrides: { common: { title: { padding: 4 }, padding: { top: 6, right: 8, bottom: 5 }, chartToolbar: { enabled: toolbar2 }, annotations: { ...annotationsTheme } } } }) }, animation: { enabled: false }, legend: { enabled: false }, series: [...volumeSeries, ...priceSeries], axes: [ { type: "number", position: "right", keys: [openKey, closeKey, highKey, lowKey], interval: { maxSpacing: fromTheme(theme, (t) => t.overrides?.common?.axes?.number?.interval?.maxSpacing) ?? 45 }, label: { format: fromTheme(theme, (t) => t.overrides?.common?.axes?.number?.label?.format) ?? ".2f" }, crosshair: { enabled: true, snap: false }, // @ts-expect-error undocumented option layoutConstraints: { stacked: false, width: 100, unit: "percentage", align: "start" } }, ...volumeAxis, { type: "ordinal-time", position: "bottom", line: { enabled: false }, label: { enabled: true }, crosshair: { enabled: true } } ], tooltip: { enabled: false }, data, ...annotationOpts, ...navigatorOpts, ...statusBarOpts, ...zoomOpts, ...toolbarOpts, ...unusedOpts }; } function createVolumeSeries(theme, getTheme, openKey, closeKey, volume, volumeKey) { if (!volume) return []; const barSeriesFill = fromTheme(theme, (t) => t.overrides?.bar?.series?.fill); const itemStyler = barSeriesFill ? { fill: barSeriesFill } : { itemStyler({ datum }) { const { up, down } = getTheme().palette; return { fill: datum[openKey] < datum[closeKey] ? up?.fill : down?.fill }; } }; return [ { type: "bar", xKey: "date", yKey: volumeKey, tooltip: { enabled: false }, highlight: { enabled: false }, fillOpacity: fromTheme(theme, (t) => t.overrides?.bar?.series?.fillOpacity) ?? 0.5, ...itemStyler, // @ts-expect-error undocumented option focusPriority: 1, fastDataProcessing: true } ]; } function createPriceSeries(theme, chartType, xKey, highKey, lowKey, openKey, closeKey) { const keys = { xKey, openKey, closeKey, highKey, lowKey }; const singleKeys = { xKey, yKey: closeKey }; const common = { pickOutsideVisibleMinorAxis: true }; switch (chartType ?? "candlestick") { case "ohlc": return createPriceSeriesOHLC(common, keys); case "line": return createPriceSeriesLine(common, theme, singleKeys); case "step-line": return createPriceSeriesStepLine(common, theme, singleKeys); case "hlc": return createPriceSeriesHLC(common, theme, singleKeys, keys); case "high-low": return createPriceSeriesHighLow(common, theme, keys); case "candlestick": return createPriceSeriesCandlestick(common, keys); case "hollow-candlestick": return createPriceSeriesHollowCandlestick(common, theme, keys); default: logger_exports.warnOnce(`unknown chart type: ${chartType}; expected one of: ${chartTypes3.join(", ")}`); return createPriceSeriesCandlestick(common, keys); } } function createPriceSeriesOHLC(common, keys) { return [ { type: "ohlc", // @ts-expect-error undocumented option focusPriority: 0, ...common, ...keys } ]; } function createPriceSeriesLine(common, theme, singleKeys) { return [ { type: "line", // @ts-expect-error undocumented option focusPriority: 0, ...common, ...singleKeys, stroke: fromTheme(theme, (t) => t.overrides?.line?.series?.stroke) ?? PALETTE_NEUTRAL_STROKE, marker: fromTheme(theme, (t) => t.overrides?.line?.series?.marker) ?? { enabled: false } } ]; } function createPriceSeriesStepLine(common, theme, singleKeys) { return [ { type: "line", // @ts-expect-error undocumented option focusPriority: 0, ...common, ...singleKeys, stroke: fromTheme(theme, (t) => t.overrides?.line?.series?.stroke) ?? PALETTE_NEUTRAL_STROKE, interpolation: fromTheme(theme, (t) => t.overrides?.line?.series?.interpolation) ?? { type: "step" }, marker: fromTheme(theme, (t) => t.overrides?.line?.series?.marker) ?? { enabled: false } } ]; } function createPriceSeriesHLC(common, theme, singleKeys, { xKey, highKey, closeKey, lowKey }) { const rangeAreaColors = getThemeColors(RANGE_AREA_TYPE, theme); return [ { type: RANGE_AREA_TYPE, // @ts-expect-error undocumented option focusPriority: 0, ...common, xKey, yHighKey: highKey, yLowKey: closeKey, fill: rangeAreaColors.fill ?? PALETTE_UP_FILL, stroke: rangeAreaColors.stroke ?? PALETTE_UP_STROKE, fillOpacity: fromTheme(theme, (t) => t.overrides?.["range-area"]?.series?.fillOpacity) ?? 0.3, strokeWidth: fromTheme(theme, (t) => t.overrides?.["range-area"]?.series?.strokeWidth) ?? 2 }, { type: RANGE_AREA_TYPE, // @ts-expect-error undocumented option focusPriority: 0, ...common, xKey, yHighKey: closeKey, yLowKey: lowKey, fill: rangeAreaColors.fill ?? PALETTE_DOWN_FILL, stroke: rangeAreaColors.stroke ?? PALETTE_DOWN_STROKE, fillOpacity: fromTheme(theme, (t) => t.overrides?.["range-area"]?.series?.fillOpacity) ?? 0.3, strokeWidth: fromTheme(theme, (t) => t.overrides?.["range-area"]?.series?.strokeWidth) ?? 2 }, { type: "line", ...common, ...singleKeys, stroke: fromTheme(theme, (t) => t.overrides?.line?.series?.stroke) ?? PALETTE_ALT_NEUTRAL_STROKE, strokeWidth: fromTheme(theme, (t) => t.overrides?.line?.series?.strokeWidth) ?? 2, marker: fromTheme(theme, (t) => t.overrides?.line?.series?.marker) ?? { enabled: false } } ]; } function createPriceSeriesHighLow(common, theme, { xKey, highKey, lowKey }) { const rangeBarColors = getThemeColors("range-bar", theme); return [ { type: "range-bar", ...common, xKey, yHighKey: highKey, yLowKey: lowKey, fill: rangeBarColors.fill ?? PALETTE_NEUTRAL_FILL, stroke: rangeBarColors.stroke ?? PALETTE_NEUTRAL_STROKE, tooltip: { range: "nearest" }, // @ts-expect-error undocumented option focusPriority: 0, fastDataProcessing: true } ]; } function createPriceSeriesCandlestick(common, keys) { return [ { type: "candlestick", // @ts-expect-error undocumented option focusPriority: 0, ...common, ...keys } ]; } function createPriceSeriesHollowCandlestick(common, theme, keys) { const item = fromTheme(theme, (t) => t.overrides?.candlestick?.series?.item); return [ { type: "candlestick", // @ts-expect-error undocumented option focusPriority: 0, ...common, ...keys, item: { up: { fill: item?.up?.fill ?? "transparent" } } } ]; } function getThemeColors(seriesType, theme) { const fill = fromTheme(theme, (t) => t.overrides?.[seriesType]?.series?.fill); const stroke3 = fromTheme(theme, (t) => t.overrides?.[seriesType]?.series?.stroke); return { fill, stroke: stroke3 }; } var chartTypes3, toolbarButtons, RANGE_AREA_TYPE; var init_priceVolumePreset = __esm({ "packages/ag-charts-community/src/api/preset/priceVolumePreset.ts"() { "use strict"; init_main(); init_symbols(); init_object(); init_priceVolumePresetTheme(); chartTypes3 = ["ohlc", "line", "step-line", "hlc", "high-low", "candlestick", "hollow-candlestick"]; toolbarButtons = [ { icon: "trend-line-drawing", tooltip: "toolbarAnnotationsLineAnnotations", value: "line-menu" }, { icon: "fibonacci-retracement-drawing", tooltip: "toolbarAnnotationsFibonacciAnnotations", value: "fibonacci-menu" }, { icon: "text-annotation", tooltip: "toolbarAnnotationsTextAnnotations", value: "text-menu" }, { icon: "arrow-drawing", tooltip: "toolbarAnnotationsShapeAnnotations", value: "shape-menu" }, { icon: "measurer-drawing", tooltip: "toolbarAnnotationsMeasurerAnnotations", value: "measurer-menu" }, { icon: "delete", tooltip: "toolbarAnnotationsClearAll", value: "clear" } ]; RANGE_AREA_TYPE = "range-area"; } }); // packages/ag-charts-community/src/api/preset/sparkline.ts function createInitialBaseTheme(baseTheme, initialBaseTheme) { if (typeof baseTheme === "string") { return { ...initialBaseTheme, baseTheme }; } if (baseTheme != null) { return { ...baseTheme, // @ts-expect-error internal implementation baseTheme: setInitialBaseTheme(baseTheme.baseTheme, initialBaseTheme) }; } return initialBaseTheme; } function sparklineDataPreset(data) { if (Array.isArray(data) && data.length !== 0) { const firstItem = data[0]; if (typeof firstItem === "number") { const mappedData = data.map((y, x) => ({ x, y })); return { data: mappedData, series: [{ xKey: "x", yKey: "y" }], datumKey: "y" }; } else if (Array.isArray(firstItem)) { const mappedData = data.map((datum) => ({ x: datum[0], y: datum[1], datum })); return { data: mappedData, series: [{ xKey: "x", yKey: "y" }], datumKey: "datum" }; } } return { data }; } function axisPreset(opts, defaultType) { switch (opts?.type) { case "number": { const { type, min, max, reverse } = opts; return pickProps(opts, { type, reverse, min, max }); } case "time": { const { type, min, max, reverse } = opts; return pickProps(opts, { type, reverse, min, max }); } case "category": { const { type, paddingInner, paddingOuter, reverse } = opts; return pickProps(opts, { type, reverse, paddingInner, paddingOuter }); } } return { type: defaultType }; } function gridLinePreset(opts, defaultEnabled, sparkOpts) { const gridLineOpts = {}; if (opts?.stroke != null) { gridLineOpts.style = [{ stroke: opts?.stroke }]; gridLineOpts.enabled ?? (gridLineOpts.enabled = true); } if (opts?.strokeWidth != null) { gridLineOpts.width = opts?.strokeWidth; gridLineOpts.enabled ?? (gridLineOpts.enabled = true); } if (sparkOpts.type === "bar" && sparkOpts.direction !== "horizontal") { gridLineOpts.enabled ?? (gridLineOpts.enabled = true); } if (opts?.visible != null) { gridLineOpts.enabled = opts.visible; } gridLineOpts.enabled ?? (gridLineOpts.enabled = defaultEnabled); return gridLineOpts; } function sparkline(opts) { const { background, container, height: height2, listeners, locale, minHeight, minWidth, overrideDevicePixelRatio, padding, width: width2, theme: baseTheme, data: baseData, crosshair, axis, min, max, tooltip, context, ...optsRest } = opts; const chartOpts = pickProps(opts, { background, container, height: height2, listeners, locale, minHeight, minWidth, overrideDevicePixelRatio, padding, width: width2, tooltip: IGNORED_PROP, context: IGNORED_PROP, data: IGNORED_PROP, crosshair: IGNORED_PROP, axis: IGNORED_PROP, min: IGNORED_PROP, max: IGNORED_PROP, theme: IGNORED_PROP }); const { data, series: [seriesOverrides] = [], datumKey } = sparklineDataPreset(baseData); const seriesOptions = optsRest; if (seriesOverrides != null) Object.assign(seriesOptions, seriesOverrides); seriesOptions.tooltip = { ...tooltip, renderer: tooltipRendererFn(context, tooltip, datumKey) }; chartOpts.theme = setInitialBaseTheme(baseTheme, SPARKLINE_THEME); chartOpts.data = data; chartOpts.series = [seriesOptions]; const swapAxes = seriesOptions.type !== "bar" || seriesOptions.direction !== "horizontal"; const [xAxisPosition, yAxisPosition] = swapAxes ? ["bottom", "left"] : ["left", "bottom"]; const xAxis = { ...axisPreset(axis, "category"), position: xAxisPosition, ...pickProps(opts, { crosshair }) }; const yAxis = { type: "number", gridLine: gridLinePreset(axis, false, opts), position: yAxisPosition, ...pickProps(opts, { min, max }) }; chartOpts.axes = swapAxes ? [yAxis, xAxis] : [xAxis, yAxis]; return chartOpts; } var commonAxisProperties, numericAxisProperties, tooltipDefaults, barGridLineDefaults, barAxisDefaults, SPARKLINE_THEME, setInitialBaseTheme, tooltipRendererFn; var init_sparkline = __esm({ "packages/ag-charts-community/src/api/preset/sparkline.ts"() { "use strict"; init_main3(); init_symbols(); init_memo(); init_presetUtils(); commonAxisProperties = { title: { enabled: false }, label: { enabled: false }, line: { enabled: false }, gridLine: { enabled: false }, crosshair: { enabled: false, stroke: DEFAULT_SPARKLINE_CROSSHAIR_STROKE, lineDash: [0], label: { enabled: false } } }; numericAxisProperties = { ...commonAxisProperties, nice: false }; tooltipDefaults = { position: { type: "sparkline" } }; barGridLineDefaults = { style: [{ stroke: { $ref: "gridLineColor" } }], width: 2 }; barAxisDefaults = { number: { gridLine: barGridLineDefaults }, time: { gridLine: barGridLineDefaults }, category: { gridLine: barGridLineDefaults } }; SPARKLINE_THEME = { overrides: { common: { animation: { enabled: false }, contextMenu: { enabled: false }, keyboard: { enabled: false }, background: { visible: false }, padding: { top: 0, right: 0, bottom: 0, left: 0 }, axes: { number: { ...numericAxisProperties, interval: { values: [0] } }, log: { ...numericAxisProperties }, time: { ...numericAxisProperties }, category: { ...commonAxisProperties } } }, bar: { series: { crisp: false, label: { placement: "inside-end", padding: 4 }, // @ts-expect-error undocumented option sparklineMode: true }, tooltip: { ...tooltipDefaults, range: "nearest" }, axes: barAxisDefaults }, line: { seriesArea: { padding: { top: 2, right: 2, bottom: 2, left: 2 } }, series: { // @ts-expect-error undocumented option sparklineMode: true, strokeWidth: 1, marker: { enabled: false, size: 3 }, tooltip: tooltipDefaults } }, area: { seriesArea: { padding: { top: 1, right: 0, bottom: 1, left: 0 } }, series: { strokeWidth: 1, fillOpacity: 0.4, tooltip: tooltipDefaults } } } }; setInitialBaseTheme = simpleMemorize(createInitialBaseTheme); tooltipRendererFn = simpleMemorize((context, tooltip, datumKey) => { return (params) => { const xValue = params.datum[params.xKey]; const yValue = params.datum[params.yKey]; const datum = datumKey != null ? params.datum[datumKey] : params.datum; const userContent = tooltip?.renderer?.({ context, datum, xValue, yValue }); if (typeof userContent === "string") return userContent; const title = userContent?.title; const content = userContent?.content; return title != null && content != null ? { heading: title, title: void 0, // Undocumented 'compact' tooltip mode data: [{ label: void 0, value: content }] } : { heading: title ?? content ?? yValue.toFixed(2), title: void 0, data: [] }; }; }); } }); // packages/ag-charts-community/src/api/preset/presets.ts var PRESETS, PRESET_DATA_PROCESSORS; var init_presets = __esm({ "packages/ag-charts-community/src/api/preset/presets.ts"() { "use strict"; init_gauge(); init_priceVolumePreset(); init_sparkline(); PRESETS = { "price-volume": priceVolume, gauge, sparkline }; PRESET_DATA_PROCESSORS = { sparkline: sparklineDataPreset }; } }); // packages/ag-charts-community/src/chart/factory/processEnterpriseOptions.ts function removeUsedEnterpriseOptions(options, silent) { let usedOptions = []; const isGaugeChart = isAgGaugeChartOptions(options); const optsType = optionsType(options); const optionsChartType = optsType ? chartTypes2.get(optsType) : "unknown"; for (const module2 of EXPECTED_ENTERPRISE_MODULES) { if (optionsChartType !== "unknown" && !module2.chartTypes.includes(optionsChartType)) continue; if (module2.type === "root" || module2.type === "legend") { const optionValue = options[module2.optionsKey]; if (optionValue == null) continue; if (!module2.optionsInnerKey) { usedOptions.push(module2.optionsKey); delete options[module2.optionsKey]; } else if (optionValue[module2.optionsInnerKey]) { usedOptions.push(`${module2.optionsKey}.${module2.optionsInnerKey}`); delete optionValue[module2.optionsInnerKey]; } } else if (module2.type === "axis") { if (!("axes" in options) || !options.axes?.some((axis) => axis.type === module2.identifier)) continue; usedOptions.push(`axis[type=${module2.identifier}]`); options.axes = options.axes.filter((axis) => axis.type !== module2.identifier); } else if (module2.type === "axis-option") { if (!("axes" in options) || !options.axes?.some((axis) => axis[module2.optionsKey])) continue; usedOptions.push(`axis.${module2.optionsKey}`); options.axes.forEach((axis) => { if (axis[module2.optionsKey]) { delete axis[module2.optionsKey]; } }); } else if (module2.type === "series") { if (module2.community) continue; if (!options.series?.some((series) => series.type === module2.identifier)) continue; usedOptions.push(`series[type=${module2.identifier}]`); options.series = options.series.filter((series) => series.type !== module2.identifier); } else if (module2.type === "series-option") { if (!options.series?.some((series) => series[module2.optionsKey])) continue; usedOptions.push(`series.${module2.optionsKey}`); options.series.forEach((series) => { if (series[module2.optionsKey]) { delete series[module2.optionsKey]; } }); } } if (usedOptions.length && !silent) { if (isGaugeChart) { usedOptions = ["AgCharts.createGauge"]; } let enterprisePackageName = "ag-charts-enterprise"; let enterpriseReferenceUrl = "https://www.ag-grid.com/charts/javascript/installation/"; if (options.mode === "integrated") { enterprisePackageName = "ag-grid-charts-enterprise' or 'ag-grid-enterprise/charts-enterprise"; enterpriseReferenceUrl = "https://www.ag-grid.com/javascript-data-grid/integrated-charts-installation/"; } logger_exports.warnOnce( [ `unable to use these enterprise features as '${enterprisePackageName}' has not been loaded:`, "", ...usedOptions, "", `See: ${enterpriseReferenceUrl}` ].join("\n") ); } } function removeUnusedEnterpriseOptions(options) { const integratedMode = "mode" in options && options.mode === "integrated"; for (const module2 of moduleRegistry.byType("root", "legend")) { const moduleOptions = options[module2.optionsKey]; const isPresentAndDisabled = moduleOptions != null && moduleOptions.enabled === false; const removable = !("removable" in module2) || module2.removable === true || module2.removable === "standalone-only" && !integratedMode; if (isPresentAndDisabled && removable) { delete options[module2.optionsKey]; } } } var init_processEnterpriseOptions = __esm({ "packages/ag-charts-community/src/chart/factory/processEnterpriseOptions.ts"() { "use strict"; init_main(); init_module(); init_types(); init_chartTypes(); init_expectedEnterpriseModules(); } }); // packages/ag-charts-community/src/module/coreModulesTypes.ts function paletteType(partial) { if (partial?.up || partial?.down || partial?.neutral) { return "user-full"; } else if (partial?.fills || partial?.strokes) { return "user-indexed"; } return "inbuilt"; } var init_coreModulesTypes = __esm({ "packages/ag-charts-community/src/module/coreModulesTypes.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/themes/chartTheme.ts function isPresetOverridesType(type) { return PRESET_OVERRIDES_TYPES[type] === true; } var DEFAULT_BACKGROUND_FILL, CHART_TYPE_CONFIG, PRESET_OVERRIDES_TYPES, CHART_TYPE_SPECIFIC_COMMON_OPTIONS, _ChartTheme, ChartTheme; var init_chartTheme = __esm({ "packages/ag-charts-community/src/chart/themes/chartTheme.ts"() { "use strict"; init_main(); init_coreModulesTypes(); init_enterpriseModule(); init_json(); init_object(); init_axisRegistry(); init_chartTypes(); init_legendRegistry(); init_seriesRegistry(); init_defaultColors(); init_symbols(); DEFAULT_BACKGROUND_FILL = "white"; CHART_TYPE_CONFIG = { get cartesian() { return { seriesTypes: chartTypes2.cartesianTypes, commonOptions: ["zoom", "navigator"] }; }, get polar() { return { seriesTypes: chartTypes2.polarTypes, commonOptions: [] }; }, get hierarchy() { return { seriesTypes: chartTypes2.hierarchyTypes, commonOptions: [] }; }, get topology() { return { seriesTypes: chartTypes2.topologyTypes, commonOptions: [] }; }, get "flow-proportion"() { return { seriesTypes: chartTypes2.flowProportionTypes, commonOptions: [] }; }, get standalone() { return { seriesTypes: chartTypes2.standaloneTypes, commonOptions: [] }; }, get gauge() { return { seriesTypes: chartTypes2.gaugeTypes, commonOptions: [] }; } }; PRESET_OVERRIDES_TYPES = { "radial-gauge": true, "linear-gauge": true }; CHART_TYPE_SPECIFIC_COMMON_OPTIONS = Object.values(CHART_TYPE_CONFIG).reduce((r, { commonOptions }) => r.concat(commonOptions), []); _ChartTheme = class _ChartTheme { static getAxisDefaults(overrideDefaults) { return mergeDefaults(overrideDefaults, { title: { enabled: false, text: "Axis Title", spacing: 25, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [1.0833333333333333 /* MEDIUM */] }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "textColor" } }, label: { fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, spacing: 11, color: { $ref: "textColor" }, avoidCollisions: true }, line: { enabled: true, width: 1, stroke: { $ref: "axisColor" } }, tick: { enabled: false, width: 1, stroke: { $ref: "axisColor" } }, gridLine: { enabled: true, style: [{ stroke: { $ref: "gridLineColor" }, lineDash: [] }] }, crossLines: { enabled: false, fill: { $ref: "foregroundColor" }, stroke: { $ref: "foregroundColor" }, fillOpacity: 0.1, strokeWidth: 1, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, padding: 5, color: { $ref: "textColor" } } }, crosshair: { enabled: true } }); } getChartDefaults() { return { minHeight: 300, minWidth: 300, background: { visible: true, fill: { $ref: "backgroundColor" } }, padding: { top: { $ref: "padding" }, right: { $ref: "padding" }, bottom: { $ref: "padding" }, left: { $ref: "padding" } }, seriesArea: { padding: { top: 0, right: 0, bottom: 0, left: 0 } }, keyboard: { enabled: true }, title: { enabled: false, text: "Title", fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [1.4166666666666667 /* LARGEST */] }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "textColor" }, wrapping: "hyphenate", layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE, textAlign: DEFAULT_CAPTION_ALIGNMENT }, subtitle: { enabled: false, text: "Subtitle", spacing: 20, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [1.0833333333333333 /* MEDIUM */] }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "subtleTextColor" }, wrapping: "hyphenate", layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE, textAlign: DEFAULT_CAPTION_ALIGNMENT }, footnote: { enabled: false, text: "Footnote", spacing: 20, fontSize: { $rem: [1.0833333333333333 /* MEDIUM */] }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "subtleTextColor" }, wrapping: "hyphenate", layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE, textAlign: DEFAULT_CAPTION_ALIGNMENT }, legend: { position: "bottom" /* BOTTOM */, spacing: 30, listeners: {}, toggleSeries: true, item: { paddingX: 16, paddingY: 8, marker: { size: 15, padding: 8 }, showSeriesStroke: true, label: { color: { $ref: "textColor" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" } } }, reverseOrder: false, pagination: { marker: { size: 12 }, activeStyle: { fill: { $ref: "foregroundColor" } }, inactiveStyle: { fill: { $ref: "subtleTextColor" } }, highlightStyle: { fill: { $ref: "foregroundColor" } }, label: { color: { $ref: "textColor" } } } }, tooltip: { enabled: true, darkTheme: IS_DARK_THEME, delay: 0 }, overlays: { darkTheme: IS_DARK_THEME }, listeners: {} }; } constructor(options = {}) { const { overrides, palette } = deepClone(options); const defaults = this.createChartConfigPerChartType(this.getDefaults()); const presets = {}; if (overrides) { this.mergeOverrides(defaults, presets, overrides); } const { fills, strokes, ...otherColors } = this.getDefaultColors(); this.palette = deepFreeze( mergeDefaults(palette, { fills: Object.values(fills), strokes: Object.values(strokes), ...otherColors }) ); this.paletteType = paletteType(palette); this.config = deepFreeze(this.templateTheme(defaults)); this.presets = deepFreeze(presets); } mergeOverrides(defaults, presets, overrides) { for (const { seriesTypes, commonOptions } of Object.values(CHART_TYPE_CONFIG)) { const cleanedCommon = { ...overrides.common }; for (const commonKey of CHART_TYPE_SPECIFIC_COMMON_OPTIONS) { if (!commonOptions.includes(commonKey)) { delete cleanedCommon[commonKey]; } } if (!cleanedCommon) continue; for (const s of seriesTypes) { const seriesType = s; if (!isPresetOverridesType(seriesType)) { defaults[seriesType] = mergeDefaults(cleanedCommon, defaults[seriesType]); } } } chartTypes2.seriesTypes.forEach((s) => { const seriesType = s; const seriesOverrides = overrides[seriesType]; if (isPresetOverridesType(seriesType)) { presets[seriesType] = seriesOverrides; } else { defaults[seriesType] = mergeDefaults(seriesOverrides, defaults[seriesType]); } }); } createChartConfigPerChartType(config) { for (const [nextType, { seriesTypes }] of Object.entries(CHART_TYPE_CONFIG)) { const typeDefaults = chartDefaults.get(nextType); for (const seriesType of seriesTypes) { config[seriesType] ?? (config[seriesType] = deepClone(typeDefaults)); } } return config; } getDefaults() { const getOverridesByType = (chartType, seriesTypes) => { const result = {}; const chartTypeDefaults = { axes: {}, ...legendRegistry.getThemeTemplates(), ...this.getChartDefaults(), ...chartDefaults.get(chartType) }; for (const seriesType of seriesTypes) { result[seriesType] = mergeDefaults( seriesRegistry.getThemeTemplate(seriesType), result[seriesType] ?? deepClone(chartTypeDefaults) ); const { axes } = result[seriesType]; for (const axisType of axisRegistry.keys()) { axes[axisType] = mergeDefaults( axes[axisType], axisRegistry.getThemeTemplate(axisType), _ChartTheme.cartesianAxisDefault[axisType] ); } } return result; }; return mergeDefaults( getOverridesByType("cartesian", chartTypes2.cartesianTypes), getOverridesByType("polar", chartTypes2.polarTypes), getOverridesByType("hierarchy", chartTypes2.hierarchyTypes), getOverridesByType("topology", chartTypes2.topologyTypes), getOverridesByType("flow-proportion", chartTypes2.flowProportionTypes), getOverridesByType("standalone", chartTypes2.standaloneTypes), getOverridesByType("gauge", chartTypes2.gaugeTypes) ); } static applyTemplateTheme(node, _other, params) { if (isArray(node)) { for (let i = 0; i < node.length; i++) { const symbol = node[i]; if (typeof symbol === "symbol" && params?.has(symbol)) { node[i] = params.get(symbol); } } } else { for (const [name, value] of Object.entries(node)) { if (typeof value === "symbol" && params?.has(value)) { node[name] = params.get(value); } } } } templateTheme(themeTemplate, clone2 = true) { const themeInstance = clone2 ? deepClone(themeTemplate) : themeTemplate; const params = this.getTemplateParameters(); jsonWalk(themeInstance, _ChartTheme.applyTemplateTheme, void 0, void 0, params); return themeInstance; } getDefaultColors() { return { fills: DEFAULT_FILLS, strokes: DEFAULT_STROKES, up: { fill: DEFAULT_FILLS.GREEN, stroke: DEFAULT_STROKES.GREEN }, down: { fill: DEFAULT_FILLS.RED, stroke: DEFAULT_STROKES.RED }, neutral: { fill: DEFAULT_FILLS.GRAY, stroke: DEFAULT_STROKES.GRAY }, altUp: { fill: DEFAULT_FILLS.BLUE, stroke: DEFAULT_STROKES.BLUE }, altDown: { fill: DEFAULT_FILLS.ORANGE, stroke: DEFAULT_STROKES.ORANGE }, altNeutral: { fill: DEFAULT_FILLS.GRAY, stroke: DEFAULT_STROKES.GRAY } }; } getPublicParameters() { return { accentColor: "#2196f3", axisColor: { $foregroundBackgroundMix: [0.675] }, backgroundColor: DEFAULT_BACKGROUND_FILL, borderColor: { $foregroundBackgroundMix: [0.818] }, foregroundColor: "#464646", fontFamily: "Verdana, sans-serif", fontSize: 12 /* SMALL */, fontWeight: 400, gridLineColor: { $foregroundBackgroundAccentMix: [0.93, 0.085] }, padding: 20, subtleTextColor: { $mix: [{ $ref: "textColor" }, { $ref: "backgroundColor" }, 0.38] }, textColor: { $ref: "foregroundColor" }, chromeBackgroundColor: { $foregroundBackgroundMix: [0.975] }, chromeFontFamily: { $ref: "fontFamily" }, chromeFontSize: { $ref: "fontSize" }, chromeFontWeight: { $ref: "fontWeight" }, chromeTextColor: "#181d1f", chromeSubtleTextColor: { $mix: [{ $ref: "chromeTextColor" }, { $ref: "backgroundColor" }, 0.38] }, inputBackgroundColor: { $ref: "backgroundColor" }, inputTextColor: { $ref: "textColor" }, crosshairLabelBackgroundColor: { $ref: "foregroundColor" }, crosshairLabelTextColor: { $ref: "backgroundColor" } }; } // Private parameters that are not exposed in the themes API. getTemplateParameters() { const { isEnterprise } = enterpriseModule; const params = /* @__PURE__ */ new Map(); params.set(IS_DARK_THEME, false); params.set(IS_ENTERPRISE, isEnterprise); params.set(IS_COMMUNITY, !isEnterprise); params.set(DEFAULT_SEPARATION_LINES_COLOUR, "#d9d9d9"); params.set(DEFAULT_BACKGROUND_COLOUR, DEFAULT_BACKGROUND_FILL); params.set(DEFAULT_SHADOW_COLOUR, "#00000080"); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ DEFAULT_FILLS.ORANGE, DEFAULT_FILLS.YELLOW, DEFAULT_FILLS.GREEN ]); params.set(DEFAULT_COLOR_RANGE, [DEFAULT_FILLS.BLUE, DEFAULT_FILLS.RED]); params.set(DEFAULT_SPARKLINE_CROSSHAIR_STROKE, "#aaa"); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [DEFAULT_FILLS.GREEN, DEFAULT_FILLS.YELLOW, DEFAULT_FILLS.RED]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ "#5090dc", "#629be0", "#73a6e3", "#85b1e7", "#96bcea", "#a8c8ee", "#b9d3f1", "#cbdef5" ]); params.set(DEFAULT_CAPTION_LAYOUT_STYLE, "block"); params.set(DEFAULT_CAPTION_ALIGNMENT, "center"); params.set(DEFAULT_HIERARCHY_FILLS, ["#fff", "#e0e5ea", "#c1ccd5", "#a3b4c1", "#859cad"]); params.set(DEFAULT_HIERARCHY_STROKES, ["#fff", "#c5cbd1", "#a4b1bd", "#8498a9", "#648096"]); params.set(DEFAULT_FIBONACCI_STROKES, [ "#797b86", "#e24c4a", "#f49d2d", "#65ab58", "#409682", "#4db9d2", "#5090dc", "#3068f9", "#e24c4a", "#913aac", "#d93e64" ]); params.set(DEFAULT_POLAR_SERIES_STROKE, DEFAULT_BACKGROUND_FILL); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_FILLS.BLUE); params.set(DEFAULT_TEXT_ANNOTATION_COLOR, DEFAULT_FILLS.BLUE); params.set(DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_BACKGROUND_FILL); params.set(DEFAULT_ANNOTATION_STATISTICS_FILL, "#fafafa"); params.set(DEFAULT_ANNOTATION_STATISTICS_STROKE, "#ddd"); params.set(DEFAULT_ANNOTATION_STATISTICS_COLOR, "#000"); params.set(DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, "#181d1f"); params.set(DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, "#e35c5c"); params.set(DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, "#e35c5c"); params.set(DEFAULT_TEXTBOX_FILL, "#fafafa"); params.set(DEFAULT_TEXTBOX_STROKE, "#ddd"); params.set(DEFAULT_TEXTBOX_COLOR, "#000"); params.set(DEFAULT_TOOLBAR_POSITION, "top"); params.set(DEFAULT_GRIDLINE_ENABLED, false); const defaultColors = this.getDefaultColors(); params.set(PALETTE_UP_STROKE, this.palette.up?.stroke ?? defaultColors.up.stroke); params.set(PALETTE_UP_FILL, this.palette.up?.fill ?? defaultColors.up.fill); params.set(PALETTE_DOWN_STROKE, this.palette.down?.stroke ?? defaultColors.down.stroke); params.set(PALETTE_DOWN_FILL, this.palette.down?.fill ?? defaultColors.down.fill); params.set(PALETTE_NEUTRAL_STROKE, this.palette.neutral?.stroke ?? defaultColors.neutral.stroke); params.set(PALETTE_NEUTRAL_FILL, this.palette.neutral?.fill ?? defaultColors.neutral.fill); params.set(PALETTE_ALT_UP_STROKE, this.palette.altUp?.stroke ?? defaultColors.up.stroke); params.set(PALETTE_ALT_UP_FILL, this.palette.altUp?.fill ?? defaultColors.up.fill); params.set(PALETTE_ALT_DOWN_STROKE, this.palette.altDown?.stroke ?? defaultColors.down.stroke); params.set(PALETTE_ALT_DOWN_FILL, this.palette.altDown?.fill ?? defaultColors.down.fill); params.set(PALETTE_ALT_NEUTRAL_FILL, this.palette.altNeutral?.fill ?? defaultColors.altNeutral.fill); params.set(PALETTE_ALT_NEUTRAL_STROKE, this.palette.altNeutral?.stroke ?? defaultColors.altNeutral.stroke); return params; } }; _ChartTheme.cartesianAxisDefault = { ["number" /* NUMBER */]: _ChartTheme.getAxisDefaults({ line: { enabled: false } }), ["log" /* LOG */]: _ChartTheme.getAxisDefaults({ base: 10, line: { enabled: false }, interval: { minSpacing: NaN } }), ["category" /* CATEGORY */]: _ChartTheme.getAxisDefaults({ groupPaddingInner: 0.1, label: { autoRotate: true }, gridLine: { enabled: DEFAULT_GRIDLINE_ENABLED }, crosshair: { enabled: false } }), ["grouped-category" /* GROUPED_CATEGORY */]: _ChartTheme.getAxisDefaults({ tick: { enabled: true, stroke: DEFAULT_SEPARATION_LINES_COLOUR }, label: { spacing: 10, rotation: 270 }, paddingInner: 0.4, groupPaddingInner: 0.2, crosshair: { enabled: false } }), ["time" /* TIME */]: _ChartTheme.getAxisDefaults({ gridLine: { enabled: DEFAULT_GRIDLINE_ENABLED } }), ["ordinal-time" /* ORDINAL_TIME */]: _ChartTheme.getAxisDefaults({ groupPaddingInner: 0, label: { autoRotate: false }, gridLine: { enabled: DEFAULT_GRIDLINE_ENABLED } }), ["angle-category" /* ANGLE_CATEGORY */]: _ChartTheme.getAxisDefaults({ label: { spacing: 5 }, gridLine: { enabled: DEFAULT_GRIDLINE_ENABLED } }), ["angle-number" /* ANGLE_NUMBER */]: _ChartTheme.getAxisDefaults({ label: { spacing: 5 }, gridLine: { enabled: DEFAULT_GRIDLINE_ENABLED } }), ["radius-category" /* RADIUS_CATEGORY */]: _ChartTheme.getAxisDefaults({ line: { enabled: false } }), ["radius-number" /* RADIUS_NUMBER */]: _ChartTheme.getAxisDefaults({ line: { enabled: false } }) }; ChartTheme = _ChartTheme; } }); // packages/ag-charts-community/src/chart/themes/darkTheme.ts var DEFAULT_DARK_BACKGROUND_FILL, DEFAULT_DARK_FILLS, DEFAULT_DARK_STROKES, DarkTheme; var init_darkTheme = __esm({ "packages/ag-charts-community/src/chart/themes/darkTheme.ts"() { "use strict"; init_chartTheme(); init_symbols(); DEFAULT_DARK_BACKGROUND_FILL = "#192232"; DEFAULT_DARK_FILLS = { BLUE: "#5090dc", ORANGE: "#ffa03a", GREEN: "#459d55", CYAN: "#34bfe1", YELLOW: "#e1cc00", VIOLET: "#9669cb", GRAY: "#b5b5b5", MAGENTA: "#bd5aa7", BROWN: "#8a6224", RED: "#ef5452" }; DEFAULT_DARK_STROKES = { BLUE: "#74a8e6", ORANGE: "#ffbe70", GREEN: "#6cb176", CYAN: "#75d4ef", YELLOW: "#f6e559", VIOLET: "#aa86d8", GRAY: "#a1a1a1", MAGENTA: "#ce7ab9", BROWN: "#997b52", RED: "#ff7872" }; DarkTheme = class extends ChartTheme { getDefaultColors() { return { fills: DEFAULT_DARK_FILLS, strokes: DEFAULT_DARK_STROKES, up: { fill: DEFAULT_DARK_FILLS.GREEN, stroke: DEFAULT_DARK_STROKES.GREEN }, down: { fill: DEFAULT_DARK_FILLS.RED, stroke: DEFAULT_DARK_STROKES.RED }, neutral: { fill: DEFAULT_DARK_FILLS.GRAY, stroke: DEFAULT_DARK_STROKES.GRAY }, altUp: { fill: DEFAULT_DARK_FILLS.BLUE, stroke: DEFAULT_DARK_STROKES.BLUE }, altDown: { fill: DEFAULT_DARK_FILLS.ORANGE, stroke: DEFAULT_DARK_STROKES.ORANGE }, altNeutral: { fill: DEFAULT_DARK_FILLS.GRAY, stroke: DEFAULT_DARK_STROKES.GRAY } }; } getPublicParameters() { return { ...super.getPublicParameters(), axisColor: { $foregroundBackgroundMix: [0.263] }, backgroundColor: DEFAULT_DARK_BACKGROUND_FILL, borderColor: { $foregroundBackgroundMix: [0.784] }, chromeBackgroundColor: { $foregroundBackgroundMix: [0.93] }, foregroundColor: "#fff", gridLineColor: { $foregroundBackgroundAccentMix: [0.743, 0.01] }, subtleTextColor: { $mix: [{ $ref: "textColor" }, { $ref: "backgroundColor" }, 0.57] }, chromeTextColor: { $ref: "textColor" }, crosshairLabelBackgroundColor: { $foregroundBackgroundAccentMix: [0.35, 0.1] } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(IS_DARK_THEME, true); params.set(DEFAULT_POLAR_SERIES_STROKE, DEFAULT_DARK_BACKGROUND_FILL); params.set(DEFAULT_SEPARATION_LINES_COLOUR, "#7f8389"); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ DEFAULT_DARK_FILLS.ORANGE, DEFAULT_DARK_FILLS.YELLOW, DEFAULT_DARK_FILLS.GREEN ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [ DEFAULT_DARK_FILLS.GREEN, DEFAULT_DARK_FILLS.YELLOW, DEFAULT_DARK_FILLS.RED ]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ "#5090dc", "#4882c6", "#4073b0", "#38659a", "#305684", "#28486e", "#203a58", "#182b42" ]); params.set(DEFAULT_HIERARCHY_FILLS, ["#192834", "#253746", "#324859", "#3f596c", "#4d6a80"]); params.set(DEFAULT_HIERARCHY_STROKES, ["#192834", "#3b5164", "#496275", "#577287", "#668399"]); params.set(DEFAULT_BACKGROUND_COLOUR, DEFAULT_DARK_BACKGROUND_FILL); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_DARK_FILLS.BLUE); params.set(DEFAULT_TEXT_ANNOTATION_COLOR, "#fff"); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_DARK_FILLS.BLUE); params.set(DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_DARK_BACKGROUND_FILL); params.set(DEFAULT_ANNOTATION_STATISTICS_FILL, "#28313e"); params.set(DEFAULT_ANNOTATION_STATISTICS_STROKE, "#4b525d"); params.set(DEFAULT_ANNOTATION_STATISTICS_COLOR, "#fff"); params.set(DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, "#fff"); params.set(DEFAULT_TEXTBOX_FILL, "#28313e"); params.set(DEFAULT_TEXTBOX_STROKE, "#4b525d"); params.set(DEFAULT_TEXTBOX_COLOR, "#fff"); return params; } constructor(options) { super(options); } }; } }); // packages/ag-charts-community/src/chart/themes/financialDark.ts var FINANCIAL_DARK_FILLS, FINANCIAL_DARK_STROKES, FinancialDark; var init_financialDark = __esm({ "packages/ag-charts-community/src/chart/themes/financialDark.ts"() { "use strict"; init_darkTheme(); init_symbols(); FINANCIAL_DARK_FILLS = { GREEN: "#089981", RED: "#F23645", BLUE: "#5090dc", GRAY: "#A9A9A9" }; FINANCIAL_DARK_STROKES = { GREEN: "#089981", RED: "#F23645", BLUE: "#5090dc", GRAY: "#909090" }; FinancialDark = class extends DarkTheme { getDefaultColors() { return { fills: { ...FINANCIAL_DARK_FILLS }, strokes: { ...FINANCIAL_DARK_STROKES }, up: { fill: FINANCIAL_DARK_FILLS.GREEN, stroke: FINANCIAL_DARK_STROKES.GREEN }, down: { fill: FINANCIAL_DARK_FILLS.RED, stroke: FINANCIAL_DARK_STROKES.RED }, neutral: { fill: FINANCIAL_DARK_FILLS.BLUE, stroke: FINANCIAL_DARK_STROKES.BLUE }, altUp: { fill: FINANCIAL_DARK_FILLS.GREEN, stroke: FINANCIAL_DARK_STROKES.GREEN }, altDown: { fill: FINANCIAL_DARK_FILLS.RED, stroke: FINANCIAL_DARK_STROKES.RED }, altNeutral: { fill: FINANCIAL_DARK_FILLS.GRAY, stroke: FINANCIAL_DARK_STROKES.GRAY } }; } getPublicParameters() { return { ...super.getPublicParameters(), gridLineColor: { $foregroundBackgroundAccentMix: [0.88, 0.01] }, padding: 0 }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ FINANCIAL_DARK_FILLS.GREEN, FINANCIAL_DARK_FILLS.BLUE, FINANCIAL_DARK_FILLS.RED ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, FINANCIAL_DARK_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, FINANCIAL_DARK_FILLS.BLUE); params.set(DEFAULT_CAPTION_LAYOUT_STYLE, "overlay"); params.set(DEFAULT_CAPTION_ALIGNMENT, "left"); params.set(DEFAULT_TOOLBAR_POSITION, "bottom"); params.set(DEFAULT_GRIDLINE_ENABLED, true); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/financialLight.ts var FINANCIAL_LIGHT_FILLS, FINANCIAL_LIGHT_STROKES, FinancialLight; var init_financialLight = __esm({ "packages/ag-charts-community/src/chart/themes/financialLight.ts"() { "use strict"; init_chartTheme(); init_symbols(); FINANCIAL_LIGHT_FILLS = { GREEN: "#089981", RED: "#F23645", BLUE: "#5090dc", GRAY: "#A9A9A9" }; FINANCIAL_LIGHT_STROKES = { GREEN: "#089981", RED: "#F23645", BLUE: "#5090dc", GRAY: "#909090" }; FinancialLight = class extends ChartTheme { getDefaultColors() { return { fills: { ...FINANCIAL_LIGHT_FILLS }, strokes: { ...FINANCIAL_LIGHT_STROKES }, up: { fill: FINANCIAL_LIGHT_FILLS.GREEN, stroke: FINANCIAL_LIGHT_STROKES.GREEN }, down: { fill: FINANCIAL_LIGHT_FILLS.RED, stroke: FINANCIAL_LIGHT_STROKES.RED }, neutral: { fill: FINANCIAL_LIGHT_FILLS.BLUE, stroke: FINANCIAL_LIGHT_STROKES.BLUE }, altUp: { fill: FINANCIAL_LIGHT_FILLS.GREEN, stroke: FINANCIAL_LIGHT_STROKES.GREEN }, altDown: { fill: FINANCIAL_LIGHT_FILLS.RED, stroke: FINANCIAL_LIGHT_STROKES.RED }, altNeutral: { fill: FINANCIAL_LIGHT_FILLS.GRAY, stroke: FINANCIAL_LIGHT_STROKES.GRAY } }; } getPublicParameters() { return { ...super.getPublicParameters(), gridLineColor: { $foregroundBackgroundAccentMix: [0.94, 0.01] }, padding: 0 }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ FINANCIAL_LIGHT_FILLS.GREEN, FINANCIAL_LIGHT_FILLS.BLUE, FINANCIAL_LIGHT_FILLS.RED ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, FINANCIAL_LIGHT_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, FINANCIAL_LIGHT_FILLS.BLUE); params.set(DEFAULT_CAPTION_LAYOUT_STYLE, "overlay"); params.set(DEFAULT_CAPTION_ALIGNMENT, "left"); params.set(DEFAULT_TOOLBAR_POSITION, "bottom"); params.set(DEFAULT_GRIDLINE_ENABLED, true); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/materialDark.ts var MATERIAL_DARK_FILLS, MATERIAL_DARK_STROKES, MaterialDark; var init_materialDark = __esm({ "packages/ag-charts-community/src/chart/themes/materialDark.ts"() { "use strict"; init_darkTheme(); init_symbols(); MATERIAL_DARK_FILLS = { BLUE: "#2196F3", ORANGE: "#FF9800", GREEN: "#4CAF50", CYAN: "#00BCD4", YELLOW: "#FFEB3B", VIOLET: "#7E57C2", GRAY: "#9E9E9E", MAGENTA: "#F06292", BROWN: "#795548", RED: "#F44336" }; MATERIAL_DARK_STROKES = { BLUE: "#90CAF9", ORANGE: "#FFCC80", GREEN: "#A5D6A7", CYAN: "#80DEEA", YELLOW: "#FFF9C4", VIOLET: "#B39DDB", GRAY: "#E0E0E0", MAGENTA: "#F48FB1", BROWN: "#A1887F", RED: "#EF9A9A" }; MaterialDark = class extends DarkTheme { getDefaultColors() { return { fills: MATERIAL_DARK_FILLS, strokes: MATERIAL_DARK_STROKES, up: { fill: MATERIAL_DARK_FILLS.GREEN, stroke: MATERIAL_DARK_STROKES.GREEN }, down: { fill: MATERIAL_DARK_FILLS.RED, stroke: MATERIAL_DARK_STROKES.RED }, neutral: { fill: MATERIAL_DARK_FILLS.GRAY, stroke: MATERIAL_DARK_STROKES.GRAY }, altUp: { fill: MATERIAL_DARK_FILLS.BLUE, stroke: MATERIAL_DARK_STROKES.BLUE }, altDown: { fill: MATERIAL_DARK_FILLS.RED, stroke: MATERIAL_DARK_STROKES.RED }, altNeutral: { fill: MATERIAL_DARK_FILLS.GRAY, stroke: MATERIAL_DARK_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ MATERIAL_DARK_FILLS.ORANGE, MATERIAL_DARK_FILLS.YELLOW, MATERIAL_DARK_FILLS.GREEN ]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ "#2196f3", // 500 "#208FEC", // (interpolated) "#1E88E5", // 600 "#1C7FDC", // (interpolated) "#1976d2", // 700 "#176EC9", // (interpolated) "#1565c0" // 800 ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [ MATERIAL_DARK_FILLS.GREEN, MATERIAL_DARK_FILLS.YELLOW, MATERIAL_DARK_FILLS.RED ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, MATERIAL_DARK_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, MATERIAL_DARK_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/materialLight.ts var MATERIAL_LIGHT_FILLS, MATERIAL_LIGHT_STROKES, MaterialLight; var init_materialLight = __esm({ "packages/ag-charts-community/src/chart/themes/materialLight.ts"() { "use strict"; init_chartTheme(); init_symbols(); MATERIAL_LIGHT_FILLS = { BLUE: "#2196F3", ORANGE: "#FF9800", GREEN: "#4CAF50", CYAN: "#00BCD4", YELLOW: "#FFEB3B", VIOLET: "#7E57C2", GRAY: "#9E9E9E", MAGENTA: "#F06292", BROWN: "#795548", RED: "#F44336" }; MATERIAL_LIGHT_STROKES = { BLUE: "#1565C0", ORANGE: "#E65100", GREEN: "#2E7D32", CYAN: "#00838F", YELLOW: "#F9A825", VIOLET: "#4527A0", GRAY: "#616161", MAGENTA: "#C2185B", BROWN: "#4E342E", RED: "#B71C1C" }; MaterialLight = class extends ChartTheme { getDefaultColors() { return { fills: MATERIAL_LIGHT_FILLS, strokes: MATERIAL_LIGHT_STROKES, up: { fill: MATERIAL_LIGHT_FILLS.GREEN, stroke: MATERIAL_LIGHT_STROKES.GREEN }, down: { fill: MATERIAL_LIGHT_FILLS.RED, stroke: MATERIAL_LIGHT_STROKES.RED }, neutral: { fill: MATERIAL_LIGHT_FILLS.GRAY, stroke: MATERIAL_LIGHT_STROKES.GRAY }, altUp: { fill: MATERIAL_LIGHT_FILLS.BLUE, stroke: MATERIAL_LIGHT_STROKES.BLUE }, altDown: { fill: MATERIAL_LIGHT_FILLS.RED, stroke: MATERIAL_LIGHT_STROKES.RED }, altNeutral: { fill: MATERIAL_LIGHT_FILLS.GRAY, stroke: MATERIAL_LIGHT_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ MATERIAL_LIGHT_FILLS.ORANGE, MATERIAL_LIGHT_FILLS.YELLOW, MATERIAL_LIGHT_FILLS.GREEN ]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ "#2196f3", // 500 "#329EF4", // (interpolated) "#42a5f5", // 400 "#53ADF6", // (interpolated) "#64b5f6", // 300 "#7AC0F8", // (interpolated) "#90caf9" // 200 ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [ MATERIAL_LIGHT_FILLS.GREEN, MATERIAL_LIGHT_FILLS.YELLOW, MATERIAL_LIGHT_FILLS.RED ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, MATERIAL_LIGHT_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, MATERIAL_LIGHT_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/polychromaDark.ts var POLYCHROMA_DARK_FILLS, POLYCHROMA_DARK_STROKES, PolychromaDark; var init_polychromaDark = __esm({ "packages/ag-charts-community/src/chart/themes/polychromaDark.ts"() { "use strict"; init_darkTheme(); init_symbols(); POLYCHROMA_DARK_FILLS = { BLUE: "#436ff4", PURPLE: "#9a7bff", MAGENTA: "#d165d2", PINK: "#f0598b", RED: "#f47348", ORANGE: "#f2a602", YELLOW: "#e9e201", GREEN: "#21b448", CYAN: "#00b9a2", MODERATE_BLUE: "#00aee4", GRAY: "#bbbbbb" }; POLYCHROMA_DARK_STROKES = { BLUE: "#6698ff", PURPLE: "#c0a3ff", MAGENTA: "#fc8dfc", PINK: "#ff82b1", RED: "#ff9b70", ORANGE: "#ffcf4e", YELLOW: "#ffff58", GREEN: "#58dd70", CYAN: "#51e2c9", MODERATE_BLUE: "#4fd7ff", GRAY: "#eeeeee" }; PolychromaDark = class extends DarkTheme { getDefaultColors() { return { fills: POLYCHROMA_DARK_FILLS, strokes: POLYCHROMA_DARK_STROKES, up: { fill: POLYCHROMA_DARK_FILLS.GREEN, stroke: POLYCHROMA_DARK_STROKES.GREEN }, down: { fill: POLYCHROMA_DARK_FILLS.RED, stroke: POLYCHROMA_DARK_STROKES.RED }, neutral: { fill: POLYCHROMA_DARK_FILLS.GRAY, stroke: POLYCHROMA_DARK_STROKES.GRAY }, altUp: { fill: POLYCHROMA_DARK_FILLS.BLUE, stroke: POLYCHROMA_DARK_STROKES.BLUE }, altDown: { fill: POLYCHROMA_DARK_FILLS.RED, stroke: POLYCHROMA_DARK_STROKES.RED }, altNeutral: { fill: POLYCHROMA_DARK_FILLS.GRAY, stroke: POLYCHROMA_DARK_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [POLYCHROMA_DARK_FILLS.BLUE, POLYCHROMA_DARK_FILLS.RED]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ POLYCHROMA_DARK_FILLS.BLUE, POLYCHROMA_DARK_FILLS.PURPLE, POLYCHROMA_DARK_FILLS.MAGENTA, POLYCHROMA_DARK_FILLS.PINK, POLYCHROMA_DARK_FILLS.RED, POLYCHROMA_DARK_FILLS.ORANGE, POLYCHROMA_DARK_FILLS.YELLOW, POLYCHROMA_DARK_FILLS.GREEN ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [POLYCHROMA_DARK_FILLS.BLUE, POLYCHROMA_DARK_FILLS.RED]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, POLYCHROMA_DARK_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, POLYCHROMA_DARK_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/polychromaLight.ts var POLYCHROMA_LIGHT_FILLS, POLYCHROMA_LIGHT_STROKES, PolychromaLight; var init_polychromaLight = __esm({ "packages/ag-charts-community/src/chart/themes/polychromaLight.ts"() { "use strict"; init_chartTheme(); init_symbols(); POLYCHROMA_LIGHT_FILLS = { BLUE: "#436ff4", PURPLE: "#9a7bff", MAGENTA: "#d165d2", PINK: "#f0598b", RED: "#f47348", ORANGE: "#f2a602", YELLOW: "#e9e201", GREEN: "#21b448", CYAN: "#00b9a2", MODERATE_BLUE: "#00aee4", GRAY: "#bbbbbb" }; POLYCHROMA_LIGHT_STROKES = { BLUE: "#2346c9", PURPLE: "#7653d4", MAGENTA: "#a73da9", PINK: "#c32d66", RED: "#c84b1c", ORANGE: "#c87f00", YELLOW: "#c1b900", GREEN: "#008c1c", CYAN: "#00927c", MODERATE_BLUE: "#0087bb", GRAY: "#888888" }; PolychromaLight = class extends ChartTheme { getDefaultColors() { return { fills: POLYCHROMA_LIGHT_FILLS, strokes: POLYCHROMA_LIGHT_STROKES, up: { fill: POLYCHROMA_LIGHT_FILLS.GREEN, stroke: POLYCHROMA_LIGHT_STROKES.GREEN }, down: { fill: POLYCHROMA_LIGHT_FILLS.RED, stroke: POLYCHROMA_LIGHT_STROKES.RED }, neutral: { fill: POLYCHROMA_LIGHT_FILLS.GRAY, stroke: POLYCHROMA_LIGHT_STROKES.GRAY }, altUp: { fill: POLYCHROMA_LIGHT_FILLS.BLUE, stroke: POLYCHROMA_LIGHT_STROKES.BLUE }, altDown: { fill: POLYCHROMA_LIGHT_FILLS.RED, stroke: POLYCHROMA_LIGHT_STROKES.RED }, altNeutral: { fill: POLYCHROMA_LIGHT_FILLS.GRAY, stroke: POLYCHROMA_LIGHT_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [POLYCHROMA_LIGHT_FILLS.BLUE, POLYCHROMA_LIGHT_FILLS.RED]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ POLYCHROMA_LIGHT_FILLS.BLUE, POLYCHROMA_LIGHT_FILLS.PURPLE, POLYCHROMA_LIGHT_FILLS.MAGENTA, POLYCHROMA_LIGHT_FILLS.PINK, POLYCHROMA_LIGHT_FILLS.RED, POLYCHROMA_LIGHT_FILLS.ORANGE, POLYCHROMA_LIGHT_FILLS.YELLOW, POLYCHROMA_LIGHT_FILLS.GREEN ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [POLYCHROMA_LIGHT_FILLS.BLUE, POLYCHROMA_LIGHT_FILLS.RED]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, POLYCHROMA_LIGHT_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, POLYCHROMA_LIGHT_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/sheetsDark.ts var SHEETS_DARK_FILLS, SHEETS_DARK_STROKES, SheetsDark; var init_sheetsDark = __esm({ "packages/ag-charts-community/src/chart/themes/sheetsDark.ts"() { "use strict"; init_darkTheme(); init_symbols(); SHEETS_DARK_FILLS = { BLUE: "#4472C4", ORANGE: "#ED7D31", GRAY: "#A5A5A5", YELLOW: "#FFC000", MODERATE_BLUE: "#5B9BD5", GREEN: "#70AD47", DARK_GRAY: "#7B7B7B", DARK_BLUE: "#264478", VERY_DARK_GRAY: "#636363", DARK_YELLOW: "#997300" }; SHEETS_DARK_STROKES = { BLUE: "#6899ee", ORANGE: "#ffa55d", GRAY: "#cdcdcd", YELLOW: "#ffea53", MODERATE_BLUE: "#82c3ff", GREEN: "#96d56f", DARK_GRAY: "#a1a1a1", DARK_BLUE: "#47689f", VERY_DARK_GRAY: "#878787", DARK_YELLOW: "#c0993d" }; SheetsDark = class extends DarkTheme { getDefaultColors() { return { fills: { ...SHEETS_DARK_FILLS, RED: SHEETS_DARK_FILLS.ORANGE }, strokes: { ...SHEETS_DARK_STROKES, RED: SHEETS_DARK_STROKES.ORANGE }, up: { fill: SHEETS_DARK_FILLS.GREEN, stroke: SHEETS_DARK_STROKES.GREEN }, down: { fill: SHEETS_DARK_FILLS.ORANGE, stroke: SHEETS_DARK_STROKES.ORANGE }, neutral: { fill: SHEETS_DARK_FILLS.GRAY, stroke: SHEETS_DARK_STROKES.GRAY }, altUp: { fill: SHEETS_DARK_FILLS.BLUE, stroke: SHEETS_DARK_STROKES.BLUE }, altDown: { fill: SHEETS_DARK_FILLS.ORANGE, stroke: SHEETS_DARK_STROKES.ORANGE }, altNeutral: { fill: SHEETS_DARK_FILLS.GRAY, stroke: SHEETS_DARK_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ SHEETS_DARK_FILLS.ORANGE, SHEETS_DARK_FILLS.YELLOW, SHEETS_DARK_FILLS.GREEN ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [ SHEETS_DARK_FILLS.GREEN, SHEETS_DARK_FILLS.YELLOW, SHEETS_DARK_FILLS.ORANGE ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, SHEETS_DARK_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, SHEETS_DARK_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/sheetsLight.ts var SHEETS_LIGHT_FILLS, SHEETS_LIGHT_STROKES, SheetsLight; var init_sheetsLight = __esm({ "packages/ag-charts-community/src/chart/themes/sheetsLight.ts"() { "use strict"; init_chartTheme(); init_symbols(); SHEETS_LIGHT_FILLS = { BLUE: "#5281d5", ORANGE: "#ff8d44", GRAY: "#b5b5b5", YELLOW: "#ffd02f", MODERATE_BLUE: "#6aabe6", GREEN: "#7fbd57", DARK_GRAY: "#8a8a8a", DARK_BLUE: "#335287", VERY_DARK_GRAY: "#717171", DARK_YELLOW: "#a98220" }; SHEETS_LIGHT_STROKES = { BLUE: "#214d9b", ORANGE: "#c25600", GRAY: "#7f7f7f", YELLOW: "#d59800", MODERATE_BLUE: "#3575ac", GREEN: "#4b861a", DARK_GRAY: "#575757", DARK_BLUE: "#062253", VERY_DARK_GRAY: "#414141", DARK_YELLOW: "#734f00" }; SheetsLight = class extends ChartTheme { getDefaultColors() { return { fills: { ...SHEETS_LIGHT_FILLS, RED: SHEETS_LIGHT_FILLS.ORANGE }, strokes: { ...SHEETS_LIGHT_STROKES, RED: SHEETS_LIGHT_STROKES.ORANGE }, up: { fill: SHEETS_LIGHT_FILLS.GREEN, stroke: SHEETS_LIGHT_STROKES.GREEN }, down: { fill: SHEETS_LIGHT_FILLS.ORANGE, stroke: SHEETS_LIGHT_STROKES.ORANGE }, neutral: { fill: SHEETS_LIGHT_STROKES.GRAY, stroke: SHEETS_LIGHT_STROKES.GRAY }, altUp: { fill: SHEETS_LIGHT_FILLS.BLUE, stroke: SHEETS_LIGHT_STROKES.BLUE }, altDown: { fill: SHEETS_LIGHT_FILLS.ORANGE, stroke: SHEETS_LIGHT_STROKES.ORANGE }, altNeutral: { fill: SHEETS_LIGHT_FILLS.GRAY, stroke: SHEETS_LIGHT_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ SHEETS_LIGHT_FILLS.ORANGE, SHEETS_LIGHT_FILLS.YELLOW, SHEETS_LIGHT_FILLS.GREEN ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [ SHEETS_LIGHT_FILLS.GREEN, SHEETS_LIGHT_FILLS.YELLOW, SHEETS_LIGHT_FILLS.ORANGE ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, SHEETS_LIGHT_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, SHEETS_LIGHT_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/vividDark.ts var VIVID_DARK_FILLS, VIVID_DARK_STROKES, VividDark; var init_vividDark = __esm({ "packages/ag-charts-community/src/chart/themes/vividDark.ts"() { "use strict"; init_darkTheme(); init_symbols(); VIVID_DARK_FILLS = { BLUE: "#0083ff", ORANGE: "#ff6600", GREEN: "#00af00", CYAN: "#00ccff", YELLOW: "#f7c700", VIOLET: "#ac26ff", GRAY: "#a7a7b7", MAGENTA: "#e800c5", BROWN: "#b54300", RED: "#ff0000" }; VIVID_DARK_STROKES = { BLUE: "#67b7ff", ORANGE: "#ffc24d", GREEN: "#5cc86f", CYAN: "#54ebff", VIOLET: "#fff653", YELLOW: "#c18aff", GRAY: "#aeaeae", MAGENTA: "#f078d4", BROWN: "#ba8438", RED: "#ff726e" }; VividDark = class extends DarkTheme { getDefaultColors() { return { fills: VIVID_DARK_FILLS, strokes: VIVID_DARK_STROKES, up: { fill: VIVID_DARK_FILLS.GREEN, stroke: VIVID_DARK_STROKES.GREEN }, down: { fill: VIVID_DARK_FILLS.RED, stroke: VIVID_DARK_STROKES.RED }, neutral: { fill: VIVID_DARK_FILLS.GRAY, stroke: VIVID_DARK_STROKES.GRAY }, altUp: { fill: VIVID_DARK_FILLS.BLUE, stroke: VIVID_DARK_STROKES.BLUE }, altDown: { fill: VIVID_DARK_FILLS.ORANGE, stroke: VIVID_DARK_STROKES.ORANGE }, altNeutral: { fill: VIVID_DARK_FILLS.GRAY, stroke: VIVID_DARK_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [ VIVID_DARK_FILLS.ORANGE, VIVID_DARK_FILLS.YELLOW, VIVID_DARK_FILLS.GREEN ]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ "#0083ff", "#0076e6", "#0069cc", "#005cb3", "#004f99", "#004280", "#003466", "#00274c" ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [ VIVID_DARK_FILLS.GREEN, VIVID_DARK_FILLS.YELLOW, VIVID_DARK_FILLS.RED ]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, VIVID_DARK_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, VIVID_DARK_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/themes/vividLight.ts var VIVID_FILLS, VIVID_STROKES, VividLight; var init_vividLight = __esm({ "packages/ag-charts-community/src/chart/themes/vividLight.ts"() { "use strict"; init_chartTheme(); init_symbols(); VIVID_FILLS = { BLUE: "#0083ff", ORANGE: "#ff6600", GREEN: "#00af00", CYAN: "#00ccff", YELLOW: "#f7c700", VIOLET: "#ac26ff", GRAY: "#a7a7b7", MAGENTA: "#e800c5", BROWN: "#b54300", RED: "#ff0000" }; VIVID_STROKES = { BLUE: "#0f68c0", ORANGE: "#d47100", GREEN: "#007922", CYAN: "#009ac2", VIOLET: "#bca400", YELLOW: "#753cac", GRAY: "#646464", MAGENTA: "#9b2685", BROWN: "#6c3b00", RED: "#cb0021" }; VividLight = class extends ChartTheme { getDefaultColors() { return { fills: VIVID_FILLS, strokes: VIVID_STROKES, up: { fill: VIVID_FILLS.GREEN, stroke: VIVID_STROKES.GREEN }, down: { fill: VIVID_FILLS.RED, stroke: VIVID_STROKES.RED }, neutral: { fill: VIVID_FILLS.GRAY, stroke: VIVID_STROKES.GRAY }, altUp: { fill: VIVID_FILLS.BLUE, stroke: VIVID_STROKES.BLUE }, altDown: { fill: VIVID_FILLS.ORANGE, stroke: VIVID_STROKES.ORANGE }, altNeutral: { fill: VIVID_FILLS.GRAY, stroke: VIVID_STROKES.GRAY } }; } getTemplateParameters() { const params = super.getTemplateParameters(); params.set(DEFAULT_DIVERGING_SERIES_COLOR_RANGE, [VIVID_FILLS.ORANGE, VIVID_FILLS.YELLOW, VIVID_FILLS.GREEN]); params.set(DEFAULT_FUNNEL_SERIES_COLOR_RANGE, [ "#0083ff", "#1a8fff", "#339cff", "#4da8ff", "#66b5ff", "#80c1ff", "#99cdff", "#b3daff" ]); params.set(DEFAULT_GAUGE_SERIES_COLOR_RANGE, [VIVID_FILLS.GREEN, VIVID_FILLS.YELLOW, VIVID_FILLS.RED]); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, VIVID_FILLS.BLUE); params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, VIVID_FILLS.BLUE); return params; } }; } }); // packages/ag-charts-community/src/chart/mapping/themes.ts function createChartTheme(value) { if (value instanceof ChartTheme) { return value; } if (value == null || typeof value === "string") { const stockTheme = themes[value]; if (stockTheme) { return stockTheme(); } logger_exports.warnOnce(`the theme [${value}] is invalid, using [ag-default] instead.`); return lightTheme(); } const { errors } = validate(value, themeOptionsDef, "theme"); if (!errors.length) { const flattenedTheme = reduceThemeOptions(value); const baseTheme = flattenedTheme.baseTheme ? getChartTheme(flattenedTheme.baseTheme) : lightTheme(); return new baseTheme.constructor(flattenedTheme); } for (const { message } of errors) { logger_exports.warnOnce(message); } return lightTheme(); } function reduceThemeOptions(options) { let maybeNested = options; let palette; let params; const overrides = []; while (typeof maybeNested === "object") { palette ?? (palette = maybeNested.palette); params ?? (params = maybeNested.params); if (maybeNested.overrides) { overrides.push(maybeNested.overrides); } maybeNested = maybeNested.baseTheme; } return { baseTheme: maybeNested, overrides: mergeDefaults(...overrides), params, palette }; } var lightTheme, darkTheme, themes, getChartTheme, themeOptionsDef; var init_themes = __esm({ "packages/ag-charts-community/src/chart/mapping/themes.ts"() { "use strict"; init_main(); init_memo(); init_object(); init_chartTheme(); init_darkTheme(); init_financialDark(); init_financialLight(); init_materialDark(); init_materialLight(); init_polychromaDark(); init_polychromaLight(); init_sheetsDark(); init_sheetsLight(); init_vividDark(); init_vividLight(); lightTheme = simpleMemorize(() => new ChartTheme()); darkTheme = simpleMemorize(() => new DarkTheme()); themes = { // darkThemes, "ag-default-dark": darkTheme, "ag-sheets-dark": simpleMemorize(() => new SheetsDark()), "ag-polychroma-dark": simpleMemorize(() => new PolychromaDark()), "ag-vivid-dark": simpleMemorize(() => new VividDark()), "ag-material-dark": simpleMemorize(() => new MaterialDark()), "ag-financial-dark": simpleMemorize(() => new FinancialDark()), // lightThemes, null: lightTheme, undefined: lightTheme, "ag-default": lightTheme, "ag-sheets": simpleMemorize(() => new SheetsLight()), "ag-polychroma": simpleMemorize(() => new PolychromaLight()), "ag-vivid": simpleMemorize(() => new VividLight()), "ag-material": simpleMemorize(() => new MaterialLight()), "ag-financial": simpleMemorize(() => new FinancialLight()) }; getChartTheme = simpleMemorize(createChartTheme); themeOptionsDef = { baseTheme: or(string, object), overrides: object, params: object, palette: { fills: arrayOf(string), strokes: arrayOf(string), up: { fill: string, stroke: string }, down: { fill: string, stroke: string }, neutral: { fill: string, stroke: string } } }; } }); // packages/ag-charts-community/src/module/optionsModule.ts var unthemedSeries, _ChartOptions, ChartOptions; var init_optionsModule = __esm({ "packages/ag-charts-community/src/module/optionsModule.ts"() { "use strict"; init_main(); init_main3(); init_presets(); init_axisRegistry(); init_chartTypes(); init_expectedEnterpriseModules(); init_processEnterpriseOptions(); init_seriesRegistry(); init_themes(); init_types(); init_core(); init_color(); init_debug(); init_json(); init_object(); init_coreModulesTypes(); init_enterpriseModule(); unthemedSeries = /* @__PURE__ */ new Set(["map-shape-background", "map-line-background"]); _ChartOptions = class _ChartOptions { constructor(userOptions, processedOverrides, specialOverrides, metadata, deltaOptions, stripSymbols = false) { this.themeParameters = {}; this.debug = Debug.create(true, "opts"); this.optionMetadata = metadata ?? {}; this.processedOverrides = processedOverrides ?? {}; let baseChartOptions = null; if (userOptions instanceof _ChartOptions) { baseChartOptions = userOptions; this.specialOverrides = baseChartOptions.specialOverrides; if (!deltaOptions) throw new Error("AG Charts - internal error: deltaOptions must be supplied."); this.userOptions = mergeDefaults( deltaOptions, deepClone(baseChartOptions.userOptions, _ChartOptions.OPTIONS_CLONE_OPTS) ); } else { this.userOptions = userOptions; this.specialOverrides = this.specialOverridesDefaults({ ...specialOverrides }); } if (stripSymbols) { this.removeLeftoverSymbols(this.userOptions); } let activeTheme, processedOptions, defaultAxes, fastDelta, themeParameters; if (!stripSymbols && deltaOptions != null && _ChartOptions.isFastPathDelta(deltaOptions) && baseChartOptions != null) { ({ activeTheme, processedOptions, defaultAxes, fastDelta } = this.fastSetup( deltaOptions, baseChartOptions )); } else { ({ activeTheme, processedOptions, defaultAxes, themeParameters } = this.slowSetup( processedOverrides, deltaOptions, stripSymbols )); } this.activeTheme = activeTheme; this.processedOptions = processedOptions; this.defaultAxes = defaultAxes; this.fastDelta = fastDelta; this.themeParameters = themeParameters ?? {}; } static isFastPathDelta(deltaOptions) { for (const key of Object.keys(deltaOptions)) { if (!this.FAST_PATH_OPTIONS.has(key)) return false; } return true; } fastSetup(deltaOptions, baseChartOptions) { const { activeTheme, defaultAxes, processedOptions: baseOptions } = baseChartOptions; const { presetType } = this.optionMetadata; const processor = presetType ? PRESET_DATA_PROCESSORS[presetType] : void 0; if (presetType != null && deltaOptions.data != null && processor != null) { const { series, data } = processor(deltaOptions.data); deltaOptions = mergeDefaults({ series, data }, deltaOptions); } this.fastSeriesSetup(deltaOptions, baseOptions); const processedOptions = mergeDefaults(deltaOptions, baseOptions); return { activeTheme, defaultAxes, processedOptions, fastDelta: deltaOptions }; } fastSeriesSetup(deltaOptions, baseOptions) { if (!deltaOptions.series) return; if (deltaOptions.series?.every((s, i) => jsonPropertyCompare(s, baseOptions.series?.[i] ?? {}))) { delete deltaOptions["series"]; } else { deltaOptions.series = deltaOptions.series.map((s, i) => { return mergeDefaults(s, baseOptions.series?.[i] ?? {}); }); } } slowSetup(processedOverrides, deltaOptions, stripSymbols = false) { let options = deepClone(this.userOptions, _ChartOptions.OPTIONS_CLONE_OPTS); if (deltaOptions) { options = mergeDefaults(deltaOptions, options); if (stripSymbols) { this.removeLeftoverSymbols(options); } } const { presetType } = this.optionMetadata; if (presetType != null) { const presetConstructor = PRESETS[presetType]; const presetParams = this.userOptions; const presetSubType = this.userOptions.type; const presetTheme = presetSubType != null ? getChartTheme(this.userOptions.theme).presets[presetSubType] : void 0; this.debug(">>> AgCharts.createOrUpdate() - applying preset", presetParams); options = presetConstructor?.(presetParams, presetTheme, () => this.activeTheme) ?? options; } if (!enterpriseModule.isEnterprise) { removeUsedEnterpriseOptions(options); } const activeTheme = getChartTheme(options.theme); this.sanityCheck(options); this.removeDisabledOptions(options); const seriesType = this.optionsType(options); const { axes: axesThemes = {}, annotations = {}, series: seriesTheme, ...themeDefaults } = this.getSeriesThemeConfig(seriesType, activeTheme); const [annotationsOptions, annotationsThemes] = this.splitAnnotationsOptions(annotations); this.annotationThemes = deepClone(annotationsThemes); const defaultAxes = this.getDefaultAxes(options, seriesTheme); let processedOptions = mergeDefaults( processedOverrides, options, annotationsOptions, themeDefaults, defaultAxes ); this.processAxesOptions(processedOptions, axesThemes); this.processSeriesOptions(processedOptions, activeTheme); this.processMiniChartSeriesOptions(processedOptions, activeTheme); processedOptions = deepClone(processedOptions, _ChartOptions.OPTIONS_CLONE_OPTS); const themeParameters = this.getThemeParameters(activeTheme, processedOptions); this.resolveThemeOperations(themeParameters, themeParameters); this.resolveThemeOperations(themeParameters, processedOptions); this.resolveThemeOperations(themeParameters, this.annotationThemes); if ((isAgCartesianChartOptions(processedOptions) || isAgStandaloneChartOptions(processedOptions) || isAgPolarChartOptionsWithSeriesBasedLegend(processedOptions)) && processedOptions.legend?.enabled == null) { processedOptions.legend ?? (processedOptions.legend = {}); processedOptions.legend.enabled = processedOptions.series.length > 1; } this.enableConfiguredOptions(processedOptions, this.userOptions); activeTheme.templateTheme(processedOptions, false); this.removeDisabledOptions(options); removeUnusedEnterpriseOptions(processedOptions); if (!enterpriseModule.isEnterprise) { removeUsedEnterpriseOptions(processedOptions, true); } this.debug("AgCharts.createOrUpdate() - processed options", processedOptions); return { activeTheme, processedOptions, defaultAxes, themeParameters }; } diffOptions(other) { if (this === other) return {}; if (other == null) return this.processedOptions; return this.fastDelta ?? jsonDiff(other.processedOptions, this.processedOptions); } getSeriesThemeConfig(seriesType, activeTheme) { return activeTheme?.config[seriesType] ?? {}; } getDefaultAxes(options, seriesTheme) { const optionsType2 = this.optionsType(options); let firstSeriesOptions = options.series?.find((series) => (series.type ?? "line") === optionsType2) ?? {}; if (seriesRegistry.isDerivedDefaultAxes(optionsType2)) { firstSeriesOptions = mergeDefaults(firstSeriesOptions, seriesTheme); } return seriesRegistry.cloneDefaultAxes(optionsType2, firstSeriesOptions); } optionsType(options) { return options.series?.[0]?.type ?? "line"; } sanityCheck(options) { this.axesTypeIntegrity(options); this.seriesTypeIntegrity(options); this.soloSeriesIntegrity(options); } splitAnnotationsOptions(annotations) { const { axesButtons = null, enabled = null, optionsToolbar: optionsToolbar2 = null, toolbar: toolbar2 = null, ...annotationsThemes } = annotations; if (axesButtons == null && enabled == null && optionsToolbar2 == null && toolbar2 == null) { return [{}, annotationsThemes]; } return [{ annotations: { axesButtons, enabled, optionsToolbar: optionsToolbar2, toolbar: toolbar2 } }, annotationsThemes]; } processAxesOptions(options, axesThemes) { if (!("axes" in options)) return; options.axes = options.axes?.map((axis) => { const { crossLines: crossLinesTheme, ...axisTheme } = mergeDefaults( axesThemes[axis.type]?.[axis.position], axesThemes[axis.type] ); if (axis.crossLines) { axis.crossLines = mergeArrayDefaults(axis.crossLines, crossLinesTheme); } const gridLineStyle = axisTheme.gridLine?.style; if (axis.gridLine?.style && gridLineStyle?.length) { axis.gridLine.style = axis.gridLine.style.map( (style, index) => style.stroke != null || style.lineDash != null ? mergeDefaults(style, gridLineStyle.at(index % gridLineStyle.length)) : style ); } const { top: _1, right: _2, bottom: _3, left: _4, ...axisOptions } = mergeDefaults(axis, axisTheme); return axisOptions; }); } processSeriesOptions(options, activeTheme) { const defaultTooltipPosition = this.getTooltipPositionDefaults(options); const userPalette = isObject(options.theme) ? paletteType(options.theme?.palette) : "inbuilt"; const paletteOptions = { colourIndex: 0, userPalette }; const processedSeries = options.series?.map((series) => { series.type ?? (series.type = this.getDefaultSeriesType(options)); const { innerLabels: innerLabelsTheme, ...seriesTheme } = this.getSeriesThemeConfig(series.type, activeTheme).series ?? {}; const seriesPaletteOptions = unthemedSeries.has(series.type) ? { colourIndex: 0, userPalette } : paletteOptions; const palette = this.getSeriesPalette(series.type, seriesPaletteOptions, activeTheme); const defaultTooltipRange = this.getTooltipRangeDefaults(options, series.type); const seriesOptions = mergeDefaults( this.getSeriesGroupingOptions(series), series, defaultTooltipPosition, defaultTooltipRange, seriesTheme, palette, { visible: true } ); if (seriesOptions.innerLabels) { seriesOptions.innerLabels = mergeArrayDefaults(seriesOptions.innerLabels, innerLabelsTheme); } return seriesOptions; }); options.series = this.setSeriesGroupingOptions(processedSeries ?? []); } processMiniChartSeriesOptions(options, activeTheme) { let miniChartSeries = options.navigator?.miniChart?.series; if (miniChartSeries == null) return; const paletteOptions = { colourIndex: 0, userPalette: isObject(options.theme) ? paletteType(options.theme.palette) : "inbuilt" }; miniChartSeries = miniChartSeries.map((series) => { series.type ?? (series.type = "line"); const { innerLabels: _, ...seriesTheme } = this.getSeriesThemeConfig(series.type, activeTheme).series ?? {}; return mergeDefaults( this.getSeriesGroupingOptions(series), series, seriesTheme, this.getSeriesPalette(series.type, paletteOptions, activeTheme) ); }); options.navigator.miniChart.series = this.setSeriesGroupingOptions(miniChartSeries); } getThemeParameters(theme, options) { const defaultParameters = theme.getPublicParameters(); if (!isPlainObject(options.theme) || !options.theme.params) { return defaultParameters; } const color = attachDescription( (value) => isString(value) && Color.validColorString(value), `a color` ); const themeParamsOptionsDef = { accentColor: color, axisColor: color, backgroundColor: color, borderColor: color, foregroundColor: color, fontFamily: string, fontSize: number, fontWeight: or(string, number), gridLineColor: color, padding: number, subtleTextColor: color, textColor: color, chromeBackgroundColor: color, chromeFontFamily: string, chromeFontSize: number, chromeFontWeight: or(string, number), chromeSubtleTextColor: color, chromeTextColor: color, inputBackgroundColor: color, inputTextColor: color, crosshairLabelBackgroundColor: color, crosshairLabelTextColor: color }; const { valid, errors } = validate(options.theme.params, themeParamsOptionsDef); for (const { message } of errors) { logger_exports.warnOnce(message); } return mergeDefaults(valid, defaultParameters); } resolveThemeOperations(params, options) { const modifiedPaths = jsonResolveOperations(options, params, /* @__PURE__ */ new Set(["palette", "data"])); this.debug("resolveTheme()", modifiedPaths); } getSeriesPalette(seriesType, options, activeTheme) { const paletteFactory = seriesRegistry.getPaletteFactory(seriesType); const { colourIndex: colourOffset, userPalette } = options; const { fills = [], strokes = [] } = activeTheme.palette; return paletteFactory?.({ userPalette, colorsCount: Math.max(fills.length, strokes.length), themeTemplateParameters: activeTheme.getTemplateParameters(), palette: activeTheme.palette, takeColors(count) { options.colourIndex += count; return { fills: circularSliceArray(fills, count, colourOffset), strokes: circularSliceArray(strokes, count, colourOffset) }; } }); } getSeriesGroupingOptions(series) { const groupable = seriesRegistry.isGroupable(series.type); const stackable = seriesRegistry.isStackable(series.type); const stackedByDefault = seriesRegistry.isStackedByDefault(series.type); if (series.grouped && !groupable) { logger_exports.warnOnce(`unsupported grouping of series type "${series.type}".`); } if ((series.stacked || series.stackGroup) && !stackable) { logger_exports.warnOnce(`unsupported stacking of series type "${series.type}".`); } let { grouped, stacked } = series; stacked ?? (stacked = (stackedByDefault || series.stackGroup != null) && !(groupable && grouped)); grouped ?? (grouped = true); return { stacked: stackable && stacked, grouped: groupable && grouped && !(stackable && stacked) }; } setSeriesGroupingOptions(allSeries) { const seriesGroups = this.getSeriesGrouping(allSeries); this.debug("setSeriesGroupingOptions() - series grouping: ", seriesGroups); const groupIdx = {}; const groupCount2 = seriesGroups.reduce((countMap, seriesGroup) => { var _a; if (seriesGroup.groupType === "default" /* DEFAULT */) { return countMap; } countMap[_a = seriesGroup.seriesType] ?? (countMap[_a] = 0); countMap[seriesGroup.seriesType] += seriesGroup.groupType === "stack" /* STACK */ ? 1 : seriesGroup.series.length; return countMap; }, {}); return seriesGroups.flatMap((seriesGroup) => { var _a; groupIdx[_a = seriesGroup.seriesType] ?? (groupIdx[_a] = 0); switch (seriesGroup.groupType) { case "stack" /* STACK */: { const groupIndex = groupIdx[seriesGroup.seriesType]++; return seriesGroup.series.map( (series, stackIndex) => Object.assign(series, { seriesGrouping: { groupId: seriesGroup.groupId, groupIndex, groupCount: groupCount2[seriesGroup.seriesType], stackIndex, stackCount: seriesGroup.series.length } }) ); } case "group" /* GROUP */: return seriesGroup.series.map( (series) => Object.assign(series, { seriesGrouping: { groupId: seriesGroup.groupId, groupIndex: groupIdx[seriesGroup.seriesType]++, groupCount: groupCount2[seriesGroup.seriesType], stackIndex: 0, stackCount: 0 } }) ); } return seriesGroup.series; }).map(({ stacked: _, grouped: __, ...seriesOptions }) => seriesOptions); } getSeriesGroupId(series) { return [series.type, series.xKey, series.stacked ? series.stackGroup ?? "stacked" : "grouped"].filter(Boolean).join("-"); } getSeriesGrouping(allSeries) { const groupMap = /* @__PURE__ */ new Map(); return allSeries.reduce((result, series) => { const seriesType = series.type; if (!series.stacked && !series.grouped) { result.push({ groupType: "default" /* DEFAULT */, seriesType, series: [series], groupId: "__default__" }); } else { const groupId = this.getSeriesGroupId(series); if (!groupMap.has(groupId)) { const groupType = series.stacked ? "stack" /* STACK */ : "group" /* GROUP */; const record = { groupType, seriesType, series: [], groupId }; groupMap.set(groupId, record); result.push(record); } groupMap.get(groupId).series.push(series); } return result; }, []); } getDefaultSeriesType(options) { const chartDef = ModuleRegistry.detectChartDefinition(options); switch (chartDef.name) { case "cartesian": return "line"; case "polar": return "pie"; case "hierarchy": return "treemap"; case "topology": return "map-shape"; case "flow-proportion": return "sankey"; case "standalone": return "pyramid"; case "gauge": return "radial-gauge"; default: throw new Error("Invalid chart options type detected."); } } getTooltipPositionDefaults(options) { const position = options.tooltip?.position; if (!isPlainObject(position)) { return; } const { type, xOffset, yOffset } = position; const result = {}; if (isString(type) && isEnumValue(AgTooltipPositionType, type)) { result.type = type; } if (isFiniteNumber(xOffset)) { result.xOffset = xOffset; } if (isFiniteNumber(yOffset)) { result.yOffset = yOffset; } return { tooltip: { position: result } }; } // AG-11591 Support for new series-specific & legacy chart-global 'tooltip.range' options // // The `chart.series[].tooltip.range` option is a bit different for legacy reason. This use to be // global option (`chart.tooltip.range`) that could override the theme. But now, the tooltip range // option is series-specific. // // To preserve backward compatibility, the `chart.tooltip.range` theme default has been changed from // 'nearest' to undefined. getTooltipRangeDefaults(options, seriesType) { return { tooltip: { range: options.tooltip?.range ?? seriesRegistry.getTooltipDefauls(seriesType)?.range } }; } axesTypeIntegrity(options) { if ("axes" in options && options.axes) { const axes = options.axes; for (const { type } of axes) { if (!isAxisOptionType(type)) { delete options.axes; const expectedTypes = [...axisRegistry.keys()].join(", "); logger_exports.warnOnce(`unknown axis type: ${type}; expected one of: ${expectedTypes}`); } } } } seriesTypeIntegrity(options) { options.series = options.series?.filter(({ type }) => { if (type == null || isSeriesOptionType(type) || isEnterpriseSeriesType(type)) { return true; } logger_exports.warnOnce( `unknown series type: ${JSON.stringify(type)}; expected one of: ${publicChartTypes.seriesTypes.join(", ")}` ); }); } soloSeriesIntegrity(options) { const allSeries = options.series; if (allSeries && allSeries.length > 1 && allSeries.some((series) => seriesRegistry.isSolo(series.type))) { const mainSeriesType = this.optionsType(options); if (seriesRegistry.isSolo(mainSeriesType)) { logger_exports.warn( `series[0] of type '${mainSeriesType}' is incompatible with other series types. Only processing series[0]` ); options.series = allSeries.slice(0, 1); } else { const { solo, nonSolo } = groupBy( allSeries, (s) => seriesRegistry.isSolo(s.type) ? "solo" : "nonSolo" ); const rejects = unique(solo.map((s) => s.type)).join(", "); logger_exports.warn(`Unable to mix these series types with the lead series type: ${rejects}`); options.series = nonSolo; } } } static enableConfiguredJsonOptions(visitingUserOpts, visitingMergedOpts) { if (typeof visitingMergedOpts === "object" && "enabled" in visitingMergedOpts && !visitingMergedOpts._enabledFromTheme && visitingUserOpts.enabled == null) { visitingMergedOpts.enabled = true; } } static cleanupEnabledFromThemeJsonOptions(visitingMergedOpts) { if (visitingMergedOpts._enabledFromTheme != null) { delete visitingMergedOpts._enabledFromTheme; } } enableConfiguredOptions(options, userOptions) { jsonWalk(userOptions, _ChartOptions.enableConfiguredJsonOptions, /* @__PURE__ */ new Set(["data", "theme"]), options); jsonWalk(options, _ChartOptions.cleanupEnabledFromThemeJsonOptions, /* @__PURE__ */ new Set(["data", "theme"])); } static removeDisabledOptionJson(optionsNode) { if ("enabled" in optionsNode && optionsNode.enabled === false) { Object.keys(optionsNode).forEach((key) => { if (key === "enabled") return; delete optionsNode[key]; }); } } removeDisabledOptions(options) { jsonWalk(options, _ChartOptions.removeDisabledOptionJson, /* @__PURE__ */ new Set(["data", "theme"])); } static removeLeftoverSymbolsJson(optionsNode) { if (!optionsNode || !isObject(optionsNode)) return; for (const [key, value] of Object.entries(optionsNode)) { if (isSymbol(value)) { delete optionsNode[key]; } } } removeLeftoverSymbols(options) { jsonWalk(options, _ChartOptions.removeLeftoverSymbolsJson, /* @__PURE__ */ new Set(["data"])); } specialOverridesDefaults(options) { if (options.window != null) { setWindow(options.window); } else if (typeof window !== "undefined") { options.window = window; } else if (typeof global !== "undefined") { options.window = global.window; } if (options.document != null) { setDocument(options.document); } else if (typeof document !== "undefined") { options.document = document; } else if (typeof global !== "undefined") { options.document = global.document; } if (options.window == null) { throw new Error("AG Charts - unable to resolve global window"); } if (options.document == null) { throw new Error("AG Charts - unable to resolve global document"); } return options; } }; _ChartOptions.OPTIONS_CLONE_OPTS = /* @__PURE__ */ new Set(["data", "container"]); _ChartOptions.FAST_PATH_OPTIONS = /* @__PURE__ */ new Set(["data", "width", "height"]); ChartOptions = _ChartOptions; } }); // packages/ag-charts-community/src/util/pool.ts var CLEANUP_TIMEOUT_MS, _Pool, Pool; var init_pool = __esm({ "packages/ag-charts-community/src/util/pool.ts"() { "use strict"; init_debug(); CLEANUP_TIMEOUT_MS = 100; _Pool = class _Pool { constructor(name, buildItem, releaseItem, destroyItem, maxPoolSize, cleanupTimeMs = CLEANUP_TIMEOUT_MS) { this.name = name; this.buildItem = buildItem; this.releaseItem = releaseItem; this.destroyItem = destroyItem; this.maxPoolSize = maxPoolSize; this.cleanupTimeMs = cleanupTimeMs; this.freePool = []; this.busyPool = /* @__PURE__ */ new Set(); } static getPool(name, buildItem, releaseItem, destroyItem, maxPoolSize) { if (!this.pools.has(name)) { this.pools.set(name, new _Pool(name, buildItem, releaseItem, destroyItem, maxPoolSize)); } return this.pools.get(name); } isFull() { return this.freePool.length + this.busyPool.size >= this.maxPoolSize; } obtain(params) { if (this.freePool.length === 0 && this.isFull()) { throw new Error("AG Charts - pool exhausted"); } let nextFree = this.freePool.pop(); if (nextFree == null) { nextFree = this.buildItem(params); _Pool.debug( `Pool[name=${this.name}]: Created instance (${this.freePool.length} / ${this.busyPool.size + 1} / ${this.maxPoolSize})`, nextFree ); } else { _Pool.debug( `Pool[name=${this.name}]: Re-used instance (${this.freePool.length} / ${this.busyPool.size + 1} / ${this.maxPoolSize})`, nextFree ); } this.busyPool.add(nextFree); return { item: nextFree, release: () => this.release(nextFree) }; } release(item) { if (!this.busyPool.has(item)) { throw new Error("AG Charts - cannot free item from pool which is not tracked as busy."); } _Pool.debug( `Pool[name=${this.name}]: Releasing instance (${this.freePool.length} / ${this.busyPool.size} / ${this.maxPoolSize})`, item ); this.releaseItem(item); this.busyPool.delete(item); this.freePool.push(item); _Pool.debug( `Pool[name=${this.name}]: Returned instance to free pool (${this.freePool.length} / ${this.busyPool.size} / ${this.maxPoolSize})`, item ); if (this.cleanPoolTimer) { clearTimeout(this.cleanPoolTimer); } this.cleanPoolTimer = setTimeout(() => { this.cleanPool(); }, this.cleanupTimeMs); } cleanPool() { const itemsToFree = this.freePool.splice(0); for (const item of itemsToFree) { this.destroyItem(item); } _Pool.debug( `Pool[name=${this.name}]: Cleaned pool of ${itemsToFree.length} items (${this.freePool.length} / ${this.busyPool.size} / ${this.maxPoolSize})` ); } destroy() { this.cleanPool(); for (const item of this.busyPool.values()) { this.destroyItem(item); } this.busyPool.clear(); } }; _Pool.pools = /* @__PURE__ */ new Map(); _Pool.debug = Debug.create(true, "pool"); Pool = _Pool; } }); // packages/ag-charts-community/src/api/agCharts.ts var debug3, AgCharts, _AgChartsInternal, AgChartsInternal; var init_agCharts2 = __esm({ "packages/ag-charts-community/src/api/agCharts.ts"() { "use strict"; init_main(); init_cartesianChartModule(); init_chart(); init_chartProxy(); init_registerInbuiltModules(); init_setupModules(); init_polarChartModule(); init_enterpriseModule(); init_optionsModule(); init_debug(); init_json(); init_pool(); init_version(); init_memento(); ModuleRegistry.registerMany([CartesianChartModule, PolarChartModule]); debug3 = Debug.create(true, "opts"); AgCharts = class { static licenseCheck(options) { if (this.licenseChecked) return; this.licenseManager = enterpriseModule.licenseManager?.(options); this.licenseManager?.validateLicense(); this.licenseChecked = true; } static getLicenseDetails(licenseKey) { return enterpriseModule.licenseManager?.({}).getLicenseDetails(licenseKey); } /** * Returns the `AgChartInstance` for a DOM node, if there is one. */ static getInstance(element2) { return AgChartsInternal.getInstance(element2); } /** * Create a new `AgChartInstance` based upon the given configuration options. */ static create(userOptions, optionsMetadata) { return debug3.group("AgCharts.create()", () => { this.licenseCheck(userOptions); const chart = AgChartsInternal.createOrUpdate({ userOptions, licenseManager: this.licenseManager, optionsMetadata }); if (this.licenseManager?.isDisplayWatermark() && this.licenseManager) { enterpriseModule.injectWatermark?.( chart.chart.ctx.domManager, this.licenseManager.getWatermarkMessage() ); } return chart; }); } static createFinancialChart(options) { return debug3.group("AgCharts.createFinancialChart()", () => { return this.create(options, { presetType: "price-volume" }); }); } static createGauge(options) { return debug3.group("AgCharts.createGauge()", () => { return this.create(options, { presetType: "gauge" }); }); } static __createSparkline(options) { return debug3.group("AgCharts.__createSparkline()", () => { const { pool, ...normalOptions } = options; return this.create(normalOptions, { presetType: "sparkline", pool: pool ?? true }); }); } }; AgCharts.licenseChecked = false; _AgChartsInternal = class _AgChartsInternal { static getInstance(element2) { const chart = Chart.getInstance(element2); return chart ? AgChartInstanceProxy.chartInstances.get(chart) : void 0; } static initialiseModules() { if (_AgChartsInternal.initialised) return; registerInbuiltModules(); setupModules(); _AgChartsInternal.initialised = true; } static createOrUpdate(opts) { let { proxy } = opts; const { userOptions, licenseManager, processedOverrides = proxy?.chart.chartOptions.processedOverrides ?? {}, specialOverrides = proxy?.chart.chartOptions.specialOverrides ?? {}, optionsMetadata = proxy?.chart.chartOptions.optionMetadata ?? {}, deltaOptions, stripSymbols = false } = opts; const styles = enterpriseModule.styles != null ? [["ag-charts-enterprise", enterpriseModule.styles]] : []; const { presetType } = optionsMetadata; _AgChartsInternal.initialiseModules(); debug3(() => [">>> AgCharts.createOrUpdate() user options", deepClone(userOptions)]); let mutableOptions = userOptions; if (AgCharts.optionsMutationFn && mutableOptions) { mutableOptions = AgCharts.optionsMutationFn(deepClone(mutableOptions), presetType); debug3(() => [">>> AgCharts.createOrUpdate() MUTATED user options", deepClone(mutableOptions)]); } const { document: document2, window: userWindow, styleContainer, ...options } = mutableOptions ?? {}; const baseOptions = (deltaOptions ? proxy?.chart.getChartOptions() : options) ?? options; const chartOptions = new ChartOptions( baseOptions, processedOverrides, { ...specialOverrides, document: document2, window: userWindow, styleContainer }, optionsMetadata, deltaOptions, stripSymbols ); let create = false; let chart = proxy?.chart; let poolResult; if (chart == null || ModuleRegistry.detectChartDefinition(chartOptions.processedOptions) !== ModuleRegistry.detectChartDefinition(chart.chartOptions.processedOptions)) { poolResult = this.getPool(chartOptions)?.obtain(chartOptions); if (poolResult) { chart = poolResult.item; } else { create = true; chart = _AgChartsInternal.createChartInstance(chartOptions, chart); } styles.forEach(([id, css]) => { chart?.ctx.domManager.addStyles(id, css); }); } if (proxy == null) { proxy = new AgChartInstanceProxy(chart, _AgChartsInternal.callbackApi, licenseManager); proxy.releaseChart = poolResult?.release; } else if (poolResult || create) { proxy.releaseChart?.(); proxy.chart = chart; proxy.releaseChart = poolResult?.release; } if (debug3.check() && typeof window !== "undefined") { window.agChartInstances ?? (window.agChartInstances = {}); window.agChartInstances[chart.id] = chart; } chart.queuedUserOptions.push(chartOptions.userOptions); chart.queuedChartOptions.push(chartOptions); chart.requestFactoryUpdate((chartRef) => { debug3.group(">>>> Chart.applyOptions()", () => { chartRef.applyOptions(chartOptions); const queueIdx = chartRef.queuedUserOptions.indexOf(chartOptions.userOptions) + 1; chartRef.queuedUserOptions.splice(0, queueIdx); chartRef.queuedChartOptions.splice(0, queueIdx); }); }); return proxy; } static markRemovedProperties(node, _, modified = false) { if (typeof node !== "object") return modified; for (const [key, value] of Object.entries(node)) { if (typeof value === "undefined") { Object.assign(node, { [key]: Symbol("UNSET") }); modified || (modified = true); } } return modified; } static updateUserDelta(proxy, deltaOptions) { deltaOptions = deepClone(deltaOptions, /* @__PURE__ */ new Set(["data"])); const stripSymbols = jsonWalk( deltaOptions, _AgChartsInternal.markRemovedProperties, /* @__PURE__ */ new Set(["data"]), void 0, void 0, false ); debug3(() => [">>> AgCharts.updateUserDelta() user delta", deepClone(deltaOptions)]); _AgChartsInternal.createOrUpdate({ proxy, deltaOptions, stripSymbols }); } static createChartInstance(options, oldChart) { const transferableResource = oldChart?.destroy({ keepTransferableResources: true }); const chartDef = ModuleRegistry.detectChartDefinition(options.processedOptions); return chartDef.create(options, transferableResource); } static getPool(options) { if (options.optionMetadata.pool !== true) return; return Pool.getPool( options.optionMetadata.presetType ?? "default", this.createChartInstance, this.detachAndClear, this.destroy, Infinity // AG-13480 - Prevent Grid exhausting pool during sorting. ); } }; _AgChartsInternal.caretaker = new MementoCaretaker(VERSION); _AgChartsInternal.initialised = false; _AgChartsInternal.callbackApi = { caretaker: _AgChartsInternal.caretaker, create(userOptions, processedOverrides, specialOverrides, optionsMetadata) { return _AgChartsInternal.createOrUpdate({ userOptions, processedOverrides, specialOverrides, optionsMetadata }); }, update(opts, chart) { return _AgChartsInternal.createOrUpdate({ userOptions: opts, proxy: chart }); }, updateUserDelta(chart, deltaOptions) { return _AgChartsInternal.updateUserDelta(chart, deltaOptions); } }; _AgChartsInternal.detachAndClear = (chart) => chart.detachAndClear(); _AgChartsInternal.destroy = (chart) => chart.destroy(); AgChartsInternal = _AgChartsInternal; } }); // packages/ag-charts-community/src/scene/shape/arc.ts var Arc2; var init_arc = __esm({ "packages/ag-charts-community/src/scene/shape/arc.ts"() { "use strict"; init_angle(); init_number(); init_bbox(); init_path(); Arc2 = class extends Path { constructor() { super(); this.centerX = 0; this.centerY = 0; this.radius = 10; this.startAngle = 0; this.endAngle = Math.PI * 2; this.counterClockwise = false; this.type = 0 /* Open */; this.restoreOwnStyles(); } get fullPie() { return isNumberEqual(normalizeAngle360(this.startAngle), normalizeAngle360(this.endAngle)); } updatePath() { const path = this.path; path.clear(); path.arc(this.centerX, this.centerY, this.radius, this.startAngle, this.endAngle, this.counterClockwise); if (this.type === 1 /* Chord */) { path.closePath(); } else if (this.type === 2 /* Round */ && !this.fullPie) { path.lineTo(this.centerX, this.centerY); path.closePath(); } } computeBBox() { return new BBox(this.centerX - this.radius, this.centerY - this.radius, this.radius * 2, this.radius * 2); } isPointInPath(x, y) { const bbox = this.getBBox(); return this.type !== 0 /* Open */ && bbox.containsPoint(x, y) && this.path.isPointInPath(x, y); } }; Arc2.className = "Arc"; __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "centerX", 2); __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "centerY", 2); __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "radius", 2); __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "startAngle", 2); __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "endAngle", 2); __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "counterClockwise", 2); __decorateClass([ ScenePathChangeDetection() ], Arc2.prototype, "type", 2); } }); // packages/ag-charts-community/src/scene/shape/radialColumnShape.ts function rotatePoint(x, y, rotation) { const radius = Math.sqrt(x ** 2 + y ** 2); const angle2 = Math.atan2(y, x); const rotated = angle2 + rotation; return { x: Math.cos(rotated) * radius, y: Math.sin(rotated) * radius }; } function getRadialColumnWidth(startAngle, endAngle, axisOuterRadius, columnWidthRatio, maxColumnWidthRatio) { const rotation = angleBetween(startAngle, endAngle); const pad2 = rotation * (1 - columnWidthRatio) / 2; startAngle += pad2; endAngle -= pad2; if (rotation < 1e-3) { return 2 * axisOuterRadius * maxColumnWidthRatio; } if (rotation >= 2 * Math.PI) { const midAngle = startAngle + rotation / 2; startAngle = midAngle - Math.PI; endAngle = midAngle + Math.PI; } const startX = axisOuterRadius * Math.cos(startAngle); const startY = axisOuterRadius * Math.sin(startAngle); const endX = axisOuterRadius * Math.cos(endAngle); const endY = axisOuterRadius * Math.sin(endAngle); const colWidth = Math.floor(Math.sqrt((startX - endX) ** 2 + (startY - endY) ** 2)); const maxWidth = 2 * axisOuterRadius * maxColumnWidthRatio; return Math.max(1, Math.min(maxWidth, colWidth)); } var RadialColumnShape; var init_radialColumnShape = __esm({ "packages/ag-charts-community/src/scene/shape/radialColumnShape.ts"() { "use strict"; init_angle(); init_number(); init_bbox(); init_path(); RadialColumnShape = class extends Path { constructor() { super(...arguments); this.isBeveled = true; this.columnWidth = 0; this.startAngle = 0; this.endAngle = 0; this.outerRadius = 0; this.innerRadius = 0; this.axisInnerRadius = 0; this.axisOuterRadius = 0; this.isRadiusAxisReversed = false; } set cornerRadius(_value) { } computeBBox() { const { innerRadius, outerRadius, columnWidth } = this; const rotation = this.getRotation(); const left = -columnWidth / 2; const right = columnWidth / 2; const top = -outerRadius; const bottom = -innerRadius; let x0 = Infinity; let y0 = Infinity; let x1 = -Infinity; let y1 = -Infinity; for (let i = 0; i < 4; i += 1) { const { x, y } = rotatePoint(i % 2 === 0 ? left : right, i < 2 ? top : bottom, rotation); x0 = Math.min(x, x0); y0 = Math.min(y, y0); x1 = Math.max(x, x1); y1 = Math.max(y, y1); } return new BBox(x0, y0, x1 - x0, y1 - y0); } getRotation() { const { startAngle, endAngle } = this; const midAngle = angleBetween(startAngle, endAngle); return normalizeAngle360(startAngle + midAngle / 2 + Math.PI / 2); } updatePath() { const { isBeveled } = this; if (isBeveled) { this.updateBeveledPath(); } else { this.updateRectangularPath(); } this.checkPathDirty(); } updateRectangularPath() { const { columnWidth, innerRadius, outerRadius, path } = this; const left = -columnWidth / 2; const right = columnWidth / 2; const top = -outerRadius; const bottom = -innerRadius; const rotation = this.getRotation(); const points = [ [left, bottom], [left, top], [right, top], [right, bottom] ].map(([x, y]) => rotatePoint(x, y, rotation)); path.clear(true); path.moveTo(points[0].x, points[0].y); path.lineTo(points[1].x, points[1].y); path.lineTo(points[2].x, points[2].y); path.lineTo(points[3].x, points[3].y); path.closePath(); } updateBeveledPath() { const { columnWidth, path, outerRadius, innerRadius, axisInnerRadius, axisOuterRadius, isRadiusAxisReversed } = this; const isStackBottom = isNumberEqual(innerRadius, axisInnerRadius); const sideRotation = Math.asin(columnWidth / 2 / innerRadius); const pointRotation = this.getRotation(); const rotate2 = (x, y) => rotatePoint(x, y, pointRotation); const getTriangleHypotenuse = (leg, otherLeg) => Math.sqrt(leg ** 2 + otherLeg ** 2); const getTriangleLeg = (hypotenuse, otherLeg) => { if (otherLeg > hypotenuse) { return 0; } return Math.sqrt(hypotenuse ** 2 - otherLeg ** 2); }; const compare = (value, otherValue, lessThan2) => lessThan2 ? value < otherValue : value > otherValue; const shouldConnectBottomCircle = isStackBottom && !isNaN(sideRotation) && sideRotation < Math.PI / 6; let left = -columnWidth / 2; let right = columnWidth / 2; const top = -outerRadius; const bottom = -innerRadius * (shouldConnectBottomCircle ? Math.cos(sideRotation) : 1); const hasBottomIntersection = compare( axisOuterRadius, getTriangleHypotenuse(innerRadius, columnWidth / 2), !isRadiusAxisReversed ); if (hasBottomIntersection) { const bottomIntersectionX = getTriangleLeg(axisOuterRadius, innerRadius); left = -bottomIntersectionX; right = bottomIntersectionX; } path.clear(true); const bottomLeftPt = rotate2(left, bottom); path.moveTo(bottomLeftPt.x, bottomLeftPt.y); const isEmpty2 = isNumberEqual(innerRadius, outerRadius); const hasSideIntersection = compare( axisOuterRadius, getTriangleHypotenuse(outerRadius, columnWidth / 2), !isRadiusAxisReversed ); if (isEmpty2 && shouldConnectBottomCircle) { path.arc( 0, 0, innerRadius, normalizeAngle360(-sideRotation - Math.PI / 2) + pointRotation, normalizeAngle360(sideRotation - Math.PI / 2) + pointRotation, false ); } else if (hasSideIntersection) { const sideIntersectionY = -getTriangleLeg(axisOuterRadius, columnWidth / 2); const topIntersectionX = getTriangleLeg(axisOuterRadius, outerRadius); if (!hasBottomIntersection) { const topLeftPt = rotate2(left, sideIntersectionY); path.lineTo(topLeftPt.x, topLeftPt.y); } path.arc( 0, 0, axisOuterRadius, Math.atan2(sideIntersectionY, left) + pointRotation, Math.atan2(top, -topIntersectionX) + pointRotation, false ); if (!isNumberEqual(topIntersectionX, 0)) { const topRightBevelPt = rotate2(topIntersectionX, top); path.lineTo(topRightBevelPt.x, topRightBevelPt.y); } path.arc( 0, 0, axisOuterRadius, Math.atan2(top, topIntersectionX) + pointRotation, Math.atan2(sideIntersectionY, right) + pointRotation, false ); } else { const topLeftPt = rotate2(left, top); const topRightPt = rotate2(right, top); path.lineTo(topLeftPt.x, topLeftPt.y); path.lineTo(topRightPt.x, topRightPt.y); } const bottomRightPt = rotate2(right, bottom); path.lineTo(bottomRightPt.x, bottomRightPt.y); if (shouldConnectBottomCircle) { path.arc( 0, 0, innerRadius, normalizeAngle360(sideRotation - Math.PI / 2) + pointRotation, normalizeAngle360(-sideRotation - Math.PI / 2) + pointRotation, true ); } else { const rotatedBottomLeftPt = rotate2(left, bottom); path.lineTo(rotatedBottomLeftPt.x, rotatedBottomLeftPt.y); } path.closePath(); } }; RadialColumnShape.className = "RadialColumnShape"; __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "isBeveled", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "columnWidth", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "startAngle", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "endAngle", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "outerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "innerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "axisInnerRadius", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "axisOuterRadius", 2); __decorateClass([ ScenePathChangeDetection() ], RadialColumnShape.prototype, "isRadiusAxisReversed", 2); } }); // packages/ag-charts-community/src/integrated-charts-scene.ts var integrated_charts_scene_exports = {}; __export(integrated_charts_scene_exports, { Arc: () => Arc2, BBox: () => BBox, Caption: () => Caption, CategoryScale: () => CategoryScale, Group: () => Group, Line: () => Line, LinearScale: () => LinearScale, Marker: () => Marker, Path: () => Path, RadialColumnShape: () => RadialColumnShape, Rect: () => Rect, Scene: () => Scene, Sector: () => Sector, Shape: () => Shape, TranslatableGroup: () => TranslatableGroup, getRadialColumnWidth: () => getRadialColumnWidth, toRadians: () => toRadians }); var init_integrated_charts_scene = __esm({ "packages/ag-charts-community/src/integrated-charts-scene.ts"() { "use strict"; init_caption(); init_marker(); init_categoryScale(); init_linearScale(); init_bbox(); init_group(); init_scene(); init_arc(); init_line(); init_path(); init_radialColumnShape(); init_rect(); init_sector2(); init_shape(); init_angle(); } }); // packages/ag-charts-community/src/integrated-charts-theme.ts var integrated_charts_theme_exports = {}; __export(integrated_charts_theme_exports, { ChartTheme: () => ChartTheme, DEFAULT_ANNOTATION_HANDLE_FILL: () => DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_ANNOTATION_STATISTICS_COLOR: () => DEFAULT_ANNOTATION_STATISTICS_COLOR, DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, DEFAULT_ANNOTATION_STATISTICS_FILL: () => DEFAULT_ANNOTATION_STATISTICS_FILL, DEFAULT_ANNOTATION_STATISTICS_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_STROKE, DEFAULT_BACKGROUND_COLOUR: () => DEFAULT_BACKGROUND_COLOUR, DEFAULT_CAPTION_ALIGNMENT: () => DEFAULT_CAPTION_ALIGNMENT, DEFAULT_CAPTION_LAYOUT_STYLE: () => DEFAULT_CAPTION_LAYOUT_STYLE, DEFAULT_COLOR_RANGE: () => DEFAULT_COLOR_RANGE, DEFAULT_DIVERGING_SERIES_COLOR_RANGE: () => DEFAULT_DIVERGING_SERIES_COLOR_RANGE, DEFAULT_FIBONACCI_STROKES: () => DEFAULT_FIBONACCI_STROKES, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_FUNNEL_SERIES_COLOR_RANGE: () => DEFAULT_FUNNEL_SERIES_COLOR_RANGE, DEFAULT_GAUGE_SERIES_COLOR_RANGE: () => DEFAULT_GAUGE_SERIES_COLOR_RANGE, DEFAULT_GRIDLINE_ENABLED: () => DEFAULT_GRIDLINE_ENABLED, DEFAULT_HIERARCHY_FILLS: () => DEFAULT_HIERARCHY_FILLS, DEFAULT_HIERARCHY_STROKES: () => DEFAULT_HIERARCHY_STROKES, DEFAULT_POLAR_SERIES_STROKE: () => DEFAULT_POLAR_SERIES_STROKE, DEFAULT_SEPARATION_LINES_COLOUR: () => DEFAULT_SEPARATION_LINES_COLOUR, DEFAULT_SHADOW_COLOUR: () => DEFAULT_SHADOW_COLOUR, DEFAULT_SPARKLINE_CROSSHAIR_STROKE: () => DEFAULT_SPARKLINE_CROSSHAIR_STROKE, DEFAULT_TEXTBOX_COLOR: () => DEFAULT_TEXTBOX_COLOR, DEFAULT_TEXTBOX_FILL: () => DEFAULT_TEXTBOX_FILL, DEFAULT_TEXTBOX_STROKE: () => DEFAULT_TEXTBOX_STROKE, DEFAULT_TEXT_ANNOTATION_COLOR: () => DEFAULT_TEXT_ANNOTATION_COLOR, DEFAULT_TOOLBAR_POSITION: () => DEFAULT_TOOLBAR_POSITION, IS_COMMUNITY: () => IS_COMMUNITY, IS_DARK_THEME: () => IS_DARK_THEME, IS_ENTERPRISE: () => IS_ENTERPRISE, PALETTE_ALT_DOWN_FILL: () => PALETTE_ALT_DOWN_FILL, PALETTE_ALT_DOWN_STROKE: () => PALETTE_ALT_DOWN_STROKE, PALETTE_ALT_NEUTRAL_FILL: () => PALETTE_ALT_NEUTRAL_FILL, PALETTE_ALT_NEUTRAL_STROKE: () => PALETTE_ALT_NEUTRAL_STROKE, PALETTE_ALT_UP_FILL: () => PALETTE_ALT_UP_FILL, PALETTE_ALT_UP_STROKE: () => PALETTE_ALT_UP_STROKE, PALETTE_DOWN_FILL: () => PALETTE_DOWN_FILL, PALETTE_DOWN_STROKE: () => PALETTE_DOWN_STROKE, PALETTE_NEUTRAL_FILL: () => PALETTE_NEUTRAL_FILL, PALETTE_NEUTRAL_STROKE: () => PALETTE_NEUTRAL_STROKE, PALETTE_UP_FILL: () => PALETTE_UP_FILL, PALETTE_UP_STROKE: () => PALETTE_UP_STROKE, getChartTheme: () => getChartTheme, themeNames: () => themeNames, themeSymbols: () => symbols_exports, themes: () => themes }); var themeNames; var init_integrated_charts_theme = __esm({ "packages/ag-charts-community/src/integrated-charts-theme.ts"() { "use strict"; init_themes(); init_themes(); init_symbols(); init_chartTheme(); init_themes(); init_symbols(); themeNames = Object.keys(themes); } }); // packages/ag-charts-community/src/integrated-charts-util.ts var integrated_charts_util_exports = {}; __export(integrated_charts_util_exports, { Color: () => Color, interpolateColor: () => interpolateColor }); var init_integrated_charts_util = __esm({ "packages/ag-charts-community/src/integrated-charts-util.ts"() { "use strict"; init_color(); init_interpolate(); } }); // packages/ag-charts-community/src/util/deprecation.ts function createDeprecationWarning() { return (key, message) => { const msg = [`Property [${key}] is deprecated.`, message].filter(Boolean).join(" "); logger_exports.warnOnce(msg); }; } function Deprecated(message, opts) { const warnDeprecated = createDeprecationWarning(); const def = opts?.default; return addTransformToInstanceProperty((_, key, value) => { if (value !== def) { warnDeprecated(key.toString(), message); } return value; }); } function DeprecatedAndRenamedTo(newPropName, mapValue) { const warnDeprecated = createDeprecationWarning(); return addTransformToInstanceProperty( (target, key, value) => { if (value !== target[newPropName]) { warnDeprecated(key.toString(), `Use [${newPropName}] instead.`); setPath(target, newPropName, mapValue ? mapValue(value) : value); } return BREAK_TRANSFORM_CHAIN; }, (target, key) => { warnDeprecated(key.toString(), `Use [${newPropName}] instead.`); return getPath(target, newPropName); } ); } var init_deprecation = __esm({ "packages/ag-charts-community/src/util/deprecation.ts"() { "use strict"; init_main(); init_decorator(); init_object(); } }); // packages/ag-charts-community/src/util/vector.ts function add(a, b) { if (typeof b === "number") { return { x: a.x + b, y: a.y + b }; } return { x: a.x + b.x, y: a.y + b.y }; } function sub(a, b) { if (typeof b === "number") { return { x: a.x - b, y: a.y - b }; } return { x: a.x - b.x, y: a.y - b.y }; } function multiply(a, b) { if (typeof b === "number") { return { x: a.x * b, y: a.y * b }; } return { x: a.x * b.x, y: a.y * b.y }; } function length(a) { return Math.sqrt(a.x * a.x + a.y * a.y); } function lengthSquared(a) { return a.x * a.x + a.y * a.y; } function distance(a, b) { const d = sub(a, b); return Math.sqrt(d.x * d.x + d.y * d.y); } function distanceSquared(a, b) { const d = sub(a, b); return d.x * d.x + d.y * d.y; } function normalized(a) { const l = length(a); return { x: a.x / l, y: a.y / l }; } function angle(a, b = origin2()) { return Math.atan2(a.y, a.x) - Math.atan2(b.y, b.x); } function rotate(a, theta, b = origin2()) { const l = length(a); return { x: b.x + l * Math.cos(theta), y: b.y + l * Math.sin(theta) }; } function gradient(a, b, reflection) { const dx2 = b.x - a.x; const dy2 = reflection == null ? b.y - a.y : reflection - b.y - (reflection - a.y); return dy2 / dx2; } function intercept(a, gradient2, reflection) { const y = reflection == null ? a.y : reflection - a.y; return y - gradient2 * a.x; } function intersectAtY(gradient2, coefficient, y = 0, reflection) { return { x: gradient2 === Infinity ? Infinity : (y - coefficient) / gradient2, y: reflection == null ? y : reflection - y }; } function intersectAtX(gradient2, coefficient, x = 0, reflection) { const y = gradient2 === Infinity ? Infinity : gradient2 * x + coefficient; return { x, y: reflection == null ? y : reflection - y }; } function round4(a) { return { x: Math.round(a.x), y: Math.round(a.y) }; } function equal(a, b) { return a.x === b.x && a.y === b.y; } function from2(a, b) { if (typeof a === "number") { return { x: a, y: b }; } if ("currentX" in a) { return { x: a.currentX, y: a.currentY }; } if ("offsetWidth" in a) { return { x: a.offsetWidth, y: a.offsetHeight }; } if ("width" in a) { return [ { x: a.x, y: a.y }, { x: a.x + a.width, y: a.y + a.height } ]; } if ("x1" in a) { return [ { x: a.x1, y: a.y1 }, { x: a.x2, y: a.y2 } ]; } throw new Error(`Values can not be converted into a vector: [${JSON.stringify(a)}] [${b}]`); } function apply(a, b) { a.x = b.x; a.y = b.y; return a; } function required(a) { return { x: a?.x ?? 0, y: a?.y ?? 0 }; } function origin2() { return { x: 0, y: 0 }; } var Vec2; var init_vector = __esm({ "packages/ag-charts-community/src/util/vector.ts"() { "use strict"; Vec2 = { add, angle, apply, equal, distance, distanceSquared, from: from2, gradient, intercept, intersectAtX, intersectAtY, length, lengthSquared, multiply, normalized, origin: origin2, required, rotate, round: round4, sub }; } }); // packages/ag-charts-community/src/module/axisModule.ts var init_axisModule = __esm({ "packages/ag-charts-community/src/module/axisModule.ts"() { "use strict"; } }); // packages/ag-charts-community/src/module/axisOptionModule.ts var init_axisOptionModule = __esm({ "packages/ag-charts-community/src/module/axisOptionModule.ts"() { "use strict"; } }); // packages/ag-charts-community/src/module/baseModule.ts var init_baseModule = __esm({ "packages/ag-charts-community/src/module/baseModule.ts"() { "use strict"; } }); // packages/ag-charts-community/src/module/coreModules.ts var init_coreModules = __esm({ "packages/ag-charts-community/src/module/coreModules.ts"() { "use strict"; } }); // packages/ag-charts-community/src/module/optionsModuleTypes.ts var init_optionsModuleTypes = __esm({ "packages/ag-charts-community/src/module/optionsModuleTypes.ts"() { "use strict"; } }); // packages/ag-charts-community/src/module/axisContext.ts var init_axisContext = __esm({ "packages/ag-charts-community/src/module/axisContext.ts"() { "use strict"; } }); // packages/ag-charts-community/src/module/moduleContext.ts var init_moduleContext = __esm({ "packages/ag-charts-community/src/module/moduleContext.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/chartAnimationPhase.ts var init_chartAnimationPhase = __esm({ "packages/ag-charts-community/src/chart/chartAnimationPhase.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/series/seriesEvents.ts var init_seriesEvents = __esm({ "packages/ag-charts-community/src/chart/series/seriesEvents.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/series/seriesTypes.ts var init_seriesTypes = __esm({ "packages/ag-charts-community/src/chart/series/seriesTypes.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/series/hierarchy/hierarchySeries.ts var _HierarchyNode, HierarchyNode, HierarchySeries; var init_hierarchySeries = __esm({ "packages/ag-charts-community/src/chart/series/hierarchy/hierarchySeries.ts"() { "use strict"; init_main(); init_colorScale(); init_number(); init_stateMachine(); init_series(); _HierarchyNode = class _HierarchyNode { constructor(series, datumIndex, datum, sizeValue, colorValue, sumSize, depth, parent, children) { this.series = series; this.datumIndex = datumIndex; this.datum = datum; this.sizeValue = sizeValue; this.colorValue = colorValue; this.sumSize = sumSize; this.depth = depth; this.parent = parent; this.children = children; this.midPoint = { x: 0, y: 0 }; } get hasChildren() { return this.children.length > 0; } walk(callback2, order = _HierarchyNode.Walk.PreOrder) { if (order === _HierarchyNode.Walk.PreOrder) { callback2(this); } this.children.forEach((child) => { child.walk(callback2, order); }); if (order === _HierarchyNode.Walk.PostOrder) { callback2(this); } } *[Symbol.iterator]() { yield this; for (const child of this.children) { yield* child; } } }; _HierarchyNode.Walk = { PreOrder: 0, PostOrder: 1 }; HierarchyNode = _HierarchyNode; HierarchySeries = class extends Series { constructor(moduleCtx) { super({ moduleCtx, pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */] }); this.colorDomain = [0, 0]; this.maxDepth = 0; this.colorScale = new ColorScale(); this.animationState = new StateMachine( "empty", { empty: { update: { target: "ready", action: (data) => this.animateEmptyUpdateReady(data) }, reset: "empty", skip: "ready" }, ready: { updateData: "waiting", clear: "clearing", highlight: (data) => this.animateReadyHighlight(data), resize: (data) => this.animateReadyResize(data), reset: "empty", skip: "ready" }, waiting: { update: { target: "ready", action: (data) => this.animateWaitingUpdateReady(data) }, reset: "empty", skip: "ready" }, clearing: { update: { target: "empty", action: (data) => this.animateClearingUpdateEmpty(data) }, reset: "empty", skip: "ready" } }, () => this.checkProcessedDataAnimatable() ); } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } else if (phase === "ready") { this.animationState.transition("skip"); } } processData() { const { NodeClass } = this; const { childrenKey, sizeKey, colorKey, colorRange } = this.properties; let maxDepth = 0; let minColor = Infinity; let maxColor = -Infinity; const createNode = (datum, indexPath, parent) => { const depth = parent.depth != null ? parent.depth + 1 : 0; const children = childrenKey != null ? datum[childrenKey] : void 0; const isLeaf = children == null || children.length === 0; let sizeValue = sizeKey != null ? datum[sizeKey] : void 0; if (Number.isFinite(sizeValue)) { sizeValue = Math.max(sizeValue, 0); } else { sizeValue = isLeaf ? 1 : 0; } const sumSize = sizeValue; maxDepth = Math.max(maxDepth, depth); const colorValue = colorKey != null ? datum[colorKey] : void 0; if (typeof colorValue === "number") { minColor = Math.min(minColor, colorValue); maxColor = Math.max(maxColor, colorValue); } return appendChildren( new NodeClass(this, indexPath, datum, sizeValue, colorValue, sumSize, depth, parent, []), children ); }; const appendChildren = (node, data) => { const { datumIndex } = node; data?.forEach((datum, childIndex) => { const child = createNode(datum, datumIndex.concat(childIndex), node); node.children.push(child); node.sumSize += child.sumSize; }); return node; }; const rootNode = appendChildren( new NodeClass(this, [], void 0, 0, void 0, 0, void 0, void 0, []), this.data ); const colorDomain = [minColor, maxColor]; this.colorScale.domain = minColor < maxColor ? [minColor, maxColor] : [0, 1]; this.colorScale.range = colorRange ?? ["black"]; this.colorScale.update(); this.rootNode = rootNode; this.maxDepth = maxDepth; this.colorDomain = colorDomain; } update({ seriesRect }) { this.updateSelections(); this.updateNodes(); const animationData = this.getAnimationData(); const resize = this.checkResize(seriesRect); if (resize) { this.animationState.transition("resize", animationData); } this.animationState.transition("update", animationData); } resetAllAnimation(_data) { this.ctx.animationManager.stopByAnimationGroupId(this.id); } animateEmptyUpdateReady(data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(data); } animateWaitingUpdateReady(data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(data); } animateReadyHighlight(_data) { } animateReadyResize(data) { this.resetAllAnimation(data); } animateClearingUpdateEmpty(data) { this.ctx.animationManager.skipCurrentBatch(); this.resetAllAnimation(data); } getAnimationData() { return {}; } isProcessedDataAnimatable() { return true; } checkProcessedDataAnimatable() { if (!this.isProcessedDataAnimatable()) { this.ctx.animationManager.skipCurrentBatch(); } } getSeriesDomain() { return [NaN, NaN]; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } getLegendData(legendType) { const { colorKey, colorName, colorRange } = this.properties; const { id: seriesId, ctx: { legendManager }, visible } = this; return legendType === "gradient" && colorKey != null && colorRange != null ? [ { legendType: "gradient", enabled: visible && legendManager.getItemEnabled({ seriesId }), seriesId, colorName, colorRange, colorDomain: this.colorDomain } ] : []; } getDatumIdFromData(node) { return node.datumIndex.join(":"); } getDatumId(node) { return this.getDatumIdFromData(node); } removeMeIndexPathForIndex(index) { return this.datumSelection.at(index + 1)?.datum.datumIndex ?? []; } removeMeIndexForIndexPath(indexPath) { for (const { index, datum } of this.datumSelection) { if (arraysEqual(datum.datumIndex, indexPath)) { return index - 1; } } return 0; } pickFocus(opts) { if (!this.rootNode?.children.length) return void 0; const index = clamp(0, opts.datumIndex - opts.datumIndexDelta, this.datumSelection.length - 1); const { datumIndexDelta: childDelta, otherIndexDelta: depthDelta } = opts; let path = this.removeMeIndexPathForIndex(index); const currentNode = path.reduce((n, childIndex) => n.children[childIndex], this.rootNode); if (depthDelta > 0 && currentNode.hasChildren) { path = [...path, 0]; } else if (depthDelta < 0 && path.length > 1) { path = path.slice(0, -1); } else if (depthDelta === 0 && childDelta !== 0) { const maxIndex = currentNode.parent.children.length - 1; path = path.slice(); path[path.length - 1] = clamp(0, path[path.length - 1] + childDelta, maxIndex); } const nextNode = path.reduce((n, childIndex) => n.children[childIndex], this.rootNode); const bounds = this.computeFocusBounds(this.datumSelection.at(index + 1)); if (bounds == null) return; return { datum: nextNode, datumIndex: this.removeMeIndexForIndexPath(path), otherIndex: nextNode.depth, bounds, clipFocusBox: true }; } getDatumAriaText(datum, description) { if (!(datum instanceof this.NodeClass)) { logger_exports.error(`datum is not HierarchyNode: ${JSON.stringify(datum)}`); return; } return this.ctx.localeManager.t("ariaAnnounceHierarchyDatum", { level: (datum.depth ?? -1) + 1, count: datum.children.length, description }); } }; } }); // packages/ag-charts-community/src/chart/series/hierarchy/hierarchySeriesProperties.ts var HierarchySeriesProperties; var init_hierarchySeriesProperties = __esm({ "packages/ag-charts-community/src/chart/series/hierarchy/hierarchySeriesProperties.ts"() { "use strict"; init_validation2(); init_defaultColors(); init_seriesProperties(); HierarchySeriesProperties = class extends SeriesProperties { constructor() { super(...arguments); this.childrenKey = "children"; this.fills = Object.values(DEFAULT_FILLS); this.strokes = Object.values(DEFAULT_STROKES); } }; __decorateClass([ Validate(STRING) ], HierarchySeriesProperties.prototype, "childrenKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], HierarchySeriesProperties.prototype, "sizeKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], HierarchySeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate(STRING, { optional: true }) ], HierarchySeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], HierarchySeriesProperties.prototype, "fills", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY) ], HierarchySeriesProperties.prototype, "strokes", 2); __decorateClass([ Validate(COLOR_STRING_ARRAY, { optional: true }) ], HierarchySeriesProperties.prototype, "colorRange", 2); } }); // packages/ag-charts-community/src/chart/series/topologySeries.ts var init_topologySeries = __esm({ "packages/ag-charts-community/src/chart/series/topologySeries.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/series/flowProportionSeries.ts var init_flowProportionSeries = __esm({ "packages/ag-charts-community/src/chart/series/flowProportionSeries.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/series/topology/geojson.ts var init_geojson = __esm({ "packages/ag-charts-community/src/chart/series/topology/geojson.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/series/topology/lonLatBbox.ts var LonLatBBox; var init_lonLatBbox = __esm({ "packages/ag-charts-community/src/chart/series/topology/lonLatBbox.ts"() { "use strict"; LonLatBBox = class { constructor(lon0, lat0, lon1, lat1) { this.lon0 = lon0; this.lat0 = lat0; this.lon1 = lon1; this.lat1 = lat1; } merge(other) { this.lon0 = Math.min(this.lon0, other.lon0); this.lat0 = Math.min(this.lat0, other.lat0); this.lon1 = Math.max(this.lon1, other.lon1); this.lat1 = Math.max(this.lat1, other.lat1); } }; } }); // packages/ag-charts-community/src/chart/series/topology/mercatorScale.ts var radsInDeg, lonX, latY, xLon, yLat, MercatorScale; var init_mercatorScale = __esm({ "packages/ag-charts-community/src/chart/series/topology/mercatorScale.ts"() { "use strict"; init_abstractScale(); init_bbox(); radsInDeg = Math.PI / 180; lonX = (lon) => lon * radsInDeg; latY = (lat) => -Math.log(Math.tan(Math.PI * 0.25 + lat * radsInDeg * 0.5)); xLon = (x) => x / radsInDeg; yLat = (y) => (Math.atan(Math.exp(-y)) - Math.PI * 0.25) / (radsInDeg * 0.5); MercatorScale = class _MercatorScale extends AbstractScale { constructor(domain, range4) { super(); this.domain = domain; this.range = range4; this.type = "mercator"; this.bounds = _MercatorScale.bounds(domain); } static bounds(domain) { const [[lon0, lat0], [lon1, lat1]] = domain; const x0 = lonX(lon0); const y0 = latY(lat0); const x1 = lonX(lon1); const y1 = latY(lat1); return new BBox(Math.min(x0, x1), Math.min(y0, y1), Math.abs(x1 - x0), Math.abs(y1 - y0)); } static fixedScale() { return new _MercatorScale( [ [xLon(0), yLat(0)], [xLon(1), yLat(1)] ], [ [0, 0], [1, 1] ] ); } toDomain() { return; } normalizeDomains(...domains) { let x0 = -Infinity; let x1 = Infinity; let y0 = -Infinity; let y1 = Infinity; for (const domain of domains) { for (const [x, y] of domain) { x0 = Math.min(x, x0); x1 = Math.max(x, x1); y0 = Math.min(y, y0); y1 = Math.max(y, y1); } } return { domain: [ [x0, y0], [x1, y1] ], animatable: true }; } convert([lon, lat]) { const [[x0, y0], [x1, y1]] = this.range; const xScale = (x1 - x0) / this.bounds.width; const yScale = (y1 - y0) / this.bounds.height; return [(lonX(lon) - this.bounds.x) * xScale + x0, (latY(lat) - this.bounds.y) * yScale + y0]; } invert([x, y]) { const [[x0, y0], [x1, y1]] = this.range; const xScale = (x1 - x0) / this.bounds.width; const yScale = (y1 - y0) / this.bounds.height; return [xLon((x - x0) / xScale + this.bounds.x), yLat((y - y0) / yScale + this.bounds.y)]; } }; } }); // packages/ag-charts-community/src/chart/series/gaugeSeries.ts var init_gaugeSeries = __esm({ "packages/ag-charts-community/src/chart/series/gaugeSeries.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/axis/axisTicks.ts var _AxisTicks, AxisTicks; var init_axisTicks = __esm({ "packages/ag-charts-community/src/chart/axis/axisTicks.ts"() { "use strict"; init_linearScale(); init_bbox(); init_group(); init_selection(); init_text(); init_format_util(); init_id(); init_number(); init_tempUtils(); init_textMeasurer(); init_ticks(); init_axisInterval(); init_axisLabel(); _AxisTicks = class _AxisTicks { constructor() { this.id = createId(this); this.axisGroup = new TranslatableGroup({ name: `${this.id}-AxisTicks`, zIndex: 2 /* AXIS */ }); this.labelSelection = Selection.select(this.axisGroup, Text); this.interval = new AxisInterval(); this.label = new AxisLabel(); this.scale = new LinearScale(); this.position = "bottom"; this.translationX = 0; this.translationY = 0; this.padding = 0; } attachAxis(axisNode) { axisNode.appendChild(this.axisGroup); } calculateLayout() { const boxes = []; const tickData = this.generateTicks(); const { translationX, translationY } = this; this.labelSelection.update( tickData.ticks.map((d) => this.createLabelDatum(d)), void 0, (datum) => datum.tickId ); this.labelSelection.each((node, datum) => { node.setProperties(datum); if (datum.visible) { boxes.push(node.getBBox()); } }); this.axisGroup.setProperties({ translationX, translationY }); return BBox.merge(boxes); } getLabelParams(datum) { const { padding } = this; const { translate: translate2 } = datum; switch (this.position) { case "top": case "bottom": return { x: translate2, y: padding, textAlign: "center", textBaseline: "top" }; case "left": case "right": return { x: padding, y: translate2, textAlign: "start", textBaseline: "middle" }; } } inRange(x, tolerance = 1e-3) { const [min, max] = findMinMax(this.scale.range); return x >= min - tolerance && x <= max + tolerance; } createLabelDatum(datum) { const { x, y, textBaseline, textAlign } = this.getLabelParams(datum); return { visible: Boolean(datum.tickLabel), tickId: datum.tickId, fill: this.label.color, fontFamily: this.label.fontFamily, fontSize: this.label.fontSize, fontStyle: this.label.fontStyle, fontWeight: this.label.fontWeight, rotation: 0, rotationCenterX: 0, text: datum.tickLabel, textAlign, textBaseline, x, y }; } generateTicks() { const { minSpacing, maxSpacing } = this.interval; const { maxTickCount, minTickCount, tickCount } = estimateTickCount( findRangeExtent(this.scale.range), 1, minSpacing, maxSpacing, _AxisTicks.DefaultTickCount, _AxisTicks.DefaultMinSpacing ); const tickData = this.getTicksData({ nice: true, interval: this.interval.step, tickCount, minTickCount, maxTickCount }); if (this.position === "bottom" || this.position === "top") { const measurer3 = CachedTextMeasurerPool.getMeasurer({ font: this.label }); const { domain } = this.scale; const reversed = domain[0] > domain[1]; const direction = reversed ? -1 : 1; let lastTickPosition = -Infinity * direction; tickData.ticks = tickData.ticks.filter((data) => { if (Math.sign(data.translate - lastTickPosition) !== direction) return false; lastTickPosition = data.translate + measurer3.textWidth(data.tickLabel, true) * direction; return true; }); } return tickData; } getTicksData(tickParams) { const ticks = []; const niceDomain = tickParams.nice ? this.scale.niceDomain(tickParams) : this.scale.domain; const rawTicks = this.scale.ticks(tickParams, niceDomain); const fractionDigits = rawTicks.reduce((max, tick) => Math.max(max, countFractionDigits(tick)), 0); const idGenerator = createIdsGenerator(); const labelFormatter = this.label.format ? this.scale.tickFormatter({ domain: niceDomain, ticks: rawTicks, fractionDigits, specifier: this.label.format }) : (x) => formatValue(x, fractionDigits); for (let index = 0; index < rawTicks.length; index++) { const tick = rawTicks[index]; const translate2 = this.scale.convert(tick); if (!this.inRange(translate2)) continue; const tickLabel = this.label.formatter?.({ value: tick, index, fractionDigits }) ?? labelFormatter(tick); const tickId = idGenerator(tickLabel); ticks.push({ tick, tickId, tickLabel, translate: translate2 }); } return { rawTicks, fractionDigits, ticks }; } }; _AxisTicks.DefaultTickCount = 5; _AxisTicks.DefaultMinSpacing = 10; AxisTicks = _AxisTicks; } }); // packages/ag-charts-community/src/chart/chartAxis.ts var init_chartAxis = __esm({ "packages/ag-charts-community/src/chart/chartAxis.ts"() { "use strict"; } }); // packages/ag-charts-community/src/chart/legend/legendDatum.ts var init_legendDatum = __esm({ "packages/ag-charts-community/src/chart/legend/legendDatum.ts"() { "use strict"; } }); // packages/ag-charts-community/src/dom/elements.ts function createButton(options, attrs) { const button = createElement("button", getClassName("ag-charts-input ag-charts-button", attrs)); if (options.label !== void 0) { button.append(options.label); } else { button.append(createIcon(options.icon)); button.ariaLabel = options.altText; } button.addEventListener("click", options.onPress); setAttributes(button, attrs); return button; } function createCheckbox(options, attrs) { const checkbox = createElement("input", getClassName("ag-charts-input ag-charts-checkbox", attrs)); checkbox.type = "checkbox"; checkbox.checked = options.checked; checkbox.addEventListener("change", (event) => options.onChange(checkbox.checked, event)); checkbox.addEventListener("keydown", (event) => { if (isButtonClickEvent(event)) { event.preventDefault(); checkbox.click(); } }); setAttributes(checkbox, attrs); return checkbox; } function createSelect(options, attrs) { const select = createElement("select", getClassName("ag-charts-input ag-charts-select", attrs)); select.append( ...options.options.map((option) => { const optionEl = createElement("option"); optionEl.value = option.value; optionEl.textContent = option.label; return optionEl; }) ); setAttribute(select, "data-preventdefault", false); select.value = options.value; select.addEventListener("change", (event) => options.onChange(select.value, event)); setAttributes(select, attrs); return select; } function createTextArea(options, attrs) { const textArea = createElement("textarea", getClassName("ag-charts-input ag-charts-textarea", attrs)); textArea.value = options.value; textArea.addEventListener("input", (event) => options.onChange(textArea.value, event)); setAttributes(textArea, attrs); setAttribute(textArea, "data-preventdefault", false); return textArea; } function createIcon(icon) { const el = createElement("span", `ag-charts-icon ag-charts-icon-${icon}`); setAttribute(el, "aria-hidden", true); return el; } function getClassName(baseClass, attrs) { if (attrs == null) return baseClass; return `${baseClass} ${attrs.class}`; } var init_elements = __esm({ "packages/ag-charts-community/src/dom/elements.ts"() { "use strict"; init_core(); init_attributeUtil(); init_keynavUtil(); } }); // packages/ag-charts-community/src/scale/scale.ts var init_scale = __esm({ "packages/ag-charts-community/src/scale/scale.ts"() { "use strict"; } }); // packages/ag-charts-community/src/scene/gradient/conicGradient.ts var ConicGradient; var init_conicGradient = __esm({ "packages/ag-charts-community/src/scene/gradient/conicGradient.ts"() { "use strict"; init_angle(); init_gradient(); ConicGradient = class extends Gradient { constructor(colorSpace, stops, angle2 = 0, bbox) { super(colorSpace, stops, bbox); this.angle = angle2; } createCanvasGradient(ctx, bbox) { const angleOffset = 90; const { angle: angle2 } = this; const radians = normalizeAngle360(toRadians(angle2 + angleOffset)); const cx = bbox.x + bbox.width * 0.5; const cy = bbox.y + bbox.height * 0.5; return ctx.createConicGradient(radians, cx, cy); } }; } }); // packages/ag-charts-community/src/scene/shape/svgPath.ts var SvgPath; var init_svgPath = __esm({ "packages/ag-charts-community/src/scene/shape/svgPath.ts"() { "use strict"; init_path(); SvgPath = class extends Path { constructor(d = "") { super(); this.x = 0; this.y = 0; this.commands = []; this._d = ""; this.d = d; } get d() { return this._d; } set d(d) { if (d === this._d) return; this._d = d; this.commands.length = 0; for (const [_, command, paramsString] of d.matchAll(/([A-Z])([0-9. ]*)/g)) { const params = paramsString.split(/\s+/g).map(Number); this.commands.push([command, params]); } this.checkPathDirty(); } updatePath() { const { path, x, y } = this; path.clear(); let lastX = x; let lastY = y; for (const [command, params] of this.commands) { switch (command) { case "M": path.moveTo(x + params[0], y + params[1]); lastX = x + params[0]; break; case "C": path.cubicCurveTo( x + params[0], y + params[1], x + params[2], y + params[3], x + params[4], y + params[5] ); lastX = x + params[4]; lastY = y + params[5]; break; case "H": path.lineTo(x + params[0], lastY); lastX = y + params[0]; break; case "L": path.lineTo(x + params[0], y + params[1]); lastX = x + params[0]; lastY = y + params[1]; break; case "V": path.lineTo(lastX, y + params[0]); lastY = y + params[0]; break; case "Z": path.closePath(); break; default: throw new Error(`Could not translate command '${command}' with '${params.join(" ")}'`); } } path.closePath(); } }; __decorateClass([ ScenePathChangeDetection() ], SvgPath.prototype, "x", 2); __decorateClass([ ScenePathChangeDetection() ], SvgPath.prototype, "y", 2); } }); // packages/ag-charts-community/src/scene/image.ts var Image; var init_image = __esm({ "packages/ag-charts-community/src/scene/image.ts"() { "use strict"; init_node(); Image = class extends Node { constructor(sourceImage) { super(); this.sourceImage = sourceImage; this.x = 0; this.y = 0; this.width = 0; this.height = 0; this.opacity = 1; } render(renderCtx) { const { ctx } = renderCtx; const image = this.sourceImage; if (image) { ctx.globalAlpha = this.opacity; ctx.drawImage(image, 0, 0, image.width, image.height, this.x, this.y, this.width, this.height); } super.render(renderCtx); } }; __decorateClass([ SceneChangeDetection() ], Image.prototype, "x", 2); __decorateClass([ SceneChangeDetection() ], Image.prototype, "y", 2); __decorateClass([ SceneChangeDetection() ], Image.prototype, "width", 2); __decorateClass([ SceneChangeDetection() ], Image.prototype, "height", 2); __decorateClass([ SceneChangeDetection() ], Image.prototype, "opacity", 2); } }); // packages/ag-charts-community/src/widget/exports.ts var exports_exports = {}; __export(exports_exports, { ButtonWidget: () => ButtonWidget, NativeWidget: () => NativeWidget, SliderWidget: () => SliderWidget, ToolbarWidget: () => ToolbarWidget, WIDGET_HTML_EVENTS: () => WIDGET_HTML_EVENTS, Widget: () => Widget, WidgetEventUtil: () => WidgetEventUtil }); var init_exports = __esm({ "packages/ag-charts-community/src/widget/exports.ts"() { "use strict"; init_widget(); init_widgetEvents(); init_nativeWidget(); init_toolbarWidget(); init_buttonWidget(); init_sliderWidget(); } }); // packages/ag-charts-community/src/components/popover/popover.ts var canvasOverlay, Popover; var init_popover = __esm({ "packages/ag-charts-community/src/components/popover/popover.ts"() { "use strict"; init_core(); init_module(); init_keynavUtil(); canvasOverlay = "canvas-overlay"; Popover = class extends BaseModuleInstance { constructor(ctx, id, options) { super(); this.ctx = ctx; this.hideFns = []; this.moduleId = `popover-${id}`; if (options?.detached) { this.element = createElement("div"); } else { this.element = ctx.domManager.addChild(canvasOverlay, this.moduleId); } this.element.setAttribute("role", "presentation"); this.destroyFns.push(() => ctx.domManager.removeChild(canvasOverlay, this.moduleId)); } attachTo(popover) { if (this.element.parentElement) return; popover.element.append(this.element); } hide(opts) { const { lastFocus = this.lastFocus } = opts ?? {}; if (this.element.children.length === 0) return; this.hideFns.forEach((fn) => fn()); lastFocus?.focus(); this.lastFocus = void 0; } removeChildren() { this.element.replaceChildren(); } showWithChildren(children, options) { if (!this.element.parentElement) { throw new Error("Can not show popover that has not been attached to a parent."); } const popover = createElement("div", "ag-charts-popover"); if (options.ariaLabel != null) { popover.setAttribute("aria-label", options.ariaLabel); } if (options.class != null) { popover.classList.add(options.class); } popover.replaceChildren(...children); this.element.replaceChildren(popover); this.hideFns.push(() => this.removeChildren()); if (options.onHide) { this.hideFns.push(options.onHide); } if (options.initialFocus && options.sourceEvent) { const lastFocus = getLastFocus(options.sourceEvent); if (lastFocus !== void 0) { this.lastFocus = lastFocus; this.initialFocus = options.initialFocus; } } return popover; } getPopoverElement() { return this.element.firstElementChild; } updatePosition(position) { const popover = this.getPopoverElement(); if (!popover) return; popover.style.setProperty("right", "unset"); popover.style.setProperty("bottom", "unset"); if (position.x != null) popover.style.setProperty("left", `${Math.floor(position.x)}px`); if (position.y != null) popover.style.setProperty("top", `${Math.floor(position.y)}px`); this.initialFocus?.focus(); this.initialFocus = void 0; } }; } }); // packages/ag-charts-community/src/components/popover/anchoredPopover.ts var AnchoredPopover; var init_anchoredPopover = __esm({ "packages/ag-charts-community/src/components/popover/anchoredPopover.ts"() { "use strict"; init_core(); init_number(); init_popover(); AnchoredPopover = class extends Popover { setAnchor(anchor, fallbackAnchor) { this.anchor = anchor; this.fallbackAnchor = fallbackAnchor; this.updatePosition(anchor); this.repositionWithinBounds(); } showWithChildren(children, options) { const anchor = options.anchor ?? this.anchor; const fallbackAnchor = options.fallbackAnchor ?? this.fallbackAnchor; const popover = super.showWithChildren(children, options); if (anchor) { this.setAnchor(anchor, fallbackAnchor); } getWindow().requestAnimationFrame(() => { this.repositionWithinBounds(); }); return popover; } repositionWithinBounds() { const { anchor, ctx, fallbackAnchor } = this; const popover = this.getPopoverElement(); if (!anchor || !popover) return; const canvasRect = ctx.domManager.getBoundingClientRect(); const { offsetWidth: width2, offsetHeight: height2 } = popover; let x = clamp(0, anchor.x, canvasRect.width - width2); let y = clamp(0, anchor.y, canvasRect.height - height2); if (x !== anchor.x && fallbackAnchor?.x != null) { x = clamp(0, fallbackAnchor.x - width2, canvasRect.width - width2); } if (y !== anchor.y && fallbackAnchor?.y != null) { y = clamp(0, fallbackAnchor.y - height2, canvasRect.height - height2); } this.updatePosition({ x, y }); } }; } }); // packages/ag-charts-community/src/components/menu/menu.ts var Menu; var init_menu = __esm({ "packages/ag-charts-community/src/components/menu/menu.ts"() { "use strict"; init_core(); init_dom(); init_keynavUtil(); init_anchoredPopover(); Menu = class extends AnchoredPopover { show(options) { const rows = options.items.map((item) => this.createRow(options, item)); const popover = this.showWithChildren(rows, options); popover.classList.add("ag-charts-menu"); popover.setAttribute("role", "menu"); this.menuCloser = initMenuKeyNav({ orientation: "vertical", menu: popover, buttons: rows, sourceEvent: options.sourceEvent, closeCallback: () => this.hide() }); this.hideFns.push(() => { this.menuCloser?.finishClosing(); this.menuCloser = void 0; }); } createRow(options, item) { const { menuItemRole = "menuitem" } = options; const active = item.value === options.value; const row = createElement("div", "ag-charts-menu__row"); row.setAttribute("role", menuItemRole); if (menuItemRole === "menuitemradio") { row.setAttribute("aria-checked", (options.value === item.value).toString()); } if (typeof item.value === "string") { row.dataset.popoverId = item.value; } row.classList.toggle(`ag-charts-menu__row--active`, active); if (item.icon != null) { const icon = createElement("span", `ag-charts-menu__icon ${getIconClassNames(item.icon)}`); row.appendChild(icon); } const strokeWidthVisible = item.strokeWidth != null; if (strokeWidthVisible) { row.classList.toggle(`ag-charts-menu__row--stroke-width-visible`, strokeWidthVisible); row.style.setProperty("--strokeWidth", strokeWidthVisible ? `${item.strokeWidth}px` : null); } if (item.label != null) { const label = createElement("span", "ag-charts-menu__label"); label.textContent = this.ctx.localeManager.t(item.label); row.appendChild(label); } if ("altText" in item) { row.ariaLabel = this.ctx.localeManager.t(item.altText); } const select = () => { options.onPress?.(item); }; const onclick = (e) => { if (isButtonClickEvent(e)) { select(); e.preventDefault(); e.stopPropagation(); } }; row.addEventListener("keydown", onclick); row.addEventListener("click", onclick); row.addEventListener("mousemove", () => { row.focus({ preventScroll: true }); }); return row; } }; } }); // packages/ag-charts-community/src/components/popover/draggablePopover.ts var DraggablePopover; var init_draggablePopover = __esm({ "packages/ag-charts-community/src/components/popover/draggablePopover.ts"() { "use strict"; init_vector(); init_popover(); DraggablePopover = class extends Popover { constructor() { super(...arguments); this.dragged = false; } setDragHandle(dragHandle) { dragHandle.addListener("drag-start", (event) => { dragHandle.addClass(this.dragHandleDraggingClass); this.onDragStart(event); }); dragHandle.addListener("drag-move", this.onDragMove.bind(this)); dragHandle.addListener("drag-end", () => { dragHandle.removeClass(this.dragHandleDraggingClass); this.onDragEnd.bind(this); }); } onDragStart(event) { const popover = this.getPopoverElement(); if (!popover) return; event.sourceEvent.preventDefault(); this.dragged = true; this.dragStartState = { client: Vec2.from(event.clientX, event.clientY), position: Vec2.from( Number(popover.style.getPropertyValue("left").replace("px", "")), Number(popover.style.getPropertyValue("top").replace("px", "")) ) }; } onDragMove(event) { const { dragStartState } = this; const popover = this.getPopoverElement(); if (!dragStartState || !popover) return; const offset4 = Vec2.sub(Vec2.from(event.clientX, event.clientY), dragStartState.client); const position = Vec2.add(dragStartState.position, offset4); const bounds = this.ctx.domManager.getBoundingClientRect(); const partialPosition = {}; if (position.x >= bounds.x && position.x + popover.offsetWidth <= bounds.width) { partialPosition.x = position.x; } if (position.y >= bounds.y && position.y + popover.offsetHeight <= bounds.height) { partialPosition.y = position.y; } this.updatePosition(partialPosition); } onDragEnd() { this.dragStartState = void 0; } }; } }); // packages/ag-charts-community/src/components/toolbar/toolbarButtonProperties.ts var ToolbarButtonProperties; var init_toolbarButtonProperties = __esm({ "packages/ag-charts-community/src/components/toolbar/toolbarButtonProperties.ts"() { "use strict"; init_properties(); init_validation2(); ToolbarButtonProperties = class extends BaseProperties { }; __decorateClass([ Validate(STRING, { optional: true }) ], ToolbarButtonProperties.prototype, "icon", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ToolbarButtonProperties.prototype, "label", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ToolbarButtonProperties.prototype, "ariaLabel", 2); __decorateClass([ Validate(STRING, { optional: true }) ], ToolbarButtonProperties.prototype, "tooltip", 2); } }); // packages/ag-charts-community/src/components/toolbar/toolbarButtonWidget.ts var ToolbarButtonWidget; var init_toolbarButtonWidget = __esm({ "packages/ag-charts-community/src/components/toolbar/toolbarButtonWidget.ts"() { "use strict"; init_attributeUtil(); init_dom(); init_buttonWidget(); ToolbarButtonWidget = class extends ButtonWidget { constructor(localeManager) { super(); this.localeManager = localeManager; } update(options) { const { localeManager } = this; if (options.tooltip) { this.elem.title = localeManager.t(options.tooltip); } let innerHTML = ""; if (options.icon != null) { innerHTML = ``; } if (options.label != null) { const label = localeManager.t(options.label); innerHTML = `${innerHTML}${label}`; } this.elem.innerHTML = innerHTML; } setChecked(checked) { setAttribute(this.elem, "aria-checked", checked); } }; } }); // packages/ag-charts-community/src/components/toolbar/toolbar.ts var BUTTON_ACTIVE_CLASS, BaseToolbar, Toolbar; var init_toolbar = __esm({ "packages/ag-charts-community/src/components/toolbar/toolbar.ts"() { "use strict"; init_bbox(); init_listeners(); init_properties(); init_toolbarWidget(); init_toolbarButtonWidget(); BUTTON_ACTIVE_CLASS = "ag-charts-toolbar__button--active"; BaseToolbar = class extends ToolbarWidget { constructor(localeManager, orientation = "horizontal") { super(orientation); this.localeManager = localeManager; this.horizontalSpacing = 10; this.verticalSpacing = 10; this.events = new Listeners(); this.hasPrefix = false; this.buttonWidgets = []; this.addClass("ag-charts-toolbar"); this.toggleClass("ag-charts-toolbar--horizontal", orientation === "horizontal"); this.toggleClass("ag-charts-toolbar--vertical", orientation === "vertical"); } addToolbarListener(eventType, handler) { return this.events.addListener(eventType, handler); } clearButtons() { for (const button of this.buttonWidgets) { button.destroy(); } this.buttonWidgets.splice(0); } updateButtons(buttons2) { const { buttonWidgets } = this; for (const [index, button] of buttons2.entries()) { const buttonWidget = this.buttonWidgets.at(index) ?? this.createButton(index, button); buttonWidget.update(button); } for (let index = buttons2.length; index < buttonWidgets.length; index++) { const button = this.buttonWidgets.at(index); button?.destroy(); } this.buttonWidgets.splice(buttons2.length); this.refreshButtonClasses(); } updateButtonByIndex(index, button) { this.buttonWidgets.at(index)?.update(button); } clearActiveButton() { for (const button of this.buttonWidgets) { button.toggleClass(BUTTON_ACTIVE_CLASS, false); } } toggleActiveButtonByIndex(index) { if (index === -1) return; for (const [buttonIndex, button] of this.buttonWidgets.entries()) { button.toggleClass(BUTTON_ACTIVE_CLASS, index != null && index === buttonIndex); } } toggleButtonEnabledByIndex(index, enabled) { if (index === -1) return; this.buttonWidgets.at(index)?.setEnabled(enabled); } toggleSwitchCheckedByIndex(index, checked) { if (index === -1) return; this.buttonWidgets.at(index)?.setChecked(checked); } getButtonBounds() { return this.buttonWidgets.map((buttonWidget) => this.getButtonWidgetBounds(buttonWidget)); } setButtonHiddenByIndex(index, hidden) { this.buttonWidgets.at(index)?.setHidden(hidden); } getButtonWidgetBounds(buttonWidget) { const parent = this.getBounds(); const bounds = buttonWidget.getBounds(); return new BBox(bounds.x + parent.x, bounds.y + parent.y, bounds.width, bounds.height); } refreshButtonClasses() { const { buttonWidgets, hasPrefix } = this; let first2; let last; let section; for (const [index, buttonWidget] of buttonWidgets.entries()) { first2 = !hasPrefix && index === 0 || section != buttonWidget.section; last = index === buttonWidgets.length - 1 || buttonWidget.section != buttonWidgets.at(index + 1)?.section; buttonWidget.toggleClass("ag-charts-toolbar__button--first", first2); buttonWidget.toggleClass("ag-charts-toolbar__button--last", last); buttonWidget.toggleClass("ag-charts-toolbar__button--gap", index > 0 && first2); section = buttonWidget.section; } } createButton(index, button) { const buttonWidget = this.createButtonWidget(); buttonWidget.addClass("ag-charts-toolbar__button"); buttonWidget.addListener("click", (event) => { const buttonOptions = { index, ...button instanceof BaseProperties ? button.toJson() : button }; const buttonBounds = this.getButtonWidgetBounds(buttonWidget); this.events.dispatch("button-pressed", { event, button: buttonOptions, buttonBounds }); }); buttonWidget.addListener("focus", () => { this.events.dispatch("button-focused", { button: { index } }); }); if (button.section) { buttonWidget.section = button.section; } this.buttonWidgets.push(buttonWidget); this.addChild(buttonWidget); return buttonWidget; } }; Toolbar = class extends BaseToolbar { createButtonWidget() { return new ToolbarButtonWidget(this.localeManager); } }; } }); // packages/ag-charts-community/src/components/toolbar/floatingToolbar.ts var FloatingToolbarPopover, FloatingToolbar, DragHandleWidget; var init_floatingToolbar = __esm({ "packages/ag-charts-community/src/components/toolbar/floatingToolbar.ts"() { "use strict"; init_core(); init_bbox(); init_dom(); init_number(); init_nativeWidget(); init_draggablePopover(); init_toolbar(); FloatingToolbarPopover = class extends DraggablePopover { constructor(ctx, id, onPopoverMoved) { super(ctx, id); this.onPopoverMoved = onPopoverMoved; this.dragHandleDraggingClass = "ag-charts-floating-toolbar__drag-handle--dragging"; } show(children, options = {}) { this.showWithChildren(children, { ...options, class: "ag-charts-floating-toolbar" }); } hide() { this.dragged = false; super.hide(); } getBounds() { const element2 = this.getPopoverElement(); return new BBox( element2?.offsetLeft ?? 0, element2?.offsetTop ?? 0, element2?.offsetWidth ?? 0, element2?.offsetHeight ?? 0 ); } hasBeenDragged() { return this.dragged; } setAnchor(anchor, horizontalSpacing, verticalSpacing) { const element2 = this.getPopoverElement(); if (!element2) return; const position = anchor.position ?? "above"; const { offsetWidth: width2, offsetHeight: height2 } = element2; let top = anchor.y - height2 - verticalSpacing; let left = anchor.x - width2 / 2; if (position === "below") { top = anchor.y + verticalSpacing; } else if (position === "right") { top = anchor.y - height2 / 2; left = anchor.x + horizontalSpacing; } else if (position === "above-left") { left = anchor.x; } this.updatePosition({ x: left, y: top }); } ignorePointerEvents() { const element2 = this.getPopoverElement(); if (element2) element2.style.pointerEvents = "none"; } capturePointerEvents() { const element2 = this.getPopoverElement(); if (element2) element2.style.pointerEvents = "unset"; } updatePosition(position) { const bounds = this.getBounds(); const canvasRect = this.ctx.domManager.getBoundingClientRect(); position.x = Math.floor(clamp(0, position.x, canvasRect.width - bounds.width)); position.y = Math.floor(clamp(0, position.y, canvasRect.height - bounds.height)); super.updatePosition(position); this.onPopoverMoved(); } }; FloatingToolbar = class extends BaseToolbar { constructor(ctx, id) { super(ctx.localeManager); this.hasPrefix = true; this.popover = new FloatingToolbarPopover(ctx, id, this.onPopoverMoved.bind(this)); this.dragHandle = new DragHandleWidget(ctx.localeManager.t("toolbarAnnotationsDragHandle")); this.popover.setDragHandle(this.dragHandle); } show(options = {}) { this.popover.show([this.dragHandle.getElement(), this.getElement()], options); } hide() { this.popover.hide(); } setAnchor(anchor) { this.popover.setAnchor(anchor, this.horizontalSpacing, this.verticalSpacing); } hasBeenDragged() { return this.popover.hasBeenDragged(); } ignorePointerEvents() { this.popover.ignorePointerEvents(); } capturePointerEvents() { this.popover.capturePointerEvents(); } onPopoverMoved() { const popoverBounds = this.popover.getBounds(); if (this.popoverBounds?.equals(popoverBounds)) return; this.popoverBounds = popoverBounds.clone(); const buttonBounds = this.getButtonBounds(); this.events.dispatch("toolbar-moved", { popoverBounds, buttonBounds }); } getButtonWidgetBounds(buttonWidget) { const popoverBounds = this.popover.getBounds(); const bounds = super.getButtonWidgetBounds(buttonWidget); const dragHandleBounds = this.dragHandle.getBounds(); return new BBox( bounds.x + popoverBounds.x - dragHandleBounds.width, bounds.y + popoverBounds.y, bounds.width, bounds.height ); } }; DragHandleWidget = class extends NativeWidget { constructor(title) { super(createElement("div", "ag-charts-floating-toolbar__drag-handle")); const icon = new NativeWidget( createElement("span", `${getIconClassNames("drag-handle")} ag-charts-toolbar__icon`) ); icon.setAriaHidden(true); this.addChild(icon); this.elem.title = title; } }; } }); // packages/ag-charts-community/src/module-support.ts var module_support_exports = {}; __export(module_support_exports, { AND: () => AND, ARRAY: () => ARRAY, ARRAY_OF: () => ARRAY_OF, AbstractBarSeries: () => AbstractBarSeries, AbstractBarSeriesProperties: () => AbstractBarSeriesProperties, ActionOnSet: () => ActionOnSet, AnchoredPopover: () => AnchoredPopover, Animation: () => Animation, AnimationManager: () => AnimationManager, Arc: () => Arc2, Axis: () => Axis, AxisGroupZIndexMap: () => AxisGroupZIndexMap, AxisInterval: () => AxisInterval, AxisLabel: () => AxisLabel, AxisTick: () => AxisTick, AxisTickGenerator: () => AxisTickGenerator, AxisTicks: () => AxisTicks, BBox: () => BBox, BBoxValues: () => BBoxValues, BOOLEAN: () => BOOLEAN, BOOLEAN_ARRAY: () => BOOLEAN_ARRAY, Background: () => Background, BackgroundModule: () => BackgroundModule, BandScale: () => BandScale, BarSeries: () => BarSeries, BarSeriesModule: () => BarSeriesModule, BaseModuleInstance: () => BaseModuleInstance, BaseProperties: () => BaseProperties, BaseToolbar: () => BaseToolbar, ButtonWidget: () => ButtonWidget, COLOR_GRADIENT: () => COLOR_GRADIENT, COLOR_STRING: () => COLOR_STRING, COLOR_STRING_ARRAY: () => COLOR_STRING_ARRAY, CachedTextMeasurer: () => CachedTextMeasurer, CachedTextMeasurerPool: () => CachedTextMeasurerPool, Caption: () => Caption, CartesianAxis: () => CartesianAxis, CartesianSeries: () => CartesianSeries, CartesianSeriesNodeEvent: () => CartesianSeriesNodeEvent, CartesianSeriesProperties: () => CartesianSeriesProperties, CategoryAxis: () => CategoryAxis, CategoryScale: () => CategoryScale, ChangeDetectableProperties: () => ChangeDetectableProperties, Chart: () => Chart, ChartAxisDirection: () => ChartAxisDirection, ChartEventManager: () => ChartEventManager, ChartOptions: () => ChartOptions, ChartUpdateType: () => ChartUpdateType, CollapseMode: () => CollapseMode, Color: () => Color, ColorScale: () => ColorScale, ConicGradient: () => ConicGradient, ContextMenuRegistry: () => ContextMenuRegistry, ContinuousScale: () => ContinuousScale, DATE: () => DATE, DATE_ARRAY: () => DATE_ARRAY, DATE_OR_DATETIME_MS: () => DATE_OR_DATETIME_MS, DEFAULT_CARTESIAN_DIRECTION_KEYS: () => DEFAULT_CARTESIAN_DIRECTION_KEYS, DEFAULT_CARTESIAN_DIRECTION_NAMES: () => DEFAULT_CARTESIAN_DIRECTION_NAMES, DEFAULT_TOOLTIP_CLASS: () => DEFAULT_TOOLTIP_CLASS, DEFAULT_TOOLTIP_DARK_CLASS: () => DEFAULT_TOOLTIP_DARK_CLASS, DIRECTION: () => DIRECTION, DOMManager: () => DOMManager, DataController: () => DataController, DataModel: () => DataModel, DataModelSeries: () => DataModelSeries, DataService: () => DataService, Debug: () => Debug, Default: () => Default, Deprecated: () => Deprecated, DeprecatedAndRenamedTo: () => DeprecatedAndRenamedTo, DragInterpreter: () => DragInterpreter, DraggablePopover: () => DraggablePopover, DropShadow: () => DropShadow, ExtendedPath2D: () => ExtendedPath2D, FONT_SIZE_RATIO: () => FONT_SIZE_RATIO, FONT_STYLE: () => FONT_STYLE, FONT_WEIGHT: () => FONT_WEIGHT, FUNCTION: () => FUNCTION, FloatingToolbar: () => FloatingToolbar, GREATER_THAN: () => GREATER_THAN, Gradient: () => Gradient, Group: () => Group, GroupedCategoryAxis: () => GroupedCategoryAxis, HdpiCanvas: () => HdpiCanvas, HierarchyNode: () => HierarchyNode, HierarchySeries: () => HierarchySeries, HierarchySeriesProperties: () => HierarchySeriesProperties, HighlightManager: () => HighlightManager, HighlightProperties: () => HighlightProperties, HighlightStyle: () => HighlightStyle, INTERACTION_RANGE: () => INTERACTION_RANGE, INTERPOLATION_STEP_POSITION: () => INTERPOLATION_STEP_POSITION, INTERPOLATION_TYPE: () => INTERPOLATION_TYPE, Image: () => Image, InteractionManager: () => InteractionManager, InteractionState: () => InteractionState, InterpolationProperties: () => InterpolationProperties, Invalidating: () => Invalidating, LABEL_PLACEMENT: () => LABEL_PLACEMENT, LARGEST_KEY_INTERVAL: () => LARGEST_KEY_INTERVAL, LESS_THAN: () => LESS_THAN, LINE_CAP: () => LINE_CAP, LINE_DASH: () => LINE_DASH, LINE_JOIN: () => LINE_JOIN, LINE_STYLE: () => LINE_STYLE, Label: () => Label, LayoutElement: () => LayoutElement, LayoutManager: () => LayoutManager, LegendMarkerLabel: () => LegendMarkerLabel, Line: () => Line, LineSeries: () => LineSeries, LineSeriesModule: () => LineSeriesModule, LinearGradient: () => LinearGradient, LinearScale: () => LinearScale, Listeners: () => Listeners, LogScale: () => LogScale, LonLatBBox: () => LonLatBBox, MARKER_SHAPE: () => MARKER_SHAPE, MATCHING_CROSSLINE_TYPE: () => MATCHING_CROSSLINE_TYPE, MAX_SPACING: () => MAX_SPACING, MIN_SPACING: () => MIN_SPACING, Marker: () => Marker, Menu: () => Menu, MercatorScale: () => MercatorScale, ModuleRegistry: () => ModuleRegistry, Motion: () => easing_exports, NAN: () => NAN, NODE_UPDATE_STATE_TO_PHASE_MAPPING: () => NODE_UPDATE_STATE_TO_PHASE_MAPPING, NUMBER: () => NUMBER, NUMBER_ARRAY: () => NUMBER_ARRAY, NUMBER_OR_NAN: () => NUMBER_OR_NAN, NativeWidget: () => NativeWidget, NiceMode: () => NiceMode, Node: () => Node, NumberAxis: () => NumberAxis, OBJECT: () => OBJECT, OBJECT_ARRAY: () => OBJECT_ARRAY, OR: () => OR, OVERFLOW_STRATEGY: () => OVERFLOW_STRATEGY, ObserveChanges: () => ObserveChanges, OrdinalTimeScale: () => OrdinalTimeScale, PHASE_METADATA: () => PHASE_METADATA, PHASE_ORDER: () => PHASE_ORDER, PLACEMENT: () => PLACEMENT, PLAIN_OBJECT: () => PLAIN_OBJECT, POSITION: () => POSITION, POSITION_TOP_COORDINATES: () => POSITION_TOP_COORDINATES, POSITIVE_NUMBER: () => POSITIVE_NUMBER, PREV_NEXT_KEYS: () => PREV_NEXT_KEYS, Padding: () => Padding, ParallelStateMachine: () => ParallelStateMachine, Path: () => Path, PointerEvents: () => PointerEvents, PolarAxis: () => PolarAxis, PolarSeries: () => PolarSeries, PolarZIndexMap: () => PolarZIndexMap, Popover: () => Popover, PropertiesArray: () => PropertiesArray, ProxyInteractionService: () => ProxyInteractionService, ProxyOnWrite: () => ProxyOnWrite, ProxyProperty: () => ProxyProperty, ProxyPropertyOnWrite: () => ProxyPropertyOnWrite, QUICK_TRANSITION: () => QUICK_TRANSITION, RATIO: () => RATIO, REAL_NUMBER: () => REAL_NUMBER, RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD: () => RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD, RadialColumnShape: () => RadialColumnShape, Range: () => Range, Rect: () => Rect, RepeatType: () => RepeatType, Rotatable: () => Rotatable, RotatableGroup: () => RotatableGroup, RotatableText: () => RotatableText, SKIP_JS_BUILTINS: () => SKIP_JS_BUILTINS, SMALLEST_KEY_INTERVAL: () => SMALLEST_KEY_INTERVAL, SORT_DOMAIN_GROUPS: () => SORT_DOMAIN_GROUPS, STRING: () => STRING, STRING_ARRAY: () => STRING_ARRAY, Scalable: () => Scalable, ScalableGroup: () => ScalableGroup, Scene: () => Scene, SceneChangeDetection: () => SceneChangeDetection, ScenePathChangeDetection: () => ScenePathChangeDetection, Sector: () => Sector, SectorBox: () => SectorBox, Selection: () => Selection, Series: () => Series, SeriesContentZIndexMap: () => SeriesContentZIndexMap, SeriesGroupingChangedEvent: () => SeriesGroupingChangedEvent, SeriesItemHighlightStyle: () => SeriesItemHighlightStyle, SeriesMarker: () => SeriesMarker, SeriesNodeEvent: () => SeriesNodeEvent, SeriesNodePickMode: () => SeriesNodePickMode, SeriesProperties: () => SeriesProperties, SeriesTooltip: () => SeriesTooltip, SeriesZIndexMap: () => SeriesZIndexMap, Shape: () => Shape, SimpleTextMeasurer: () => SimpleTextMeasurer, SliderWidget: () => SliderWidget, StateMachine: () => StateMachine, StateMachineProperty: () => StateMachineProperty, StopProperties: () => StopProperties, SvgPath: () => SvgPath, TEXT_ALIGN: () => TEXT_ALIGN, TEXT_WRAP: () => TEXT_WRAP, TICK_INTERVAL: () => TICK_INTERVAL, Text: () => Text, TextUtils: () => TextUtils, TextWrapper: () => TextWrapper, ThemeConstants: () => constants_exports, ThemeSymbols: () => symbols_exports, TimeScale: () => TimeScale, Toolbar: () => Toolbar, ToolbarButtonProperties: () => ToolbarButtonProperties, ToolbarButtonWidget: () => ToolbarButtonWidget, ToolbarWidget: () => ToolbarWidget, Tooltip: () => Tooltip, TooltipManager: () => TooltipManager, TooltipPosition: () => TooltipPosition, Transformable: () => Transformable, TransformableText: () => TransformableText, Translatable: () => Translatable, TranslatableGroup: () => TranslatableGroup, TranslatableLine: () => TranslatableLine, UNION: () => UNION, UpdateService: () => UpdateService, VERTICAL_ALIGN: () => VERTICAL_ALIGN, Validate: () => Validate, Vec2: () => Vec2, Vec4: () => Vec4, WIDGET_HTML_EVENTS: () => WIDGET_HTML_EVENTS, Widget: () => Widget, WidgetEventUtil: () => WidgetEventUtil, ZIndexMap: () => ZIndexMap, ZoomManager: () => ZoomManager, accumulateGroup: () => accumulateGroup, accumulateStack: () => accumulateStack, accumulatedValue: () => accumulatedValue, accumulativeValueProperty: () => accumulativeValueProperty, addHitTestersToQuadtree: () => addHitTestersToQuadtree, adjustLabelPlacement: () => adjustLabelPlacement, angleBetween: () => angleBetween, animationValidation: () => animationValidation, applyShapeStyle: () => applyShapeStyle, areScalingEqual: () => areScalingEqual, area: () => area, buildFormatter: () => buildFormatter, buildResetPathFn: () => buildResetPathFn, calculateDefaultTimeTickFormat: () => calculateDefaultTimeTickFormat, calculateDerivativeExtrema: () => calculateDerivativeExtrema, calculateDerivativeExtremaXY: () => calculateDerivativeExtremaXY, calculateLabelChartPadding: () => calculateLabelChartPadding, calculateLabelTranslation: () => calculateLabelTranslation, calculatePlacement: () => calculatePlacement, checkCrisp: () => checkCrisp, clamp: () => clamp, clampArray: () => clampArray, clippedRoundRect: () => clippedRoundRect, collapsedStartingBarPosition: () => collapsedStartingBarPosition, compareDates: () => compareDates, computeBarFocusBounds: () => computeBarFocusBounds, computeMarkerFocusBounds: () => computeMarkerFocusBounds, countExpandingSearch: () => countExpandingSearch, countFractionDigits: () => countFractionDigits, createButton: () => createButton, createCheckbox: () => createCheckbox, createDatumId: () => createDatumId, createDeprecationWarning: () => createDeprecationWarning, createElement: () => createElement, createElementId: () => createElementId, createIcon: () => createIcon, createId: () => createId, createSelect: () => createSelect, createSvgElement: () => createSvgElement, createTextArea: () => createTextArea, dateToNumber: () => dateToNumber, datesSortOrder: () => datesSortOrder, datumKeys: () => datumKeys, datumStylerProperties: () => datumStylerProperties, deconstructSelectionsOrNodes: () => deconstructSelectionsOrNodes, deepClone: () => deepClone, deepFreeze: () => deepFreeze, defaultTimeTickFormat: () => defaultTimeTickFormat, diff: () => diff, downloadUrl: () => downloadUrl, drawCorner: () => drawCorner, drawMarkerUnitPolygon: () => drawMarkerUnitPolygon, easing: () => easing_exports, enterpriseModule: () => enterpriseModule, evaluateBezier: () => evaluateBezier, extent: () => extent, extractDecoratedProperties: () => extractDecoratedProperties, findMinMax: () => findMinMax, findQuadtreeMatch: () => findQuadtreeMatch, findRangeExtent: () => findRangeExtent, fixNumericExtent: () => fixNumericExtent, focusCursorAtEnd: () => focusCursorAtEnd, formatNumber: () => formatNumber, formatPercent: () => formatPercent, formatValue: () => formatValue, fromToMotion: () => fromToMotion, generateUUID: () => generateUUID, getAngleRatioRadians: () => getAngleRatioRadians, getColorStops: () => getColorStops, getDateTicksForInterval: () => getDateTicksForInterval, getDatumRefPoint: () => getDatumRefPoint, getDocument: () => getDocument, getElementBBox: () => getElementBBox, getIconClassNames: () => getIconClassNames, getLastFocus: () => getLastFocus, getMissCount: () => getMissCount, getPath: () => getPath, getPathComponents: () => getPathComponents, getRadialColumnWidth: () => getRadialColumnWidth, getWindow: () => getWindow, groupAccumulativeValueProperty: () => groupAccumulativeValueProperty, groupAverage: () => groupAverage, groupCount: () => groupCount, groupStackValueProperty: () => groupStackValueProperty, groupSum: () => groupSum, hasNoModifiers: () => hasNoModifiers, inRange: () => inRange, initMenuKeyNav: () => initMenuKeyNav, initRovingTabIndex: () => initRovingTabIndex, interpolatePoints: () => interpolatePoints, isAgFlowProportionChartOptions: () => isAgFlowProportionChartOptions, isAgGaugeChartOptions: () => isAgGaugeChartOptions, isAgHierarchyChartOptions: () => isAgHierarchyChartOptions, isAgStandaloneChartOptions: () => isAgStandaloneChartOptions, isAgTopologyChartOptions: () => isAgTopologyChartOptions, isBetweenAngles: () => isBetweenAngles, isButtonClickEvent: () => isButtonClickEvent, isContinuous: () => isContinuous, isDecoratedObject: () => isDecoratedObject, isDenseInterval: () => isDenseInterval, isInputPending: () => isInputPending, isInteger: () => isInteger, isNegative: () => isNegative, isNumberEqual: () => isNumberEqual, isProperties: () => isProperties, isScaleValid: () => isScaleValid, jsonApply: () => jsonApply, jsonDiff: () => jsonDiff, jsonPropertyCompare: () => jsonPropertyCompare, jsonResolveOperations: () => jsonResolveOperations, jsonWalk: () => jsonWalk, keyProperty: () => keyProperty, labelDirectionHandling: () => labelDirectionHandling, legendSymbolSvg: () => legendSymbolSvg, lineDistanceSquared: () => lineDistanceSquared, listDecoratedProperties: () => listDecoratedProperties, makeAccessibleClickListener: () => makeAccessibleClickListener, mapValues: () => mapValues, markerFadeInAnimation: () => markerFadeInAnimation, markerPaletteFactory: () => markerPaletteFactory, markerScaleInAnimation: () => markerScaleInAnimation, markerSwipeScaleInAnimation: () => markerSwipeScaleInAnimation, mergeArrayDefaults: () => mergeArrayDefaults, mergeDefaults: () => mergeDefaults, midpointStartingBarPosition: () => midpointStartingBarPosition, mod: () => mod, moduleRegistry: () => moduleRegistry, motion: () => motion, nearestSquared: () => nearestSquared, nearestSquaredInContainer: () => nearestSquaredInContainer, normaliseGroupTo: () => normaliseGroupTo, normalisePropertyTo: () => normalisePropertyTo, normalisedExtentWithMetadata: () => normalisedExtentWithMetadata, normalizeAngle180: () => normalizeAngle180, normalizeAngle360: () => normalizeAngle360, normalizeAngle360Inclusive: () => normalizeAngle360Inclusive, objectsEqual: () => objectsEqual, objectsEqualWith: () => objectsEqualWith, pairUpSpans: () => pairUpSpans, partialAssign: () => partialAssign, pathFadeInAnimation: () => pathFadeInAnimation, pathMotion: () => pathMotion, pathSwipeInAnimation: () => pathSwipeInAnimation, pickByMatchingAngle: () => pickByMatchingAngle, plotAreaPathFill: () => plotAreaPathFill, plotInterpolatedAreaSeriesFillSpans: () => plotInterpolatedAreaSeriesFillSpans, plotInterpolatedLinePathStroke: () => plotInterpolatedLinePathStroke, plotLinePathStroke: () => plotLinePathStroke, predicateWithMessage: () => predicateWithMessage, prepareAreaFillAnimationFns: () => prepareAreaFillAnimationFns, prepareAreaPathAnimation: () => prepareAreaPathAnimation, prepareAxisAnimationContext: () => prepareAxisAnimationContext, prepareAxisAnimationFunctions: () => prepareAxisAnimationFunctions, prepareBarAnimationFunctions: () => prepareBarAnimationFunctions, prepareLinePathAnimation: () => prepareLinePathAnimation, prepareLinePathPropertyAnimation: () => prepareLinePathPropertyAnimation, prepareLinePathStrokeAnimationFns: () => prepareLinePathStrokeAnimationFns, preparePieSeriesAnimationFunctions: () => preparePieSeriesAnimationFunctions, range: () => range, rangedValueProperty: () => rangedValueProperty, resetAxisGroupFn: () => resetAxisGroupFn, resetAxisLabelSelectionFn: () => resetAxisLabelSelectionFn, resetAxisLineSelectionFn: () => resetAxisLineSelectionFn, resetAxisSelectionFn: () => resetAxisSelectionFn, resetBarSelectionsFn: () => resetBarSelectionsFn, resetIds: () => resetIds, resetLabelFn: () => resetLabelFn, resetMarkerFn: () => resetMarkerFn, resetMarkerPositionFn: () => resetMarkerPositionFn, resetMotion: () => resetMotion, resetPieSelectionsFn: () => resetPieSelectionsFn, round: () => round, rowCountProperty: () => rowCountProperty, sanitizeHtml: () => sanitizeHtml, scale: () => scale, sectorBox: () => sectorBox, seriesLabelFadeInAnimation: () => seriesLabelFadeInAnimation, seriesLabelFadeOutAnimation: () => seriesLabelFadeOutAnimation, setAttribute: () => setAttribute, setAttributes: () => setAttributes, setDocument: () => setDocument, setElementBBox: () => setElementBBox, setElementStyle: () => setElementStyle, setPath: () => setPath, setWindow: () => setWindow, shallowClone: () => shallowClone, singleSeriesPaletteFactory: () => singleSeriesPaletteFactory, solveBezier: () => solveBezier, sortAndUniqueDates: () => sortAndUniqueDates, splitBezier: () => splitBezier, staticFromToMotion: () => staticFromToMotion, stopPageScrolling: () => stopPageScrolling, sum: () => sum, sumValues: () => sumValues, swapAxisCondition: () => swapAxisCondition, toDegrees: () => toDegrees, toRadians: () => toRadians, tooltipContentAriaLabel: () => tooltipContentAriaLabel, trailingAccumulatedValue: () => trailingAccumulatedValue, trailingAccumulatedValueProperty: () => trailingAccumulatedValueProperty, updateClipPath: () => updateClipPath, updateLabelNode: () => updateLabelNode, validateCrossLineValues: () => validateCrossLineValues, valueProperty: () => valueProperty, visibleRangeIndices: () => visibleRangeIndices, without: () => without }); var motion; var init_module_support = __esm({ "packages/ag-charts-community/src/module-support.ts"() { "use strict"; init_fromToMotion(); init_resetMotion(); init_chart(); init_numberAxis(); init_types(); init_main(); init_core(); init_angle(); init_date(); init_default(); init_decorator(); init_dom(); init_deprecation(); init_extent(); init_format_util(); init_json(); init_keynavUtil(); init_listeners(); init_nearest(); init_number(); init_object(); init_placement(); init_properties(); init_proxy(); init_stateMachine(); init_timeFormatDefaults(); init_textMeasurer(); init_textWrapper(); init_timeFormat(); init_validation2(); init_vector(); init_vector4(); init_axisModule(); init_axisOptionModule(); init_baseModule(); init_coreModules(); init_optionsModule(); init_optionsModuleTypes(); init_module(); init_axisContext(); init_moduleContext(); init_enterpriseModule(); init_background(); init_backgroundModule(); init_chartAnimationPhase(); init_chartAxisDirection(); init_axisUtil(); init_axisTickGenerator(); init_dataModel(); init_dataController(); init_dataService(); init_processors(); init_aggregateFunctions(); init_updateService(); init_layoutManager(); init_animationManager(); init_chartEventManager(); init_contextMenuRegistry(); init_dragInterpreter(); init_highlightManager(); init_interactionManager(); init_tooltipManager(); init_zoomManager(); init_zIndexMap(); init_series(); init_seriesEvents(); init_seriesLabelUtil(); init_seriesProperties(); init_seriesMarker(); init_seriesTooltip(); init_seriesTypes(); init_seriesZIndexMap(); init_util(); init_barSeries(); init_barSeriesModule(); init_scaling(); init_abstractBarSeries(); init_cartesianSeries(); init_lineSeries(); init_lineSeriesModule(); init_lineUtil(); init_lineInterpolationUtil(); init_barUtil(); init_areaUtil(); init_markerUtil(); init_labelUtil(); init_pathUtil(); init_quadtreeUtil(); init_interpolationProperties(); init_dataModelSeries(); init_polarSeries(); init_pieUtil(); init_polarZIndexMap(); init_hierarchySeries(); init_hierarchySeriesProperties(); init_topologySeries(); init_flowProportionSeries(); init_geojson(); init_lonLatBbox(); init_mercatorScale(); init_gaugeSeries(); init_shapeUtil(); init_axis(); init_axisInterval(); init_axisLabel(); init_axisTick(); init_polarAxis(); init_categoryAxis(); init_groupedCategoryAxis(); init_cartesianAxis(); init_axisTicks(); init_chartAxis(); init_crossLine(); init_crossLineLabelPosition(); init_legendDatum(); init_legendSymbol(); init_tooltip(); init_animation(); init_easing(); init_resetMotion(); init_fromToMotion(); init_pathMotion(); init_domManager(); init_elements(); init_proxyInteractionService(); init_id(); init_constants(); init_chartUpdateType(); init_ticks(); init_color(); init_attributeUtil(); init_debug(); init_sanitize(); init_value(); init_bboxinterface(); init_padding(); init_distance(); init_timeScale(); init_logScale(); init_bandScale(); init_categoryScale(); init_continuousScale(); init_ordinalTimeScale(); init_colorScale(); init_linearScale(); init_scale(); init_invalidating(); init_dropShadow(); init_changeDetectableProperties(); init_group(); init_node(); init_transformable(); init_selection(); init_gradient(); init_stops(); init_linearGradient(); init_conicGradient(); init_path(); init_sector(); init_corner(); init_svgPath(); init_text(); init_continuousScale(); init_ordinalTimeScale(); init_label(); init_marker(); init_shapes(); init_legendMarkerLabel(); init_tooltip(); init_sectorBox(); init_hdpiCanvas(); init_image(); init_extendedPath2D(); init_bezier(); init_easing(); init_caption(); init_bbox(); init_group(); init_scene(); init_arc(); init_line(); init_range(); init_path(); init_radialColumnShape(); init_rect(); init_sector2(); init_shape(); init_util3(); init_symbols(); init_constants(); init_exports(); init_menu(); init_anchoredPopover(); init_draggablePopover(); init_popover(); init_toolbarButtonProperties(); init_toolbarButtonWidget(); init_toolbar(); init_floatingToolbar(); motion = { ...fromToMotion_exports, ...resetMotion_exports }; } }); // packages/ag-charts-community/src/main.ts var main_exports = {}; __export(main_exports, { AG_CHARTS_LOCALE_EN_US: () => AG_CHARTS_LOCALE_EN_US, AgCharts: () => AgCharts, AgChartsCommunityModule: () => AgChartsCommunityModule, AgErrorBarSupportedSeriesTypes: () => AgErrorBarSupportedSeriesTypes, AgTooltipPositionType: () => AgTooltipPositionType, VERSION: () => VERSION, _ModuleSupport: () => module_support_exports, _Scene: () => integrated_charts_scene_exports, _Theme: () => integrated_charts_theme_exports, _Util: () => integrated_charts_util_exports, _Widget: () => exports_exports, setupCommunityModules: () => registerInbuiltModules, time: () => time_exports }); var AgChartsCommunityModule; var init_main4 = __esm({ "packages/ag-charts-community/src/main.ts"() { "use strict"; init_agCharts2(); init_registerInbuiltModules(); init_integrated_charts_scene(); init_integrated_charts_theme(); init_integrated_charts_util(); init_version(); init_main2(); init_main3(); init_time(); init_module_support(); init_exports(); AgChartsCommunityModule = { VERSION, _Scene: integrated_charts_scene_exports, _Theme: integrated_charts_theme_exports, _Util: integrated_charts_util_exports, create: AgCharts.create.bind(AgCharts), createSparkline: AgCharts.__createSparkline.bind(AgCharts), setup: registerInbuiltModules, isEnterprise: false }; } }); // packages/ag-charts-enterprise/dist/package/main.cjs.js var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from3, except, desc) => { if (from3 && typeof from3 === "object" || typeof from3 === "function") { for (let key of __getOwnPropNames2(from3)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc2(from3, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod2, secondTarget) => (__copyProps2(target, mod2, "default"), secondTarget && __copyProps2(secondTarget, mod2, "default")); var __toCommonJS2 = (mod2) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod2); var __decorateClass2 = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc2(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) __defProp2(target, key, result); return result; }; var main_exports2 = {}; __export2(main_exports2, { AgChartsEnterpriseModule: () => AgChartsEnterpriseModule, LicenseManager: () => LicenseManager2, setupEnterpriseModules: () => setupEnterpriseModules2 }); module.exports = __toCommonJS2(main_exports2); var import_ag_charts_community271 = (init_main4(), __toCommonJS(main_exports)); var MD5 = class { constructor() { this.ieCompatibility = false; } init() { this.ieCompatibility = this.md5("hello") != "5d41402abc4b2a76b9719d911017c592"; } md5cycle(x, k) { let a = x[0], b = x[1], c = x[2], d = x[3]; a = this.ff(a, b, c, d, k[0], 7, -680876936); d = this.ff(d, a, b, c, k[1], 12, -389564586); c = this.ff(c, d, a, b, k[2], 17, 606105819); b = this.ff(b, c, d, a, k[3], 22, -1044525330); a = this.ff(a, b, c, d, k[4], 7, -176418897); d = this.ff(d, a, b, c, k[5], 12, 1200080426); c = this.ff(c, d, a, b, k[6], 17, -1473231341); b = this.ff(b, c, d, a, k[7], 22, -45705983); a = this.ff(a, b, c, d, k[8], 7, 1770035416); d = this.ff(d, a, b, c, k[9], 12, -1958414417); c = this.ff(c, d, a, b, k[10], 17, -42063); b = this.ff(b, c, d, a, k[11], 22, -1990404162); a = this.ff(a, b, c, d, k[12], 7, 1804603682); d = this.ff(d, a, b, c, k[13], 12, -40341101); c = this.ff(c, d, a, b, k[14], 17, -1502002290); b = this.ff(b, c, d, a, k[15], 22, 1236535329); a = this.gg(a, b, c, d, k[1], 5, -165796510); d = this.gg(d, a, b, c, k[6], 9, -1069501632); c = this.gg(c, d, a, b, k[11], 14, 643717713); b = this.gg(b, c, d, a, k[0], 20, -373897302); a = this.gg(a, b, c, d, k[5], 5, -701558691); d = this.gg(d, a, b, c, k[10], 9, 38016083); c = this.gg(c, d, a, b, k[15], 14, -660478335); b = this.gg(b, c, d, a, k[4], 20, -405537848); a = this.gg(a, b, c, d, k[9], 5, 568446438); d = this.gg(d, a, b, c, k[14], 9, -1019803690); c = this.gg(c, d, a, b, k[3], 14, -187363961); b = this.gg(b, c, d, a, k[8], 20, 1163531501); a = this.gg(a, b, c, d, k[13], 5, -1444681467); d = this.gg(d, a, b, c, k[2], 9, -51403784); c = this.gg(c, d, a, b, k[7], 14, 1735328473); b = this.gg(b, c, d, a, k[12], 20, -1926607734); a = this.hh(a, b, c, d, k[5], 4, -378558); d = this.hh(d, a, b, c, k[8], 11, -2022574463); c = this.hh(c, d, a, b, k[11], 16, 1839030562); b = this.hh(b, c, d, a, k[14], 23, -35309556); a = this.hh(a, b, c, d, k[1], 4, -1530992060); d = this.hh(d, a, b, c, k[4], 11, 1272893353); c = this.hh(c, d, a, b, k[7], 16, -155497632); b = this.hh(b, c, d, a, k[10], 23, -1094730640); a = this.hh(a, b, c, d, k[13], 4, 681279174); d = this.hh(d, a, b, c, k[0], 11, -358537222); c = this.hh(c, d, a, b, k[3], 16, -722521979); b = this.hh(b, c, d, a, k[6], 23, 76029189); a = this.hh(a, b, c, d, k[9], 4, -640364487); d = this.hh(d, a, b, c, k[12], 11, -421815835); c = this.hh(c, d, a, b, k[15], 16, 530742520); b = this.hh(b, c, d, a, k[2], 23, -995338651); a = this.ii(a, b, c, d, k[0], 6, -198630844); d = this.ii(d, a, b, c, k[7], 10, 1126891415); c = this.ii(c, d, a, b, k[14], 15, -1416354905); b = this.ii(b, c, d, a, k[5], 21, -57434055); a = this.ii(a, b, c, d, k[12], 6, 1700485571); d = this.ii(d, a, b, c, k[3], 10, -1894986606); c = this.ii(c, d, a, b, k[10], 15, -1051523); b = this.ii(b, c, d, a, k[1], 21, -2054922799); a = this.ii(a, b, c, d, k[8], 6, 1873313359); d = this.ii(d, a, b, c, k[15], 10, -30611744); c = this.ii(c, d, a, b, k[6], 15, -1560198380); b = this.ii(b, c, d, a, k[13], 21, 1309151649); a = this.ii(a, b, c, d, k[4], 6, -145523070); d = this.ii(d, a, b, c, k[11], 10, -1120210379); c = this.ii(c, d, a, b, k[2], 15, 718787259); b = this.ii(b, c, d, a, k[9], 21, -343485551); x[0] = this.add32(a, x[0]); x[1] = this.add32(b, x[1]); x[2] = this.add32(c, x[2]); x[3] = this.add32(d, x[3]); } cmn(q, a, b, x, s, t) { a = this.add32(this.add32(a, q), this.add32(x, t)); return this.add32(a << s | a >>> 32 - s, b); } ff(a, b, c, d, x, s, t) { return this.cmn(b & c | ~b & d, a, b, x, s, t); } gg(a, b, c, d, x, s, t) { return this.cmn(b & d | c & ~d, a, b, x, s, t); } hh(a, b, c, d, x, s, t) { return this.cmn(b ^ c ^ d, a, b, x, s, t); } ii(a, b, c, d, x, s, t) { return this.cmn(c ^ (b | ~d), a, b, x, s, t); } md51(s) { const n = s.length; const state = [1732584193, -271733879, -1732584194, 271733878]; let i; for (i = 64; i <= s.length; i += 64) { this.md5cycle(state, this.md5blk(s.substring(i - 64, i))); } s = s.substring(i - 64); const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for (i = 0; i < s.length; i++) { tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3); } tail[i >> 2] |= 128 << (i % 4 << 3); if (i > 55) { this.md5cycle(state, tail); for (i = 0; i < 16; i++) { tail[i] = 0; } } tail[14] = n * 8; this.md5cycle(state, tail); return state; } /* there needs to be support for Unicode here, * unless we pretend that we can redefine the MD-5 * algorithm for multi-byte characters (perhaps by adding every four 16-bit characters and * shortening the sum to 32 bits). Otherwise I suthis.ggest performing MD-5 as if every character * was two bytes--e.g., 0040 0025 = @%--but then how will an ordinary MD-5 sum be matched? * There is no way to standardize text to something like UTF-8 before transformation; speed cost is * utterly prohibitive. The JavaScript standard itself needs to look at this: it should start * providing access to strings as preformed UTF-8 8-bit unsigned value arrays. */ md5blk(s) { const md5blks = []; for (let i = 0; i < 64; i += 4) { md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); } return md5blks; } rhex(n) { const hex_chr = "0123456789abcdef".split(""); let s = "", j = 0; for (; j < 4; j++) { s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15]; } return s; } hex(x) { for (let i = 0; i < x.length; i++) { x[i] = this.rhex(x[i]); } return x.join(""); } md5(s) { return this.hex(this.md51(s)); } add32(a, b) { return this.ieCompatibility ? this.add32Compat(a, b) : this.add32Std(a, b); } /* this function is much faster, so if possible we use it. Some IEs are the only ones I know of that need the idiotic second function, generated by an if clause. */ add32Std(a, b) { return a + b & 4294967295; } add32Compat(x, y) { const lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16); return msw << 16 | lsw & 65535; } }; function missingOrEmpty(value) { return value == null || value.length === 0; } var LICENSE_TYPES = { "01": "GRID", "02": "CHARTS", "0102": "BOTH" }; var LICENSING_HELP_URL = "https://www.ag-grid.com/charts/licensing/"; var _LicenseManager = class _LicenseManager2 { constructor(document2) { this.watermarkMessage = void 0; this.totalMessageLength = 124; this.document = document2; this.md5 = new MD5(); this.md5.init(); } validateLicense() { const licenseDetails = this.getLicenseDetails(_LicenseManager2.licenseKey, _LicenseManager2.gridContext); const currentLicenseName = `AG ${licenseDetails.currentLicenseType === "BOTH" ? "Grid and " : ""}Charts Enterprise`; let suppliedLicenseName = ""; if (licenseDetails.suppliedLicenseType === "BOTH") { suppliedLicenseName = "AG Grid and AG Charts Enterprise"; } else if (licenseDetails.suppliedLicenseType === "GRID") { suppliedLicenseName = "AG Grid Enterprise"; } else if (licenseDetails.suppliedLicenseType !== void 0) { suppliedLicenseName = "AG Charts Enterprise"; } if (licenseDetails.missing) { if (!this.isWebsiteUrl() || this.isForceWatermark()) { this.outputMissingLicenseKey(currentLicenseName); } } else if (licenseDetails.expired) { const gridReleaseDate = _LicenseManager2.getChartsReleaseDate(); const formattedReleaseDate = _LicenseManager2.formatDate(gridReleaseDate); this.outputExpiredKey(licenseDetails.expiry, formattedReleaseDate, suppliedLicenseName); } else if (!licenseDetails.valid) { this.outputInvalidLicenseKey( !!licenseDetails.incorrectLicenseType, currentLicenseName, suppliedLicenseName ); } else if (licenseDetails.isTrial && licenseDetails.trialExpired) { this.outputExpiredTrialKey(licenseDetails.expiry, currentLicenseName, suppliedLicenseName); } } static extractExpiry(license) { const restrictionHashed = license.substring(license.lastIndexOf("_") + 1, license.length); return new Date(parseInt(_LicenseManager2.decode(restrictionHashed), 10)); } static extractLicenseComponents(licenseKey) { let cleanedLicenseKey = licenseKey.replace(/[\u200B-\u200D\uFEFF]/g, ""); cleanedLicenseKey = cleanedLicenseKey.replace(/\r?\n|\r/g, ""); if (licenseKey.length <= 32) { return { md5: null, license: licenseKey, version: null, isTrial: null }; } const hashStart = cleanedLicenseKey.length - 32; const md5 = cleanedLicenseKey.substring(hashStart); const license = cleanedLicenseKey.substring(0, hashStart); const [version, isTrial, type] = _LicenseManager2.extractBracketedInformation(cleanedLicenseKey); return { md5, license, version, isTrial, type }; } getLicenseDetails(licenseKey, gridContext = false) { const currentLicenseType = "CHARTS"; if (missingOrEmpty(licenseKey)) { return { licenseKey, valid: false, missing: true, currentLicenseType }; } const chartsReleaseDate = _LicenseManager2.getChartsReleaseDate(); const { md5, license, version, isTrial, type } = _LicenseManager2.extractLicenseComponents(licenseKey); let valid = md5 === this.md5.md5(license) && licenseKey.indexOf("For_Trialing_ag-Grid_Only") === -1; let trialExpired = void 0; let expired = void 0; let expiry = null; let incorrectLicenseType = false; let suppliedLicenseType = void 0; function handleTrial() { const now = /* @__PURE__ */ new Date(); trialExpired = expiry < now; expired = void 0; } if (valid) { expiry = _LicenseManager2.extractExpiry(license); valid = !isNaN(expiry.getTime()); if (valid) { expired = chartsReleaseDate > expiry; switch (version) { case "legacy": case "2": { valid = false; break; } case "3": { if (missingOrEmpty(type)) { valid = false; } else { suppliedLicenseType = type; if (type !== LICENSE_TYPES["02"] && type !== LICENSE_TYPES["0102"]) { valid = false; incorrectLicenseType = true; } else if (isTrial) { handleTrial(); } } } } } } if (!valid) { return { licenseKey, valid, incorrectLicenseType, currentLicenseType, suppliedLicenseType }; } return { licenseKey, valid, expiry: _LicenseManager2.formatDate(expiry), expired, version, isTrial, trialExpired, invalidLicenseTypeForCombo: gridContext ? suppliedLicenseType !== "BOTH" : void 0, incorrectLicenseType, currentLicenseType, suppliedLicenseType }; } isDisplayWatermark() { return this.isForceWatermark() || !this.isLocalhost() && !this.isWebsiteUrl() && !missingOrEmpty(this.watermarkMessage); } getWatermarkMessage() { return this.watermarkMessage ?? ""; } getHostname() { if (!this.document) { return "localhost"; } const win = this.document.defaultView ?? window; if (!win) { return "localhost"; } const loc = win.location; const { hostname = "" } = loc; return hostname; } isForceWatermark() { if (!this.document) { return false; } const win = this.document?.defaultView ?? typeof window != "undefined" ? window : void 0; if (!win) { return false; } const { pathname } = win.location; return pathname ? pathname.indexOf("forceWatermark") !== -1 : false; } isWebsiteUrl() { const hostname = this.getHostname(); return /^((?:[\w-]+\.)?ag-grid\.com)$/.exec(hostname) !== null; } isLocalhost() { const hostname = this.getHostname(); return /^(?:127\.0\.0\.1|localhost)$/.exec(hostname) !== null; } static formatDate(date2) { const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; const day2 = date2.getDate(); const monthIndex = date2.getMonth(); const year2 = date2.getFullYear(); return day2 + " " + monthNames[monthIndex] + " " + year2; } static getChartsReleaseDate() { return new Date(parseInt(_LicenseManager2.decode(_LicenseManager2.RELEASE_INFORMATION), 10)); } static decode(input) { const keystr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; let t = ""; let n, r, i; let s, o, u, a; let f = 0; const e = input.replace(/[^A-Za-z0-9+/=]/g, ""); while (f < e.length) { s = keystr.indexOf(e.charAt(f++)); o = keystr.indexOf(e.charAt(f++)); u = keystr.indexOf(e.charAt(f++)); a = keystr.indexOf(e.charAt(f++)); n = s << 2 | o >> 4; r = (o & 15) << 4 | u >> 2; i = (u & 3) << 6 | a; t = t + String.fromCharCode(n); if (u != 64) { t = t + String.fromCharCode(r); } if (a != 64) { t = t + String.fromCharCode(i); } } t = _LicenseManager2.utf8_decode(t); return t; } static utf8_decode(input) { input = input.replace(/rn/g, "n"); let t = ""; for (let n = 0; n < input.length; n++) { const r = input.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r); } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128); } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128); } } return t; } static setGridContext(gridContext = false) { _LicenseManager2.gridContext = gridContext; } static setLicenseKey(licenseKey) { _LicenseManager2.licenseKey = licenseKey; } static extractBracketedInformation(licenseKey) { if (!licenseKey.includes("[")) { return ["legacy", false, void 0]; } const matches = licenseKey.match(/\[(.*?)\]/g).map((match) => match.replace("[", "").replace("]", "")); if (!matches || matches.length === 0) { return ["legacy", false, void 0]; } const isTrial = matches.filter((match) => match === "TRIAL").length === 1; const rawVersion = matches.filter((match) => match.startsWith("v"))[0]; const version = rawVersion ? rawVersion.replace("v", "") : "legacy"; const type = LICENSE_TYPES[matches.filter((match) => LICENSE_TYPES[match])[0]]; return [version, isTrial, type]; } centerPadAndOutput(input) { const paddingRequired = this.totalMessageLength - input.length; console.error(input.padStart(paddingRequired / 2 + input.length, "*").padEnd(this.totalMessageLength, "*")); } padAndOutput(input, padding = "*", terminateWithPadding = "") { console.error( input.padEnd(this.totalMessageLength - terminateWithPadding.length, padding) + terminateWithPadding ); } outputInvalidLicenseKey(incorrectLicenseType, currentLicenseName, suppliedLicenseName) { if (!_LicenseManager2.gridContext) { if (incorrectLicenseType) { this.centerPadAndOutput(""); this.centerPadAndOutput(` ${currentLicenseName} License `); this.centerPadAndOutput(" Incompatible License Key "); this.padAndOutput( `* Your license key is for ${suppliedLicenseName} only and does not cover you for ${currentLicenseName}.`, " ", "*" ); this.padAndOutput(`* To troubleshoot your license key visit ${LICENSING_HELP_URL}.`, " ", "*"); this.centerPadAndOutput(""); this.centerPadAndOutput(""); } else { this.centerPadAndOutput(""); this.centerPadAndOutput(` ${currentLicenseName} License `); this.centerPadAndOutput(" Invalid License Key "); this.padAndOutput(`* Your license key is not valid.`, " ", "*"); this.padAndOutput(`* To troubleshoot your license key visit ${LICENSING_HELP_URL}.`, " ", "*"); this.centerPadAndOutput(""); this.centerPadAndOutput(""); } } this.watermarkMessage = "Invalid License"; } outputExpiredTrialKey(formattedExpiryDate, currentLicenseName, suppliedLicenseName) { if (!_LicenseManager2.gridContext) { this.centerPadAndOutput(""); this.centerPadAndOutput(` ${currentLicenseName} License `); this.centerPadAndOutput(" Trial Period Expired. "); this.padAndOutput( `* Your trial only license for ${suppliedLicenseName} expired on ${formattedExpiryDate}.`, " ", "*" ); this.padAndOutput("* Please email info@ag-grid.com to purchase a license.", " ", "*"); this.centerPadAndOutput(""); this.centerPadAndOutput(""); } this.watermarkMessage = "Trial Period Expired"; } outputMissingLicenseKey(currentLicenseName) { if (!_LicenseManager2.gridContext) { this.centerPadAndOutput(""); this.centerPadAndOutput(` ${currentLicenseName} License `); this.centerPadAndOutput(" License Key Not Found "); this.padAndOutput(`* All ${currentLicenseName} features are unlocked for trial.`, " ", "*"); this.padAndOutput( "* If you want to hide the watermark please email info@ag-grid.com for a trial license key.", " ", "*" ); this.centerPadAndOutput(""); this.centerPadAndOutput(""); } this.watermarkMessage = "For Trial Use Only"; } outputExpiredKey(formattedExpiryDate, formattedReleaseDate, currentLicenseName) { if (!_LicenseManager2.gridContext) { this.centerPadAndOutput(""); this.centerPadAndOutput(` ${currentLicenseName} License `); this.centerPadAndOutput(" Incompatible Software Version "); this.padAndOutput( `* Your license key works with versions of ${currentLicenseName} released before ${formattedExpiryDate}.`, " ", "*" ); this.padAndOutput(`* The version you are trying to use was released on ${formattedReleaseDate}.`, " ", "*"); this.padAndOutput("* Please contact info@ag-grid.com to renew your license key.", " ", "*"); this.centerPadAndOutput(""); this.centerPadAndOutput(""); } this.watermarkMessage = "License Expired"; } }; _LicenseManager.RELEASE_INFORMATION = "MTc0MDAzOTI3Mjg4Mg=="; _LicenseManager.gridContext = false; var LicenseManager = _LicenseManager; var import_ag_charts_community270 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community5 = (init_main4(), __toCommonJS(main_exports)); function loopSymmetrically(items, step, iterator) { const loop = (start2, end2, loopStep, loopIterator) => { let prev = items[0]; for (let i = start2; loopStep > 0 ? i <= end2 : i > end2; i += loopStep) { const curr = items[i]; if (loopIterator(prev, curr)) return true; prev = curr; } return false; }; const midIndex = Math.floor(items.length / 2); if (loop(step, midIndex, step, iterator)) return true; return loop(items.length - step, midIndex, -step, iterator); } var import_ag_charts_community = (init_main4(), __toCommonJS(main_exports)); var { OR: OR2, POSITIVE_NUMBER: POSITIVE_NUMBER2, NAN: NAN2, AxisInterval: AxisInterval2, Validate: Validate2 } = import_ag_charts_community._ModuleSupport; var AngleAxisInterval = class extends AxisInterval2 { constructor() { super(...arguments); this.minSpacing = NaN; } }; __decorateClass2([ Validate2(OR2(POSITIVE_NUMBER2, NAN2)) ], AngleAxisInterval.prototype, "minSpacing", 2); var import_ag_charts_community4 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community3 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community2 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties2, ChartAxisDirection: ChartAxisDirection2, ARRAY: ARRAY2, BOOLEAN: BOOLEAN2, COLOR_STRING: COLOR_STRING2, FONT_STYLE: FONT_STYLE2, FONT_WEIGHT: FONT_WEIGHT2, LINE_DASH: LINE_DASH2, NUMBER: NUMBER2, OBJECT: OBJECT2, POSITIVE_NUMBER: POSITIVE_NUMBER22, RATIO: RATIO2, STRING: STRING2, UNION: UNION2, AND: AND2, Validate: Validate22, MATCHING_CROSSLINE_TYPE: MATCHING_CROSSLINE_TYPE2, createId: createId2, Group: Group2 } = import_ag_charts_community2._ModuleSupport; var PolarCrossLineLabel = class extends BaseProperties2 { constructor() { super(...arguments); this.fontSize = 14; this.fontFamily = "Verdana, sans-serif"; this.padding = 5; this.color = "rgba(87, 87, 87, 1)"; } }; __decorateClass2([ Validate22(BOOLEAN2, { optional: true }) ], PolarCrossLineLabel.prototype, "enabled", 2); __decorateClass2([ Validate22(STRING2, { optional: true }) ], PolarCrossLineLabel.prototype, "text", 2); __decorateClass2([ Validate22(FONT_STYLE2, { optional: true }) ], PolarCrossLineLabel.prototype, "fontStyle", 2); __decorateClass2([ Validate22(FONT_WEIGHT2, { optional: true }) ], PolarCrossLineLabel.prototype, "fontWeight", 2); __decorateClass2([ Validate22(POSITIVE_NUMBER22) ], PolarCrossLineLabel.prototype, "fontSize", 2); __decorateClass2([ Validate22(STRING2) ], PolarCrossLineLabel.prototype, "fontFamily", 2); __decorateClass2([ Validate22(NUMBER2) ], PolarCrossLineLabel.prototype, "padding", 2); __decorateClass2([ Validate22(COLOR_STRING2, { optional: true }) ], PolarCrossLineLabel.prototype, "color", 2); __decorateClass2([ Validate22(BOOLEAN2, { optional: true }) ], PolarCrossLineLabel.prototype, "parallel", 2); var PolarCrossLine = class extends BaseProperties2 { constructor() { super(...arguments); this.id = createId2(this); this.shape = "polygon"; this.label = new PolarCrossLineLabel(); this.scale = void 0; this.clippedRange = [-Infinity, Infinity]; this.gridLength = 0; this.sideFlag = -1; this.parallelFlipRotation = 0; this.regularFlipRotation = 0; this.direction = ChartAxisDirection2.X; this.axisInnerRadius = 0; this.axisOuterRadius = 0; this.lineGroup = new Group2({ name: this.id }); this.rangeGroup = new Group2({ name: this.id }); this.labelGroup = new Group2({ name: this.id }); this._isRange = void 0; } assignCrossLineGroup(isRange, crossLineRange) { if (isRange !== this._isRange) { if (isRange) { this.rangeGroup.appendChild(crossLineRange); } else { this.lineGroup.appendChild(crossLineRange); } } this._isRange = isRange; } setSectorNodeProps(node) { node.fill = this.fill; node.fillOpacity = this.fillOpacity ?? 1; node.stroke = this.stroke; node.strokeOpacity = this.strokeOpacity ?? 1; node.strokeWidth = this.strokeWidth ?? 1; node.lineDash = this.lineDash; } setLabelNodeProps(node, x, y, baseline, rotation) { const { label } = this; node.x = x; node.y = y; node.text = label.text; node.textAlign = "center"; node.textBaseline = baseline; node.rotation = rotation; node.rotationCenterX = x; node.rotationCenterY = y; node.fill = label.color; node.fontFamily = label.fontFamily; node.fontSize = label.fontSize; node.fontStyle = label.fontStyle; node.visible = true; } }; __decorateClass2([ Validate22(BOOLEAN2, { optional: true }) ], PolarCrossLine.prototype, "enabled", 2); __decorateClass2([ Validate22(UNION2(["range", "line"], "a crossLine type"), { optional: true }) ], PolarCrossLine.prototype, "type", 2); __decorateClass2([ Validate22(AND2(MATCHING_CROSSLINE_TYPE2("range"), ARRAY2.restrict({ length: 2 })), { optional: true }) ], PolarCrossLine.prototype, "range", 2); __decorateClass2([ Validate22(MATCHING_CROSSLINE_TYPE2("value"), { optional: true }) ], PolarCrossLine.prototype, "value", 2); __decorateClass2([ Validate22(COLOR_STRING2, { optional: true }) ], PolarCrossLine.prototype, "fill", 2); __decorateClass2([ Validate22(RATIO2, { optional: true }) ], PolarCrossLine.prototype, "fillOpacity", 2); __decorateClass2([ Validate22(COLOR_STRING2, { optional: true }) ], PolarCrossLine.prototype, "stroke", 2); __decorateClass2([ Validate22(NUMBER2, { optional: true }) ], PolarCrossLine.prototype, "strokeWidth", 2); __decorateClass2([ Validate22(RATIO2, { optional: true }) ], PolarCrossLine.prototype, "strokeOpacity", 2); __decorateClass2([ Validate22(LINE_DASH2, { optional: true }) ], PolarCrossLine.prototype, "lineDash", 2); __decorateClass2([ Validate22(UNION2(["polygon", "circle"], "a shape")) ], PolarCrossLine.prototype, "shape", 2); __decorateClass2([ Validate22(OBJECT2) ], PolarCrossLine.prototype, "label", 2); var { ChartAxisDirection: ChartAxisDirection22, validateCrossLineValues: validateCrossLineValues2, normalizeAngle360: normalizeAngle3602, isNumberEqual: isNumberEqual2, Group: Group22, Path: Path2, Sector: Sector2, RotatableText: RotatableText2, ContinuousScale: ContinuousScale2, BandScale: BandScale2 } = import_ag_charts_community3._ModuleSupport; var AngleCrossLine = class extends PolarCrossLine { constructor() { super(); this.direction = ChartAxisDirection22.X; this.polygonNode = new Path2(); this.sectorNode = new Sector2(); this.lineNode = new Path2(); this.crossLineRange = new Group22(); this.labelNode = new RotatableText2(); this.ticks = []; this.crossLineRange.append(this.polygonNode); this.crossLineRange.append(this.sectorNode); this.crossLineRange.append(this.lineNode); this.labelGroup.append(this.labelNode); } update(visible) { const { scale: scale2, shape, type, value, range: range22 } = this; const visibilityCheck = () => { if (!ContinuousScale2.is(scale2)) { return true; } const [start2, end2] = range22 ?? [value, void 0]; const { domain } = scale2; return start2 >= domain[0] && start2 <= domain[1] && (type === "line" || end2 >= start2 && end2 <= domain[1]); }; if (!scale2 || !type || !validateCrossLineValues2(type, value, range22, scale2, visibilityCheck)) { this.rangeGroup.visible = false; this.lineGroup.visible = false; this.labelGroup.visible = false; return; } this.rangeGroup.visible = visible; this.lineGroup.visible = visible; this.labelGroup.visible = visible; if (type === "line" && shape === "circle" && BandScale2.is(scale2)) { this.type = "range"; this.range = [value, value]; } this.updateLineNode(visible); this.updatePolygonNode(visible); this.updateSectorNode(visible); this.updateLabelNode(visible); } updateLineNode(visible) { const { scale: scale2, type, value, lineNode: line } = this; if (!visible || type !== "line" || !scale2) { line.visible = false; return; } const angle2 = scale2.convert(value); if (isNaN(angle2)) { line.visible = false; return; } const { axisInnerRadius, axisOuterRadius } = this; line.visible = true; line.stroke = this.stroke; line.strokeOpacity = this.strokeOpacity ?? 1; line.strokeWidth = this.strokeWidth ?? 1; line.fill = void 0; line.lineDash = this.lineDash; const x = axisOuterRadius * Math.cos(angle2); const y = axisOuterRadius * Math.sin(angle2); const x0 = axisInnerRadius * Math.cos(angle2); const y0 = axisInnerRadius * Math.sin(angle2); line.path.clear(true); line.path.moveTo(x0, y0); line.path.lineTo(x, y); this.assignCrossLineGroup(false, this.crossLineRange); } updatePolygonNode(visible) { const { polygonNode: polygon, range: range22, scale: scale2, shape, type, ticks } = this; if (!visible || type !== "range" || shape !== "polygon" || !scale2 || !range22) { polygon.visible = false; return; } const { axisInnerRadius, axisOuterRadius } = this; const startIndex = ticks.indexOf(range22[0]); const endIndex = ticks.indexOf(range22[1]); const stops = startIndex <= endIndex ? ticks.slice(startIndex, endIndex + 1) : ticks.slice(startIndex).concat(ticks.slice(0, endIndex + 1)); const angles = stops.map((value) => scale2.convert(value)); polygon.visible = true; this.setSectorNodeProps(polygon); const { path } = polygon; path.clear(true); angles.forEach((angle2, index) => { const x = axisOuterRadius * Math.cos(angle2); const y = axisOuterRadius * Math.sin(angle2); if (index === 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } }); if (axisInnerRadius === 0) { path.lineTo(0, 0); } else { angles.slice().reverse().forEach((angle2) => { const x = axisInnerRadius * Math.cos(angle2); const y = axisInnerRadius * Math.sin(angle2); path.lineTo(x, y); }); } polygon.path.closePath(); this.assignCrossLineGroup(true, this.crossLineRange); } updateSectorNode(visible) { const { sectorNode: sector, range: range22, scale: scale2, shape, type } = this; if (!visible || type !== "range" || shape !== "circle" || !scale2 || !range22) { sector.visible = false; return; } const { axisInnerRadius, axisOuterRadius } = this; const angles = range22.map((value) => scale2.convert(value)); const step = scale2.step ?? 0; const padding = scale2 instanceof import_ag_charts_community3._ModuleSupport.BandScale ? step / 2 : 0; sector.visible = true; this.setSectorNodeProps(sector); sector.centerX = 0; sector.centerY = 0; sector.innerRadius = axisInnerRadius; sector.outerRadius = axisOuterRadius; sector.startAngle = angles[0] - padding; sector.endAngle = angles[1] + padding; this.assignCrossLineGroup(true, this.crossLineRange); } updateLabelNode(visible) { const { label, labelNode: node, range: range22, scale: scale2, type, ticks } = this; if (!visible || label.enabled === false || !label.text || !scale2 || type === "range" && !range22) { node.visible = false; return; } node.visible = true; const { axisInnerRadius, axisOuterRadius } = this; let labelX; let labelY; let rotation; let textBaseline; if (type === "line") { const angle2 = normalizeAngle3602(scale2.convert(this.value)); const angle270 = 1.5 * Math.PI; const isRightSide = isNumberEqual2(angle2, angle270) || angle2 > angle270 || angle2 < Math.PI / 2; const midX = (axisInnerRadius + axisOuterRadius) / 2 * Math.cos(angle2); const midY = (axisInnerRadius + axisOuterRadius) / 2 * Math.sin(angle2); labelX = midX + label.padding * Math.cos(angle2 + Math.PI / 2); labelY = midY + label.padding * Math.sin(angle2 + Math.PI / 2); textBaseline = isRightSide ? "top" : "bottom"; rotation = isRightSide ? angle2 : angle2 - Math.PI; } else { const [startAngle, endAngle] = range22.map((value) => normalizeAngle3602(scale2.convert(value))); let angle2 = (startAngle + endAngle) / 2; if (startAngle > endAngle) { angle2 -= Math.PI; } angle2 = normalizeAngle3602(angle2); const isBottomSide = (isNumberEqual2(angle2, 0) || angle2 > 0) && angle2 < Math.PI; let distance2; if (this.shape === "circle" || ticks.length < 3) { distance2 = axisOuterRadius - label.padding; } else { distance2 = axisOuterRadius * Math.cos(Math.PI / ticks.length) - label.padding; } labelX = distance2 * Math.cos(angle2); labelY = distance2 * Math.sin(angle2); textBaseline = isBottomSide ? "bottom" : "top"; rotation = isBottomSide ? angle2 - Math.PI / 2 : angle2 + Math.PI / 2; } this.setLabelNodeProps(node, labelX, labelY, textBaseline, rotation); } }; AngleCrossLine.className = "AngleCrossLine"; var { ChartAxisDirection: ChartAxisDirection3, NUMBER: NUMBER22, UNION: UNION22, ProxyOnWrite: ProxyOnWrite2, TextWrapper: TextWrapper2, TextUtils: TextUtils2, Validate: Validate3, isNumberEqual: isNumberEqual22, toRadians: toRadians2, normalizeAngle360: normalizeAngle36022, normalizeAngle360Inclusive: normalizeAngle360Inclusive2, Path: Path22, RotatableText: RotatableText22, Transformable: Transformable2, BBox: BBox2 } = import_ag_charts_community4._ModuleSupport; var AngleAxisLabel = class extends import_ag_charts_community4._ModuleSupport.AxisLabel { constructor() { super(...arguments); this.orientation = "fixed"; } }; __decorateClass2([ Validate3(UNION22(["fixed", "parallel", "perpendicular"], "a label orientation")) ], AngleAxisLabel.prototype, "orientation", 2); var AngleAxis = class extends import_ag_charts_community4._ModuleSupport.PolarAxis { constructor(moduleCtx, scale2) { super(moduleCtx, scale2); this.startAngle = 0; this.endAngle = void 0; this.labelData = []; this.tickData = []; this.radiusLine = this.axisGroup.appendChild(new Path22()); this.includeInvisibleDomains = true; } get direction() { return ChartAxisDirection3.X; } createLabel() { return new AngleAxisLabel(); } calculateTickLayout(domain) { const { nice, scale: scale2 } = this; const ticksParams = { nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity }; const niceDomain = nice ? scale2.niceDomain(ticksParams, domain) : domain; const tickData = this.generateAngleTicks(niceDomain); this.tickData = tickData; const ticks = tickData.map((t) => t.value); return { niceDomain, primaryTickCount: void 0, tickDomain: niceDomain, ticks, fractionDigits: 0, bbox: this.getBBox() }; } update() { super.update(); this.updateRadiusLine(); } normalizedAngles() { const startAngle = normalizeAngle36022(-Math.PI / 2 + toRadians2(this.startAngle)); const sweep = this.endAngle != null ? normalizeAngle360Inclusive2(toRadians2(this.endAngle) - toRadians2(this.startAngle)) : 2 * Math.PI; const endAngle = startAngle + sweep; return [startAngle, endAngle]; } computeRange() { this.range = this.normalizedAngles(); } updateSelections() { const data = this.tickData; this.gridLineGroupSelection.update(this.gridLength && this.gridLine.enabled ? data : []); this.tickLineGroupSelection.update(this.tick.enabled ? data : []); this.tickLabelGroupSelection.update(this.label.enabled ? data : []); this.gridLineGroupSelection.cleanup(); this.tickLineGroupSelection.cleanup(); this.tickLabelGroupSelection.cleanup(); } updatePosition() { const { translation, axisGroup, gridGroup, crossLineRangeGroup, crossLineLineGroup, crossLineLabelGroup } = this; const translationX = Math.floor(translation.x); const translationY = Math.floor(translation.y); axisGroup.translationX = translationX; axisGroup.translationY = translationY; gridGroup.translationX = translationX; gridGroup.translationY = translationY; crossLineRangeGroup.translationX = translationX; crossLineRangeGroup.translationY = translationY; crossLineLineGroup.translationX = translationX; crossLineLineGroup.translationY = translationY; crossLineLabelGroup.translationX = translationX; crossLineLabelGroup.translationY = translationY; } updateRadiusLine() { const node = this.radiusLine; const { path } = node; path.clear(true); const { points, closePath } = this.getAxisLinePoints(); points.forEach(({ x, y, moveTo, arc, radius = 0, startAngle = 0, endAngle = 0 }) => { if (arc) { path.arc(x, y, radius, startAngle, endAngle); } else if (moveTo) { path.moveTo(x, y); } else { path.lineTo(x, y); } }); if (closePath) { path.closePath(); } node.visible = this.line.enabled; node.stroke = this.line.stroke; node.strokeWidth = this.line.width; node.fill = void 0; } getAxisLinePoints() { const { scale: scale2, shape, gridLength: radius } = this; const [startAngle, endAngle] = this.range; const isFullCircle = isNumberEqual22(endAngle - startAngle, 2 * Math.PI); const points = []; if (shape === "circle") { if (isFullCircle) { points.push( { x: radius, y: 0, moveTo: true }, { x: 0, y: 0, radius, startAngle: 0, endAngle: 2 * Math.PI, arc: true, moveTo: false } ); } else { points.push( { x: radius * Math.cos(startAngle), y: radius * Math.sin(startAngle), moveTo: true }, { x: 0, y: 0, radius, startAngle: normalizeAngle36022(startAngle), endAngle: normalizeAngle36022(endAngle), arc: true, moveTo: false } ); } } else if (shape === "polygon") { const angles = scale2.ticks({ nice: this.nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity })?.map((value) => scale2.convert(value)); if (angles && angles.length > 2) { angles.forEach((angle2, i) => { const x = radius * Math.cos(angle2); const y = radius * Math.sin(angle2); const moveTo = i === 0; points.push({ x, y, moveTo }); }); } } return { points, closePath: isFullCircle }; } updateGridLines() { const { scale: scale2, gridLength: radius, gridLine: { style, width: width2 }, innerRadiusRatio } = this; if (!(style && radius > 0)) { return; } const innerRadius = radius * innerRadiusRatio; const styleCount = style.length; this.gridLineGroupSelection.each((line, datum, index) => { const { value } = datum; const { stroke: stroke22, lineDash } = style[index % styleCount]; const angle2 = scale2.convert(value); line.x1 = innerRadius * Math.cos(angle2); line.y1 = innerRadius * Math.sin(angle2); line.x2 = radius * Math.cos(angle2); line.y2 = radius * Math.sin(angle2); line.stroke = stroke22; line.strokeWidth = width2; line.lineDash = lineDash; line.fill = void 0; }); this.gridLineGroupSelection.cleanup(); } updateLabels() { const { label, tickLabelGroupSelection } = this; tickLabelGroupSelection.each((node, _, index) => { const labelDatum = this.labelData[index]; if (!labelDatum || labelDatum.hidden) { node.visible = false; return; } node.text = labelDatum.text; node.setFont(label); node.fill = label.color; node.x = labelDatum.x; node.y = labelDatum.y; node.textAlign = labelDatum.textAlign; node.textBaseline = labelDatum.textBaseline; node.visible = true; if (labelDatum.rotation) { node.rotation = labelDatum.rotation; node.rotationCenterX = labelDatum.x; node.rotationCenterY = labelDatum.y; } else { node.rotation = 0; } }); } updateTickLines() { const { scale: scale2, gridLength: radius, tick, tickLineGroupSelection } = this; tickLineGroupSelection.each((line, datum) => { const { value } = datum; const angle2 = scale2.convert(value); const cos = Math.cos(angle2); const sin = Math.sin(angle2); line.x1 = radius * cos; line.y1 = radius * sin; line.x2 = (radius + tick.size) * cos; line.y2 = (radius + tick.size) * sin; line.stroke = tick.stroke; line.strokeWidth = tick.width; }); } createLabelNodeData(ticks, options, seriesRect) { const { label, gridLength: radius, scale: scale2, tick } = this; if (!label.enabled) { return []; } const tempText2 = new RotatableText22(); const seriesLeft = seriesRect.x - this.translation.x; const seriesRight = seriesRect.x + seriesRect.width - this.translation.x; const labelData = ticks.map((datum, index) => { const { value } = datum; const distance2 = radius + label.spacing + tick.size; const angle2 = scale2.convert(value); const cos = Math.cos(angle2); const sin = Math.sin(angle2); const x = distance2 * cos; const y = distance2 * sin; const { textAlign, textBaseline } = this.getLabelAlign(angle2); const isLastTickOverFirst = index === ticks.length - 1 && value !== ticks[0] && isNumberEqual22(normalizeAngle36022(angle2), normalizeAngle36022(scale2.convert(ticks[0]))); const rotation = this.getLabelRotation(angle2); let text22 = String(value); if (label.formatter) { const { callbackCache } = this.moduleCtx; text22 = callbackCache.call(label.formatter, { value, index }) ?? ""; } tempText2.text = text22; tempText2.x = x; tempText2.y = y; tempText2.setFont(label); tempText2.textAlign = textAlign; tempText2.textBaseline = textBaseline; tempText2.rotation = rotation; if (rotation) { tempText2.rotationCenterX = x; tempText2.rotationCenterY = y; } let box = rotation ? Transformable2.toCanvas(tempText2) : tempText2.getBBox(); if (box && options.hideWhenNecessary && !rotation) { const overflowLeft = seriesLeft - box.x; const overflowRight = box.x + box.width - seriesRight; const pixelError = 1; if (overflowLeft > pixelError || overflowRight > pixelError) { const availWidth = box.width - Math.max(overflowLeft, overflowRight); text22 = TextWrapper2.wrapText(text22, { maxWidth: availWidth, font: label, textWrap: "never" }); if (text22 === TextUtils2.EllipsisChar) { text22 = ""; } tempText2.text = text22; box = tempText2.getBBox(); } } return { text: text22, x, y, textAlign, textBaseline, hidden: text22 === "" || datum.hidden || isLastTickOverFirst, rotation, box }; }); if (label.avoidCollisions) { this.avoidLabelCollisions(labelData); } return labelData; } computeLabelsBBox(options, seriesRect) { this.labelData = this.createLabelNodeData(this.tickData, options, seriesRect); const textBoxes = this.labelData.map(({ box }) => box).filter((box) => box != null); if (!this.label.enabled || textBoxes.length === 0) { return null; } return BBox2.merge(textBoxes); } getLabelOrientation() { const { label } = this; return label instanceof AngleAxisLabel ? label.orientation : "fixed"; } getLabelRotation(tickAngle) { let rotation = toRadians2(this.label.rotation ?? 0); tickAngle = normalizeAngle36022(tickAngle); const orientation = this.getLabelOrientation(); if (orientation === "parallel") { rotation += tickAngle; if (tickAngle >= 0 && tickAngle < Math.PI) { rotation -= Math.PI / 2; } else { rotation += Math.PI / 2; } } else if (orientation === "perpendicular") { rotation += tickAngle; if (tickAngle >= Math.PI / 2 && tickAngle < 1.5 * Math.PI) { rotation += Math.PI; } } return rotation; } getLabelAlign(tickAngle) { const cos = Math.cos(tickAngle); const sin = Math.sin(tickAngle); let textAlign; let textBaseline; const orientation = this.getLabelOrientation(); const isCos0 = isNumberEqual22(cos, 0); const isSin0 = isNumberEqual22(sin, 0); const isCos1 = isNumberEqual22(cos, 1); const isSinMinus1 = isNumberEqual22(sin, -1); const isCosPositive = cos > 0 && !isCos0; const isSinPositive = sin > 0 && !isSin0; if (orientation === "parallel") { textAlign = "center"; textBaseline = isCos1 && isSin0 || isSinPositive ? "top" : "bottom"; } else if (orientation === "perpendicular") { textAlign = isSinMinus1 || isCosPositive ? "left" : "right"; textBaseline = "middle"; } else { textAlign = "right"; if (isCos0) { textAlign = "center"; } else if (isCosPositive) { textAlign = "left"; } textBaseline = "bottom"; if (isSin0) { textBaseline = "middle"; } else if (isSinPositive) { textBaseline = "top"; } } return { textAlign, textBaseline }; } updateCrossLines() { const { shape, gridLength: radius, innerRadiusRatio } = this; this.crossLines.forEach((crossLine) => { if (crossLine instanceof AngleCrossLine) { crossLine.ticks = this.tickData.map((t) => t.value); crossLine.shape = shape; crossLine.axisOuterRadius = radius; crossLine.axisInnerRadius = radius * innerRadiusRatio; } }); super.updateCrossLines(); } }; AngleAxis.CrossLineConstructor = AngleCrossLine; __decorateClass2([ ProxyOnWrite2("rotation"), Validate3(NUMBER22) ], AngleAxis.prototype, "startAngle", 2); __decorateClass2([ Validate3(NUMBER22, { optional: true }) ], AngleAxis.prototype, "endAngle", 2); var { RATIO: RATIO22, OBJECT: OBJECT22, Validate: Validate4, isNumberEqual: isNumberEqual3, CategoryScale: CategoryScale2 } = import_ag_charts_community5._ModuleSupport; var AngleCategoryAxis = class extends AngleAxis { constructor(moduleCtx) { super(moduleCtx, new CategoryScale2()); this.groupPaddingInner = 0; this.paddingInner = 0; this.interval = new AngleAxisInterval(); } generateAngleTicks() { const { scale: scale2, gridLength: radius } = this; const { values, minSpacing } = this.interval; const ticks = values ?? scale2.ticks({ nice: this.nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity }) ?? []; if (ticks.length < 2 || isNaN(minSpacing)) { return ticks.map((value) => { return { value, visible: true }; }); } const startTick = ticks[0]; const startAngle = scale2.convert(startTick); const startX = radius * Math.cos(startAngle); const startY = radius * Math.sin(startAngle); for (let step = 1; step < ticks.length - 1; step++) { const nextTick = ticks[step]; const nextAngle = scale2.convert(nextTick); if (nextAngle - startAngle > Math.PI) { break; } const nextX = radius * Math.cos(nextAngle); const nextY = radius * Math.sin(nextAngle); const spacing = Math.sqrt((nextX - startX) ** 2 + (nextY - startY) ** 2); if (spacing > minSpacing) { const visibleTicks = /* @__PURE__ */ new Set([startTick]); loopSymmetrically(ticks, step, (_, next) => { visibleTicks.add(next); }); return ticks.map((value) => { const visible = visibleTicks.has(value); return { value, visible }; }); } } return [{ value: startTick, visible: true }]; } avoidLabelCollisions(labelData) { let { minSpacing } = this.label; if (!Number.isFinite(minSpacing)) { minSpacing = 0; } if (labelData.length < 3) { return; } const labelsCollide = (prev, next) => { if (prev.hidden || next.hidden) { return false; } const prevBox = prev.box.clone().grow(minSpacing / 2); const nextBox = next.box.clone().grow(minSpacing / 2); return prevBox.collidesBBox(nextBox); }; const firstLabel = labelData[0]; const lastLabel = labelData.at(-1); const visibleLabels = /* @__PURE__ */ new Set([firstLabel]); const lastLabelIsOverFirst = isNumberEqual3(firstLabel.x, lastLabel.x) && isNumberEqual3(firstLabel.y, lastLabel.y); const maxStep = Math.floor(labelData.length / 2); for (let step = 1; step <= maxStep; step++) { const labels = lastLabelIsOverFirst ? labelData.slice(0, -1) : labelData; const collisionDetected = loopSymmetrically(labels, step, labelsCollide); if (!collisionDetected) { loopSymmetrically(labels, step, (_, next) => { visibleLabels.add(next); }); break; } } labelData.forEach((datum) => { if (!visibleLabels.has(datum)) { datum.hidden = true; datum.box = void 0; } }); } }; AngleCategoryAxis.className = "AngleCategoryAxis"; AngleCategoryAxis.type = "angle-category"; __decorateClass2([ Validate4(RATIO22) ], AngleCategoryAxis.prototype, "groupPaddingInner", 2); __decorateClass2([ Validate4(RATIO22) ], AngleCategoryAxis.prototype, "paddingInner", 2); __decorateClass2([ Validate4(OBJECT22) ], AngleCategoryAxis.prototype, "interval", 2); var AngleCategoryAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "angle-category", moduleFactory: (ctx) => new AngleCategoryAxis(ctx) }; var import_ag_charts_community7 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community6 = (init_main4(), __toCommonJS(main_exports)); var { range: range3, isDenseInterval: isDenseInterval2, isNumberEqual: isNumberEqual4, LinearScale: LinearScale2 } = import_ag_charts_community6._ModuleSupport; var LinearAngleScale = class _LinearAngleScale extends LinearScale2 { constructor() { super(...arguments); this.arcLength = 0; } static getNiceStepAndTickCount(ticks, domain) { const [start2, stop] = domain; let step = LinearScale2.getTickStep(start2, stop, ticks); const maxTickCount = isNaN(ticks.maxTickCount) ? Infinity : ticks.maxTickCount; const expectedTickCount = Math.abs(stop - start2) / step; let niceTickCount = Math.pow(2, Math.ceil(Math.log(expectedTickCount) / Math.log(2))); if (niceTickCount > maxTickCount) { niceTickCount /= 2; step *= 2; } return { count: niceTickCount, step }; } ticks(ticks, domain = this.domain) { const { arcLength } = this; if (!domain || domain.length < 2 || domain.some((d) => !isFinite(d)) || arcLength <= 0) { return []; } const { nice, interval } = ticks; const [d0, d1] = domain; if (interval) { const step2 = Math.abs(interval); const availableRange = this.getPixelRange(); if (!isDenseInterval2((d1 - d0) / step2, availableRange)) { return range3(d0, d1, step2); } } let step; if (nice && this.hasNiceRange()) { const linearNiceDomain = super.niceDomain(ticks, domain); step = _LinearAngleScale.getNiceStepAndTickCount(ticks, linearNiceDomain).step; } else { step = LinearScale2.getTickStep(d0, d1, ticks); } return range3(d0, d1, step); } hasNiceRange() { const sortedRange = this.range.slice().sort((a, b) => a - b); const niceRanges = [Math.PI, 2 * Math.PI]; return niceRanges.some((r) => isNumberEqual4(r, sortedRange[1] - sortedRange[0])); } niceDomain(ticks, domain = this.domain) { const linearNiceDomain = super.niceDomain(ticks, domain); if (!this.hasNiceRange()) return linearNiceDomain; const reversed = linearNiceDomain[0] > linearNiceDomain[1]; const start2 = reversed ? linearNiceDomain[1] : linearNiceDomain[0]; const { step, count } = _LinearAngleScale.getNiceStepAndTickCount(ticks, linearNiceDomain); const s = 1 / step; const stop = step >= 1 ? Math.ceil(start2 / step + count) * step : Math.ceil((start2 + count * step) * s) / s; return reversed ? [stop, start2] : [start2, stop]; } getPixelRange() { return this.arcLength; } }; var { AND: AND22, Default: Default2, GREATER_THAN: GREATER_THAN2, LESS_THAN: LESS_THAN2, NUMBER_OR_NAN: NUMBER_OR_NAN2, OBJECT: OBJECT3, Validate: Validate5, angleBetween: angleBetween2, isNumberEqual: isNumberEqual5, normalisedExtentWithMetadata: normalisedExtentWithMetadata2, findMinMax: findMinMax2 } = import_ag_charts_community7._ModuleSupport; var AngleNumberAxis = class extends AngleAxis { constructor(moduleCtx) { super(moduleCtx, new LinearAngleScale()); this.shape = "circle"; this.min = NaN; this.max = NaN; this.interval = new AngleAxisInterval(); } normaliseDataDomain(d) { const { min, max } = this; const { extent: extent3, clipped } = normalisedExtentWithMetadata2(d, min, max); return { domain: extent3, clipped }; } updateScale() { super.updateScale(); this.scale.arcLength = this.getRangeArcLength(); } getRangeArcLength() { const { range: requestedRange } = this; const min = Math.min(...requestedRange); const max = Math.max(...requestedRange); const rotation = angleBetween2(min, max) || 2 * Math.PI; const radius = this.gridLength; return rotation * radius; } generateAngleTicks(domain) { const { scale: scale2, range: requestedRange, nice } = this; const { values, step, minSpacing, maxSpacing } = this.interval; let rawTicks; if (values == null) { const { arcLength } = scale2; const minTickCount = maxSpacing ? Math.floor(arcLength / maxSpacing) : 1; const maxTickCount = minSpacing ? Math.floor(arcLength / minSpacing) : Infinity; const preferredTickCount = Math.floor(4 / Math.PI * Math.abs(requestedRange[0] - requestedRange[1])); const tickCount = Math.max(minTickCount, Math.min(maxTickCount, preferredTickCount)); const tickParams = { nice, interval: step, tickCount, minTickCount, maxTickCount }; rawTicks = scale2.ticks(tickParams, domain); } else { const [d0, d1] = findMinMax2(domain.map(Number)); rawTicks = values.filter((value) => value >= d0 && value <= d1).sort((a, b) => a - b); } return rawTicks.map((value) => ({ value, visible: true })); } avoidLabelCollisions(labelData) { let { minSpacing } = this.label; if (!Number.isFinite(minSpacing)) { minSpacing = 0; } const labelsCollide = (prev, next) => { if (prev.hidden || next.hidden) { return false; } const prevBox = prev.box.clone().grow(minSpacing / 2); const nextBox = next.box.clone().grow(minSpacing / 2); return prevBox.collidesBBox(nextBox); }; const firstLabel = labelData[0]; const lastLabel = labelData.at(-1); if (firstLabel !== lastLabel && isNumberEqual5(firstLabel.x, lastLabel.x) && isNumberEqual5(firstLabel.y, lastLabel.y)) { lastLabel.hidden = true; } for (let step = 1; step < labelData.length; step *= 2) { let collisionDetected = false; for (let i = step; i < labelData.length; i += step) { const next = labelData[i]; const prev = labelData[i - step]; if (labelsCollide(prev, next)) { collisionDetected = true; break; } } if (!collisionDetected) { labelData.forEach((datum, i) => { if (i % step > 0) { datum.hidden = true; datum.box = void 0; } }); return; } } labelData.forEach((datum, i) => { if (i > 0) { datum.hidden = true; datum.box = void 0; } }); } }; AngleNumberAxis.className = "AngleNumberAxis"; AngleNumberAxis.type = "angle-number"; __decorateClass2([ Validate5(AND22(NUMBER_OR_NAN2, LESS_THAN2("max"))), Default2(NaN) ], AngleNumberAxis.prototype, "min", 2); __decorateClass2([ Validate5(AND22(NUMBER_OR_NAN2, GREATER_THAN2("min"))), Default2(NaN) ], AngleNumberAxis.prototype, "max", 2); __decorateClass2([ Validate5(OBJECT3) ], AngleNumberAxis.prototype, "interval", 2); var AngleNumberAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "angle-number", moduleFactory: (ctx) => new AngleNumberAxis(ctx) }; var import_ag_charts_community8 = (init_main4(), __toCommonJS(main_exports)); var { OrdinalTimeScale: OrdinalTimeScale2 } = import_ag_charts_community8._ModuleSupport; var OrdinalTimeAxis = class extends import_ag_charts_community8._ModuleSupport.CategoryAxis { constructor(moduleCtx) { super(moduleCtx, new OrdinalTimeScale2()); } }; OrdinalTimeAxis.className = "OrdinalTimeAxis"; OrdinalTimeAxis.type = "ordinal-time"; var OrdinalTimeAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "ordinal-time", moduleFactory: (ctx) => new OrdinalTimeAxis(ctx) }; var import_ag_charts_community11 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community10 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community9 = (init_main4(), __toCommonJS(main_exports)); var { ChartAxisDirection: ChartAxisDirection4, Validate: Validate6, NUMBER: NUMBER3, validateCrossLineValues: validateCrossLineValues22, clamp: clamp2, normalizeAngle360: normalizeAngle3603, toRadians: toRadians22, isNumberEqual: isNumberEqual6, Group: Group3, Path: Path3, Sector: Sector22, RotatableText: RotatableText3 } = import_ag_charts_community9._ModuleSupport; var RadiusCrossLineLabel = class extends PolarCrossLineLabel { constructor() { super(...arguments); this.positionAngle = void 0; } }; __decorateClass2([ Validate6(NUMBER3, { optional: true }) ], RadiusCrossLineLabel.prototype, "positionAngle", 2); var RadiusCrossLine = class extends PolarCrossLine { constructor() { super(); this.direction = ChartAxisDirection4.Y; this.label = new RadiusCrossLineLabel(); this.polygonNode = new Path3(); this.sectorNode = new Sector22(); this.crossLineRange = new Group3(); this.labelNode = new RotatableText3(); this.outerRadius = 0; this.innerRadius = 0; this.crossLineRange.append(this.polygonNode); this.crossLineRange.append(this.sectorNode); this.labelGroup.append(this.labelNode); } update(visible) { const { scale: scale2, type, value, range: range22 } = this; if (!scale2 || !type || !validateCrossLineValues22(type, value, range22, scale2)) { this.rangeGroup.visible = false; this.lineGroup.visible = false; this.labelGroup.visible = false; return; } if (type === "line" && scale2 instanceof import_ag_charts_community9._ModuleSupport.BandScale) { this.type = "range"; this.range = [value, value]; } this.updateRadii(); const { innerRadius, outerRadius } = this; visible && (visible = innerRadius >= this.axisInnerRadius && outerRadius <= this.axisOuterRadius); this.rangeGroup.visible = visible; this.lineGroup.visible = visible; this.labelGroup.visible = visible; this.updatePolygonNode(visible); this.updateSectorNode(visible); this.updateLabelNode(visible); this.assignCrossLineGroup(this.type === "range", this.crossLineRange); } updateRadii() { const { range: range22, scale: scale2, type, axisInnerRadius, axisOuterRadius } = this; if (!scale2) return { innerRadius: 0, outerRadius: 0 }; const getRadius = (value) => axisOuterRadius + axisInnerRadius - value; let outerRadius, innerRadius; if (type === "line") { outerRadius = getRadius(scale2.convert(this.value)); innerRadius = outerRadius; } else { const bandwidth = Math.abs(scale2?.bandwidth ?? 0); const convertedRange = range22.map((r) => scale2.convert(r)); outerRadius = getRadius(Math.max(...convertedRange)); innerRadius = getRadius(Math.min(...convertedRange)) + bandwidth; } this.outerRadius = outerRadius; this.innerRadius = innerRadius; } drawPolygon(radius, angles, polygon) { angles.forEach((angle2, index) => { const x = radius * Math.cos(angle2); const y = radius * Math.sin(angle2); if (index === 0) { polygon.path.moveTo(x, y); } else { polygon.path.lineTo(x, y); } }); polygon.path.closePath(); } updatePolygonNode(visible) { const { gridAngles, polygonNode: polygon, scale: scale2, shape, type, innerRadius, outerRadius } = this; if (!visible || shape !== "polygon" || !scale2 || !gridAngles) { polygon.visible = false; return; } polygon.visible = true; const padding = this.getPadding(); polygon.path.clear(true); this.drawPolygon(outerRadius - padding, gridAngles, polygon); const reversedAngles = gridAngles.slice().reverse(); const innerPolygonRadius = type === "line" ? outerRadius - padding : innerRadius + padding; this.drawPolygon(innerPolygonRadius, reversedAngles, polygon); this.setSectorNodeProps(polygon); } updateSectorNode(visible) { const { axisInnerRadius, axisOuterRadius, scale: scale2, sectorNode: sector, shape, innerRadius, outerRadius } = this; if (!visible || shape !== "circle" || !scale2) { sector.visible = false; return; } sector.visible = true; sector.startAngle = 0; sector.endAngle = 2 * Math.PI; const padding = this.getPadding(); const r0 = clamp2(axisInnerRadius, innerRadius + padding, axisOuterRadius); const r1 = clamp2(axisInnerRadius, outerRadius - padding, axisOuterRadius); sector.innerRadius = Math.min(r0, r1); sector.outerRadius = Math.max(r0, r1); this.setSectorNodeProps(sector); } updateLabelNode(visible) { const { innerRadius, label, labelNode: node, scale: scale2, shape, type } = this; if (!visible || label.enabled === false || !label.text || !scale2) { node.visible = false; return; } const angle2 = normalizeAngle3603(toRadians22((label.positionAngle ?? 0) - 90)); const isBottomSide = (isNumberEqual6(angle2, 0) || angle2 > 0) && angle2 < Math.PI; const rotation = isBottomSide ? angle2 - Math.PI / 2 : angle2 + Math.PI / 2; let distance2; const angles = this.gridAngles ?? []; if (type === "line") { distance2 = innerRadius + label.padding; } else if (shape === "circle" || angles.length < 3) { distance2 = innerRadius - label.padding; } else { distance2 = innerRadius * Math.cos(Math.PI / angles.length) - label.padding; } const labelX = distance2 * Math.cos(angle2); const labelY = distance2 * Math.sin(angle2); let textBaseline; if (type === "line") { textBaseline = isBottomSide ? "top" : "bottom"; } else { textBaseline = isBottomSide ? "bottom" : "top"; } this.setLabelNodeProps(node, labelX, labelY, textBaseline, rotation); } getPadding() { const { scale: scale2 } = this; if (!scale2) return 0; const bandwidth = Math.abs(scale2.bandwidth ?? 0); const step = Math.abs(scale2.step ?? 0); return scale2 instanceof import_ag_charts_community9._ModuleSupport.BandScale ? (step - bandwidth) / 2 : 0; } }; RadiusCrossLine.className = "RadiusCrossLine"; var { ChartAxisDirection: ChartAxisDirection5, Default: Default22, ZIndexMap: ZIndexMap2, NUMBER: NUMBER4, BOOLEAN: BOOLEAN22, Validate: Validate7, isNumberEqual: isNumberEqual7, normalizeAngle360: normalizeAngle3604, toRadians: toRadians3, Caption: Caption2, Group: Group4, Path: Path4, Line: Line2, Selection: Selection2, AxisTickGenerator: AxisTickGenerator2, AxisGroupZIndexMap: AxisGroupZIndexMap2 } = import_ag_charts_community10._ModuleSupport; var RadiusAxisLabel = class extends import_ag_charts_community10._ModuleSupport.AxisLabel { constructor() { super(...arguments); this.autoRotateAngle = 335; } }; __decorateClass2([ Validate7(BOOLEAN22, { optional: true }) ], RadiusAxisLabel.prototype, "autoRotate", 2); __decorateClass2([ Validate7(NUMBER4) ], RadiusAxisLabel.prototype, "autoRotateAngle", 2); var RadiusAxis = class extends import_ag_charts_community10._ModuleSupport.PolarAxis { constructor(moduleCtx, scale2) { super(moduleCtx, scale2); this.positionAngle = 0; this.tickGenerator = new AxisTickGenerator2(this); this.generatedTicks = void 0; this.lineNode = this.axisGroup.appendChild( new Line2({ name: `${this.id}-Axis-line`, zIndex: AxisGroupZIndexMap2.AxisLine }) ); this.gridPathGroup = this.gridGroup.appendChild( new Group4({ name: `${this.id}-gridPaths`, zIndex: ZIndexMap2.AXIS_GRID }) ); this.gridPathSelection = Selection2.select(this.gridPathGroup, Path4); this.axisGroup.appendChild(this.title.caption.node); this.destroyFns.push(this.title.caption.registerInteraction(this.moduleCtx, "afterend")); } get direction() { return ChartAxisDirection5.Y; } getAxisTransform() { const maxRadius = this.scale.range[0]; const { translation, positionAngle, innerRadiusRatio } = this; const innerRadius = maxRadius * innerRadiusRatio; const rotation = toRadians3(positionAngle); return { translationX: translation.x, translationY: translation.y - maxRadius - innerRadius, rotation, rotationCenterX: 0, rotationCenterY: maxRadius + innerRadius }; } update() { super.update(); this.updateTitle(); const { enabled, stroke: stroke22, width: width2 } = this.line; this.lineNode.setProperties({ stroke: stroke22, strokeWidth: enabled ? width2 : 0, x1: 0, y1: this.range[0], x2: 0, y2: this.range[1] }); } calculateTickLayout(domain, niceMode, _visibleRange, initialPrimaryTickCount) { const { parallelFlipRotation, regularFlipRotation } = this.calculateRotations(); const visibleRange = [0, 1]; const sideFlag = this.label.getSideFlag(); const labelX = sideFlag * (this.getTickSize() + this.label.spacing + this.seriesAreaPadding); const tickGenerationResult = this.tickGenerator.generateTicks({ domain, niceMode, visibleRange, primaryTickCount: initialPrimaryTickCount, parallelFlipRotation, regularFlipRotation, labelX, sideFlag }); const { tickData, primaryTickCount = initialPrimaryTickCount } = tickGenerationResult; const { ticks, rawTicks, tickDomain, fractionDigits, niceDomain = domain } = tickData; const labels = ticks.map((d) => this.getTickLabelProps(d, tickGenerationResult)); this.generatedTicks = { ticks, labels }; return { ticks: rawTicks, tickDomain, niceDomain, primaryTickCount, fractionDigits, bbox: void 0 }; } updateSelections() { const { generatedTicks } = this; if (!generatedTicks) return; const { ticks, labels } = generatedTicks; this.gridLineGroupSelection.update(this.gridLength ? ticks : []); this.tickLineGroupSelection.update(ticks); this.tickLabelGroupSelection.update(labels); this.gridPathSelection.update(this.gridLine.enabled ? this.prepareGridPathTickData(ticks) : []); this.gridLineGroupSelection.cleanup(); this.tickLineGroupSelection.cleanup(); this.tickLabelGroupSelection.cleanup(); this.gridPathSelection.cleanup(); } // TODO - abstract out updateLabels() { if (!this.label.enabled) return; const axisLabelPositionFn = import_ag_charts_community10._ModuleSupport.resetAxisLabelSelectionFn(); this.tickLabelGroupSelection.each((node, datum) => { node.fill = datum.fill; node.fontFamily = datum.fontFamily; node.fontSize = datum.fontSize; node.fontStyle = datum.fontStyle; node.fontWeight = datum.fontWeight; node.text = datum.text; node.textBaseline = datum.textBaseline; node.textAlign = datum.textAlign ?? "center"; node.setProperties(axisLabelPositionFn(node, datum)); }); } updateGridLines() { super.updateGridLines(); const { gridLine: { style, width: width2 }, shape, generatedTicks } = this; if (!style || !generatedTicks) { return; } const styleCount = style.length; const setStyle = (node, index) => { const { stroke: stroke22, lineDash } = style[index % styleCount]; node.stroke = stroke22; node.strokeWidth = width2; node.lineDash = lineDash; node.fill = void 0; }; const [startAngle, endAngle] = this.gridRange ?? [0, 2 * Math.PI]; const isFullCircle = isNumberEqual7(endAngle - startAngle, 2 * Math.PI); const drawCircleShape = (node, value) => { const { path } = node; path.clear(true); const radius = this.getTickRadius(value); if (isFullCircle) { path.moveTo(radius, 0); path.arc(0, 0, radius, 0, 2 * Math.PI); } else { path.moveTo(radius * Math.cos(startAngle), radius * Math.sin(startAngle)); path.arc(0, 0, radius, normalizeAngle3604(startAngle), normalizeAngle3604(endAngle)); } if (isFullCircle) { path.closePath(); } }; const drawPolygonShape = (node, value) => { const { path } = node; const angles = this.gridAngles; path.clear(true); if (!angles || angles.length < 3) { return; } const radius = this.getTickRadius(value); angles.forEach((angle2, idx) => { const x = radius * Math.cos(angle2); const y = radius * Math.sin(angle2); if (idx === 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } angles.forEach((innerAngle, innerIdx) => { const x2 = radius * Math.cos(innerAngle); const y2 = radius * Math.sin(innerAngle); if (innerIdx === 0) { path.moveTo(x2, y2); } else { path.lineTo(x2, y2); } }); path.closePath(); }); path.closePath(); }; const drawFn = shape === "circle" ? drawCircleShape : drawPolygonShape; this.gridPathSelection.each((node, value, index) => { setStyle(node, index); drawFn(node, value); }); } updateTitle() { const identityFormatter = (params) => params.defaultValue; const { title, range: requestedRange, moduleCtx: { callbackCache } } = this; const { formatter = identityFormatter } = this.title; title.caption.enabled = title.enabled; title.caption.fontFamily = title.fontFamily; title.caption.fontSize = title.fontSize; title.caption.fontStyle = title.fontStyle; title.caption.fontWeight = title.fontWeight; title.caption.color = title.color; title.caption.wrapping = title.wrapping; let titleVisible = false; const titleNode = title.caption.node; if (title.enabled) { titleVisible = true; titleNode.rotation = Math.PI / 2; titleNode.x = Math.floor((requestedRange[0] + requestedRange[1]) / 2); titleNode.y = -Caption2.SMALL_PADDING; titleNode.textAlign = "center"; titleNode.textBaseline = "bottom"; titleNode.text = callbackCache.call(formatter, this.getTitleFormatterParams()); } titleNode.visible = titleVisible; } updateCrossLines() { this.crossLines.forEach((crossLine) => { if (crossLine instanceof RadiusCrossLine) { const { shape, gridAngles, range: range22, innerRadiusRatio } = this; const radius = range22[0]; crossLine.shape = shape; crossLine.gridAngles = gridAngles; crossLine.axisOuterRadius = radius; crossLine.axisInnerRadius = radius * innerRadiusRatio; } }); super.updateCrossLines(); } createLabel() { return new RadiusAxisLabel(); } // TODO - abstract out (shared with cartesian axis) getTickLabelProps(datum, tickGenerationResult) { const { label } = this; const { combinedRotation, textBaseline, textAlign } = tickGenerationResult; const range22 = this.scale.range; const text22 = datum.tickLabel; const sideFlag = label.getSideFlag(); const labelX = sideFlag * (this.getTickSize() + label.spacing + this.seriesAreaPadding); const visible = text22 !== "" && text22 != null; return { ...this.getLabelStyles({ value: datum.tickLabel }), tickId: datum.tickId, rotation: combinedRotation, rotationCenterX: labelX, translationY: datum.translationY, text: text22, textAlign, textBaseline, visible, x: labelX, y: 0, range: range22 }; } }; RadiusAxis.CrossLineConstructor = RadiusCrossLine; __decorateClass2([ Validate7(NUMBER4), Default22(0) ], RadiusAxis.prototype, "positionAngle", 2); var { RATIO: RATIO3, ProxyPropertyOnWrite: ProxyPropertyOnWrite2, Validate: Validate8, CategoryScale: CategoryScale22 } = import_ag_charts_community11._ModuleSupport; var RadiusCategoryAxis = class extends RadiusAxis { constructor(moduleCtx) { super(moduleCtx, new CategoryScale22()); this.shape = "circle"; this.groupPaddingInner = 0; this.paddingInner = 0; this.paddingOuter = 0; } normaliseDataDomain(domain) { return { domain, clipped: false }; } prepareGridPathTickData(data) { return data.slice().reverse(); } getTickRadius(tickDatum) { const { scale: scale2, innerRadiusRatio } = this; const maxRadius = scale2.range[0]; const minRadius = maxRadius * innerRadiusRatio; if (CategoryScale22.is(scale2)) { const ticks = scale2.domain; const index = ticks.length - 1 - ticks.indexOf(tickDatum.tick); return index === 0 ? minRadius : scale2.inset + scale2.step * (index - 0.5) + scale2.bandwidth / 2; } else { const tickRange = (maxRadius - minRadius) / scale2.domain.length; return maxRadius - tickDatum.translationY + minRadius - tickRange / 2; } } }; RadiusCategoryAxis.className = "RadiusCategoryAxis"; RadiusCategoryAxis.type = "radius-category"; __decorateClass2([ Validate8(RATIO3) ], RadiusCategoryAxis.prototype, "groupPaddingInner", 2); __decorateClass2([ ProxyPropertyOnWrite2("scale", "paddingInner"), Validate8(RATIO3) ], RadiusCategoryAxis.prototype, "paddingInner", 2); __decorateClass2([ ProxyPropertyOnWrite2("scale", "paddingOuter"), Validate8(RATIO3) ], RadiusCategoryAxis.prototype, "paddingOuter", 2); var RadiusCategoryAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radius-category", moduleFactory: (ctx) => new RadiusCategoryAxis(ctx) }; var import_ag_charts_community12 = (init_main4(), __toCommonJS(main_exports)); var { AND: AND3, Default: Default3, GREATER_THAN: GREATER_THAN22, LESS_THAN: LESS_THAN22, NUMBER_OR_NAN: NUMBER_OR_NAN22, Validate: Validate9, normalisedExtentWithMetadata: normalisedExtentWithMetadata22, LinearScale: LinearScale22 } = import_ag_charts_community12._ModuleSupport; var RadiusNumberAxis = class extends RadiusAxis { constructor(moduleCtx) { super(moduleCtx, new LinearScale22()); this.shape = "polygon"; this.min = NaN; this.max = NaN; } prepareGridPathTickData(data) { const { scale: scale2 } = this; const domainTop = scale2.domain[1]; return data.filter(({ tick }) => tick !== domainTop).sort((a, b) => b.tick - a.tick); } getTickRadius(tickDatum) { const { scale: scale2 } = this; const maxRadius = scale2.range[0]; const minRadius = maxRadius * this.innerRadiusRatio; return maxRadius - tickDatum.translationY + minRadius; } normaliseDataDomain(d) { const { min, max } = this; const { extent: extent3, clipped } = normalisedExtentWithMetadata22(d, min, max); return { domain: extent3, clipped }; } }; RadiusNumberAxis.className = "RadiusNumberAxis"; RadiusNumberAxis.type = "radius-number"; __decorateClass2([ Validate9(AND3(NUMBER_OR_NAN22, LESS_THAN22("max"))), Default3(NaN) ], RadiusNumberAxis.prototype, "min", 2); __decorateClass2([ Validate9(AND3(NUMBER_OR_NAN22, GREATER_THAN22("min"))), Default3(NaN) ], RadiusNumberAxis.prototype, "max", 2); var RadiusNumberAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radius-number", moduleFactory: (ctx) => new RadiusNumberAxis(ctx) }; var import_ag_charts_community14 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community13 = (init_main4(), __toCommonJS(main_exports)); var { Chart: Chart2 } = import_ag_charts_community13._ModuleSupport; function isFlowProportion(series) { return series.type === "sankey" || series.type === "chord"; } var FlowProportionChart = class extends Chart2 { getChartType() { return "flow-proportion"; } async updateData() { await super.updateData(); const { nodes } = this.getOptions(); this.series.forEach((series) => { if (isFlowProportion(series)) { series.setChartNodes(nodes); } }); } performLayout(ctx) { const { seriesRoot, annotationRoot } = this; const { layoutBox } = ctx; layoutBox.shrink(this.seriesArea.padding.toJson()); const seriesRect = layoutBox.clone(); this.seriesRect = seriesRect; this.animationRect = seriesRect; seriesRoot.visible = this.series.some((s) => s.visible); for (const group of [seriesRoot, annotationRoot]) { group.translationX = Math.floor(seriesRect.x); group.translationY = Math.floor(seriesRect.y); } this.ctx.layoutManager.emitLayoutComplete(ctx, { series: { visible: seriesRoot.visible, rect: seriesRect, paddedRect: seriesRect } }); } }; FlowProportionChart.className = "FlowProportionChart"; FlowProportionChart.type = "flow-proportion"; var { isAgFlowProportionChartOptions: isAgFlowProportionChartOptions2 } = import_ag_charts_community14._ModuleSupport; var FlowProportionChartModule = { type: "chart", name: "flow-proportion", detect: isAgFlowProportionChartOptions2, create(options, resources) { return new FlowProportionChart(options, resources); } }; var import_ag_charts_community16 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community15 = (init_main4(), __toCommonJS(main_exports)); var logger_exports2 = {}; __export2(logger_exports2, { error: () => error2, errorOnce: () => errorOnce2, log: () => log3, logGroup: () => logGroup2, reset: () => reset2, table: () => table2, warn: () => warn2, warnOnce: () => warnOnce2 }); var doOnceCache2 = /* @__PURE__ */ new Set(); function log3(...logContent) { console.log(...logContent); } function warn2(message, ...logContent) { console.warn(`AG Charts - ${message}`, ...logContent); } function error2(message, ...logContent) { if (typeof message === "object") { console.error(`AG Charts error`, message, ...logContent); } else { console.error(`AG Charts - ${message}`, ...logContent); } } function table2(...logContent) { console.table(...logContent); } function warnOnce2(message, ...logContent) { const cacheKey = `Logger.warn: ${message}`; if (doOnceCache2.has(cacheKey)) return; warn2(message, ...logContent); doOnceCache2.add(cacheKey); } function errorOnce2(message, ...logContent) { const cacheKey = `Logger.error: ${message}`; if (doOnceCache2.has(cacheKey)) return; error2(message, ...logContent); doOnceCache2.add(cacheKey); } function reset2() { doOnceCache2.clear(); } function logGroup2(name, cb) { console.groupCollapsed(name); try { return cb(); } finally { console.groupEnd(); } } function unique2(array2) { return Array.from(new Set(array2)); } function findMaxValue(min, max, iteratee) { if (min > max) return; let found; while (max >= min) { const index = Math.floor((max + min) / 2); const value = iteratee(index); if (value == null) { max = index - 1; } else { found = value; min = index + 1; } } return found; } 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* iterate2(...iterators) { for (const iterator of iterators) { yield* iterator; } } function isDefined2(val) { return val != null; } function isArray2(value) { return Array.isArray(value); } function isDate2(value) { return value instanceof Date; } function isValidDate2(value) { return isDate2(value) && !isNaN(Number(value)); } function isObject2(value) { return typeof value === "object" && value !== null && !isArray2(value); } function isString2(value) { return typeof value === "string"; } function isNumber2(value) { return typeof value === "number"; } function isFiniteNumber2(value) { return Number.isFinite(value); } var { CartesianAxis: CartesianAxis2, Chart: Chart22, ChartAxisDirection: ChartAxisDirection6, LinearScale: LinearScale3, PolarAxis: PolarAxis2, isBetweenAngles: isBetweenAngles2, normalizeAngle360Inclusive: normalizeAngle360Inclusive22, sectorBox: sectorBox2 } = import_ag_charts_community15._ModuleSupport; function isRadialGaugeSeries(series) { return series.type === "radial-gauge"; } function isLinearGaugeSeries(series) { return series.type === "linear-gauge"; } var GaugeChart = class extends Chart22 { getChartType() { return "gauge"; } updateRadialGauge(seriesRect, series) { const angleAxis = this.axes.find((axis) => axis.direction === ChartAxisDirection6.X); if (!(angleAxis instanceof PolarAxis2)) return; angleAxis.computeRange(); const seriesRectX0 = seriesRect.x; const seriesRectX1 = seriesRectX0 + seriesRect.width; const seriesRectY0 = seriesRect.y; const seriesRectY1 = seriesRectY0 + seriesRect.height; const [startAngle, endAngle] = angleAxis.range; const sweepAngle = normalizeAngle360Inclusive22(endAngle - startAngle); const largerThanHalf = sweepAngle > Math.PI; const containsTop = largerThanHalf || isBetweenAngles2(1.5 * Math.PI, startAngle, endAngle); const containsRight = largerThanHalf || isBetweenAngles2(0 * Math.PI, startAngle, endAngle); const containsBottom = largerThanHalf || isBetweenAngles2(0.5 * Math.PI, startAngle, endAngle); const containsLeft = largerThanHalf || isBetweenAngles2(1 * Math.PI, startAngle, endAngle); let textAlign; if (containsLeft && !containsRight) { textAlign = "right"; } else if (!containsLeft && containsRight) { textAlign = "left"; } else { textAlign = "center"; } let verticalAlign; if (containsTop && !containsBottom) { verticalAlign = "bottom"; } else if (!containsTop && containsBottom) { verticalAlign = "top"; } else { verticalAlign = "middle"; } const unitBox = sectorBox2({ startAngle, endAngle, innerRadius: 0, outerRadius: 0.5 }); const centerXOffset = -(unitBox.x + unitBox.width / 2) * 2; const centerYOffset = -(unitBox.y + unitBox.height / 2) * 2; const { minimumRadius = 0, maximumRadius } = series; const radiusBounds = Math.max( 0.5 * Math.min(seriesRect.width / unitBox.width, seriesRect.height / unitBox.height), // seriesRect may have negative size 0 ); let radius = Math.min(maximumRadius ?? Infinity, Math.max(radiusBounds, minimumRadius ?? 0)); const MAX_ITERATIONS = 8; for (let i = 0; i < MAX_ITERATIONS; i += 1) { const isFinalIteration = radius <= minimumRadius || i === MAX_ITERATIONS - 1; const centerX = seriesRect.x + seriesRect.width / 2 + centerXOffset * radius; const centerY = seriesRect.y + seriesRect.height / 2 + centerYOffset * radius; angleAxis.translation.x = centerX; angleAxis.translation.y = centerY; angleAxis.gridLength = radius; angleAxis.calculateLayout(); const bbox = angleAxis.computeLabelsBBox({ hideWhenNecessary: isFinalIteration }, seriesRect); if (isFinalIteration) break; let shrinkDelta = 0; if (bbox != null) { const bboxX0 = bbox.x + centerX; const bboxX1 = bboxX0 + bbox.width; const bboxY0 = bbox.y + centerY; const bboxY1 = bboxY0 + bbox.height; shrinkDelta = Math.max( seriesRectY0 - bboxY0, seriesRectX0 - bboxX0, bboxY1 - seriesRectY1, bboxX1 - seriesRectX1, 0 ); } if (shrinkDelta > 0) { radius = Math.max(radius - shrinkDelta, minimumRadius); } else { break; } } angleAxis.translation.x = seriesRect.x + seriesRect.width / 2 + centerXOffset * radius; angleAxis.translation.y = seriesRect.y + seriesRect.height / 2 + centerYOffset * radius; series.centerX = seriesRect.width / 2 + centerXOffset * radius; series.centerY = seriesRect.height / 2 + centerYOffset * radius; series.radius = radius; series.textAlign = textAlign; series.verticalAlign = verticalAlign; if (radius === 0 || radius > radiusBounds) { logger_exports2.warnOnce("There was insufficient space to display the Radial Gauge."); } } updateLinearGauge(seriesRect, series) { const xAxis = this.axes.find((axis) => axis.direction === ChartAxisDirection6.X); const yAxis = this.axes.find((axis) => axis.direction === ChartAxisDirection6.Y); if (!(xAxis instanceof CartesianAxis2)) return seriesRect; if (!(yAxis instanceof CartesianAxis2)) return seriesRect; const { horizontal, thickness } = series; let horizontalInset = 0; let verticalInset = 0; const scale2 = new LinearScale3(); const scaleAxis = horizontal ? xAxis : yAxis; scale2.domain = [0, 100]; scale2.range = scaleAxis.range; const ticks = scale2.ticks({ nice: scaleAxis.nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity }); if (horizontal) { horizontalInset = series.computeInset(ChartAxisDirection6.X, ticks); } else { verticalInset = series.computeInset(ChartAxisDirection6.Y, ticks); } const seriesWidth = seriesRect.width - Math.abs(horizontalInset); const seriesHeight = seriesRect.height - Math.abs(verticalInset); const { width: width2, height: height2 } = horizontal ? { width: Math.max(seriesWidth, 0), height: Math.max(Math.min(seriesHeight, thickness), 0) } : { width: Math.max(Math.min(seriesWidth, thickness), 0), height: Math.max(seriesHeight, 0) }; const x0 = seriesRect.x + (seriesWidth - width2) / 2 + Math.max(horizontalInset, 0); const y0 = seriesRect.y + (seriesHeight - height2) / 2 - Math.min(verticalInset, 0); xAxis.range = [0, width2]; xAxis.gridLength = width2; xAxis.calculateLayout(); xAxis.translation.x = x0; xAxis.translation.y = y0 + (xAxis.position === "bottom" ? thickness : 0); yAxis.range = [0, height2]; yAxis.gridLength = height2; yAxis.calculateLayout(); yAxis.translation.x = x0 + (yAxis.position === "right" ? thickness : 0); yAxis.translation.y = y0; series.originX = x0 - seriesRect.x; series.originY = y0 - seriesRect.y; if (width2 === 0 || height2 === 0) { logger_exports2.warnOnce("There was insufficient space to display the Linear Gauge."); } } performLayout(ctx) { const { seriesRoot, annotationRoot, series, seriesArea } = this; const { layoutBox } = ctx; const seriesRect = layoutBox.clone(); layoutBox.shrink(seriesArea.padding.toJson()); const firstSeries = this.series[0]; if (isRadialGaugeSeries(firstSeries)) { this.updateRadialGauge(layoutBox, firstSeries); } else if (isLinearGaugeSeries(firstSeries)) { this.updateLinearGauge(layoutBox, firstSeries); } this.axes.forEach((axis) => axis.update()); this.seriesRect = seriesRect.clone().translate(seriesRect.x - layoutBox.x, seriesRect.y - layoutBox.y); this.animationRect = layoutBox; seriesRoot.visible = series.some((s) => s.visible); for (const group of [seriesRoot, annotationRoot]) { group.translationX = Math.floor(layoutBox.x); group.translationY = Math.floor(layoutBox.y); } this.ctx.layoutManager.emitLayoutComplete(ctx, { series: { visible: seriesRoot.visible, rect: seriesRect, paddedRect: layoutBox } }); } getAriaLabel() { const captions = []; const chartCaption = this.getCaptionText(); if (chartCaption.length !== 0) { captions.push(chartCaption); } for (const series of this.series) { captions.push(series.getCaptionText()); } const caption = captions.join(". "); return this.ctx.localeManager.t("ariaAnnounceGaugeChart", { caption }); } }; GaugeChart.className = "GaugeChart"; GaugeChart.type = "gauge"; var { isAgGaugeChartOptions: isAgGaugeChartOptions2 } = import_ag_charts_community16._ModuleSupport; var GaugeChartModule = { type: "chart", name: "gauge", detect: isAgGaugeChartOptions2, create(options, resources) { return new GaugeChart(options, resources); } }; var import_ag_charts_community18 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community17 = (init_main4(), __toCommonJS(main_exports)); var { Chart: Chart3 } = import_ag_charts_community17._ModuleSupport; var HierarchyChart = class extends Chart3 { getChartType() { return "hierarchy"; } performLayout(ctx) { const { seriesRoot, annotationRoot } = this; const { layoutBox } = ctx; layoutBox.shrink(this.seriesArea.padding.toJson()); const seriesRect = layoutBox.clone(); this.seriesRect = seriesRect; this.animationRect = seriesRect; for (const group of [seriesRoot, annotationRoot]) { group.translationX = Math.floor(seriesRect.x); group.translationY = Math.floor(seriesRect.y); } seriesRoot.visible = this.series[0].visible; seriesRoot.setClipRect(seriesRect.clone()); this.ctx.layoutManager.emitLayoutComplete(ctx, { series: { visible: true, rect: seriesRect, paddedRect: seriesRect } }); } getAriaLabel() { const caption = this.getCaptionText(); return this.ctx.localeManager.t("ariaAnnounceHierarchyChart", { caption }); } }; HierarchyChart.className = "HierarchyChart"; HierarchyChart.type = "hierarchy"; var { isAgHierarchyChartOptions: isAgHierarchyChartOptions2 } = import_ag_charts_community18._ModuleSupport; var HierarchyChartModule = { type: "chart", name: "hierarchy", detect: isAgHierarchyChartOptions2, create(options, resources) { return new HierarchyChart(options, resources); } }; var import_ag_charts_community20 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community19 = (init_main4(), __toCommonJS(main_exports)); var { Chart: Chart4 } = import_ag_charts_community19._ModuleSupport; var StandaloneChart = class extends Chart4 { getChartType() { return "standalone"; } performLayout(ctx) { const { seriesRoot, annotationRoot } = this; const { layoutBox } = ctx; layoutBox.shrink(this.seriesArea.padding.toJson()); const seriesRect = layoutBox.clone(); this.seriesRect = seriesRect; this.animationRect = seriesRect; for (const group of [seriesRoot, annotationRoot]) { group.translationX = Math.floor(layoutBox.x); group.translationY = Math.floor(layoutBox.y); } seriesRoot.visible = this.series[0].visible; this.ctx.layoutManager.emitLayoutComplete(ctx, { series: { visible: true, rect: seriesRect, paddedRect: layoutBox } }); } getAriaLabel() { const caption = this.getCaptionText(); return this.ctx.localeManager.t("ariaAnnounceHierarchyChart", { caption }); } }; StandaloneChart.className = "StandaloneChart"; StandaloneChart.type = "standalone"; var { isAgStandaloneChartOptions: isAgStandaloneChartOptions2 } = import_ag_charts_community20._ModuleSupport; var StandaloneChartModule = { type: "chart", name: "standalone", detect: isAgStandaloneChartOptions2, create(options, resources) { return new StandaloneChart(options, resources); } }; var import_ag_charts_community22 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community21 = (init_main4(), __toCommonJS(main_exports)); var { Chart: Chart5, MercatorScale: MercatorScale2, NumberAxis: NumberAxis2 } = import_ag_charts_community21._ModuleSupport; function isTopologySeries(series) { return series.type === "map-shape" || series.type === "map-line" || series.type === "map-marker" || series.type === "map-shape-background" || series.type === "map-line-background"; } var TopologyChart = class extends Chart5 { constructor(options, resources) { super(options, resources); this.xAxis = new NumberAxis2(this.getModuleContext()); this.xAxis.position = "bottom"; this.yAxis = new NumberAxis2(this.getModuleContext()); this.yAxis.position = "left"; this.ctx.zoomManager.updateAxes([this.xAxis, this.yAxis]); } getChartType() { return "topology"; } async updateData() { await super.updateData(); const { topology } = this.getOptions(); this.series.forEach((series) => { if (isTopologySeries(series)) { series.setChartTopology(topology); } }); } performLayout(ctx) { const { seriesRoot, annotationRoot } = this; const { layoutBox } = ctx; layoutBox.shrink(this.seriesArea.padding.toJson()); const seriesRect = layoutBox.clone(); this.seriesRect = seriesRect; this.animationRect = seriesRect; const mapSeries = this.series.filter(isTopologySeries); const combinedBbox = mapSeries.reduce((combined, series) => { if (!series.visible) return combined; const bbox = series.topologyBounds; if (bbox == null) return combined; if (combined == null) return bbox; combined.merge(bbox); return combined; }, void 0); let scale2; if (combinedBbox != null) { const { lon0, lat0, lon1, lat1 } = combinedBbox; const domain = [ [lon0, lat0], [lon1, lat1] ]; const bounds = MercatorScale2.bounds(domain); const { width: width2, height: height2 } = seriesRect; const viewBoxScale = Math.min(width2 / bounds.width, height2 / bounds.height); const viewBoxWidth = bounds.width * viewBoxScale; const viewBoxHeight = bounds.height * viewBoxScale; const viewBoxOriginX = (width2 - viewBoxWidth) / 2; const viewBoxOriginY = (height2 - viewBoxHeight) / 2; const x0 = viewBoxOriginX; const y0 = viewBoxOriginY; const x1 = viewBoxOriginX + viewBoxWidth; const y1 = viewBoxOriginY + viewBoxHeight; const xZoom = this.ctx.zoomManager.getAxisZoom(this.xAxis.id); const yZoom = this.ctx.zoomManager.getAxisZoom(this.yAxis.id); const xSpan = (x1 - x0) / (xZoom.max - xZoom.min); const xStart = x0 - xSpan * xZoom.min; const ySpan = (y1 - y0) / (1 - yZoom.min - (1 - yZoom.max)); const yStart = y0 - ySpan * (1 - yZoom.max); scale2 = new MercatorScale2(domain, [ [xStart, yStart], [xStart + xSpan, yStart + ySpan] ]); } mapSeries.forEach((series) => { series.scale = scale2; }); const seriesVisible = this.series.some((s) => s.visible); seriesRoot.visible = seriesVisible; for (const group of [seriesRoot, annotationRoot]) { group.translationX = Math.floor(seriesRect.x); group.translationY = Math.floor(seriesRect.y); group.setClipRect(seriesRect.clone()); } this.ctx.layoutManager.emitLayoutComplete(ctx, { series: { visible: seriesVisible, rect: seriesRect, paddedRect: seriesRect } }); } }; TopologyChart.className = "TopologyChart"; TopologyChart.type = "topology"; var { isAgTopologyChartOptions: isAgTopologyChartOptions2 } = import_ag_charts_community22._ModuleSupport; var TopologyChartModule = { type: "chart", name: "topology", detect: isAgTopologyChartOptions2, create(options, resources) { return new TopologyChart(options, resources); } }; var import_ag_charts_community23 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN3, POSITIVE_NUMBER: POSITIVE_NUMBER3, ObserveChanges: ObserveChanges2, Validate: Validate10 } = import_ag_charts_community23._ModuleSupport; var Animation2 = class extends import_ag_charts_community23._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = true; ctx.animationManager.skip(false); } }; __decorateClass2([ ObserveChanges2((target, newValue) => { target.ctx.animationManager.skip(!newValue); }), Validate10(BOOLEAN3) ], Animation2.prototype, "enabled", 2); __decorateClass2([ ObserveChanges2((target, newValue) => { target.ctx.animationManager.defaultDuration = newValue; }), Validate10(POSITIVE_NUMBER3, { optional: true }) ], Animation2.prototype, "duration", 2); var AnimationModule = { type: "root", optionsKey: "animation", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Animation2(ctx), themeTemplate: { animation: { enabled: true } } }; var import_ag_charts_community98 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community24 = (init_main4(), __toCommonJS(main_exports)); var textInputTemplate_default = '
'; var { focusCursorAtEnd: focusCursorAtEnd2 } = import_ag_charts_community24._ModuleSupport; var moduleId = "text-input"; var canvasOverlay2 = "canvas-overlay"; var TextInput = class extends import_ag_charts_community24._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.layout = { getTextInputCoords: () => ({ x: 0, y: 0 }), getTextPosition: () => "center", alignment: "center", textAlign: "center" }; this.visible = false; this.element = ctx.domManager.addChild(canvasOverlay2, moduleId); this.element.classList.add("ag-charts-text-input"); this.destroyFns.push(() => ctx.domManager.removeChild(canvasOverlay2, moduleId)); } setKeyDownHandler(handler) { this.element.addEventListener("keydown", handler); this.destroyFns.push(() => this.element.removeEventListener("keydown", handler)); } show(opts) { this.element.innerHTML = textInputTemplate_default; const textArea = this.element.firstElementChild; import_ag_charts_community24._ModuleSupport.setAttribute(textArea, "data-preventdefault", false); if (!textArea.isContentEditable) { textArea.contentEditable = "true"; } textArea.setAttribute( "placeholder", this.ctx.localeManager.t(opts.placeholderText ?? "inputTextareaPlaceholder") ); if (opts.styles?.placeholderColor) { textArea.style.setProperty("--placeholder-text-color", opts.styles?.placeholderColor); } textArea.innerText = opts.text ?? ""; textArea.style.color = opts.styles?.color ?? "inherit"; textArea.style.fontFamily = opts.styles?.fontFamily ?? "inherit"; textArea.style.fontSize = opts.styles?.fontSize ? `${opts.styles.fontSize}px` : "inherit"; textArea.style.fontStyle = opts.styles?.fontStyle ?? "inherit"; textArea.style.fontWeight = typeof opts.styles?.fontWeight === "number" ? `${opts.styles.fontWeight}` : opts.styles?.fontWeight ?? "inherit"; focusCursorAtEnd2(textArea); textArea.addEventListener("input", () => { this.updatePosition(); opts.onChange?.(this.getValue(), this.getBBox()); }); textArea.addEventListener("click", (event) => { event.stopPropagation(); }); if (opts.layout) { this.layout = opts.layout; this.updatePosition(); } opts.onChange?.(this.getValue(), this.getBBox()); this.visible = true; } hide() { this.element.innerHTML = ""; this.layout = { getTextInputCoords: () => ({ x: 0, y: 0 }), getTextPosition: () => "center", alignment: "center", textAlign: "center" }; this.visible = false; } isVisible() { return this.visible; } updateColor(color) { if (!this.element.firstElementChild) return; this.element.firstElementChild.style.color = color; } updateFontSize(fontSize) { if (!this.element.firstElementChild) return; this.element.firstElementChild.style.fontSize = `${fontSize}px`; this.updatePosition(); return this.getBBox(); } getValue() { if (!this.element.firstElementChild) return; return this.element.firstElementChild.innerText.trim(); } updatePosition() { const { element: element2 } = this; const textArea = element2.firstElementChild; if (!textArea) return; const sceneRect = this.ctx.domManager.getBoundingClientRect(); const { width: width2, getTextInputCoords, getTextPosition, alignment, textAlign } = this.layout; element2.style.setProperty("width", width2 ? `${width2}px` : "unset"); const textRect = textArea.getBoundingClientRect(); const point = getTextInputCoords(textRect.height); let horizontalPosition = point.x; if (alignment === "center") { horizontalPosition -= (width2 ?? textRect.width) / 2; } else if (alignment === "right") { horizontalPosition -= width2 ?? textRect.width; } const position = getTextPosition(); let verticalPosition = point.y; if (position === "center") { verticalPosition -= textRect.height / 2; } else if (position === "bottom") { verticalPosition -= textRect.height; } element2.style.setProperty("top", `${verticalPosition}px`); element2.style.setProperty("left", `${horizontalPosition}px`); element2.style.setProperty("max-width", `${sceneRect.width - horizontalPosition}px`); element2.style.setProperty("text-align", alignment); textArea.style.setProperty("text-align", textAlign); } getBBox() { const { left, top, width: width2, height: height2 } = this.element.getBoundingClientRect(); return new import_ag_charts_community24._ModuleSupport.BBox(left, top, width2, height2); } }; var import_ag_charts_community25 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN4, BaseProperties: BaseProperties22, Validate: Validate11, UNION: UNION3 } = import_ag_charts_community25._ModuleSupport; var AXIS_TYPE = UNION3(["x", "y", "xy"], "an axis type"); var AxesButtons = class extends BaseProperties22 { constructor() { super(...arguments); this.enabled = false; this.axes = "y"; } }; __decorateClass2([ Validate11(BOOLEAN4) ], AxesButtons.prototype, "enabled", 2); __decorateClass2([ Validate11(AXIS_TYPE, { optional: true }) ], AxesButtons.prototype, "axes", 2); var import_ag_charts_community47 = (init_main4(), __toCommonJS(main_exports)); var AnnotationType = /* @__PURE__ */ ((AnnotationType3) => { AnnotationType3["Line"] = "line"; AnnotationType3["HorizontalLine"] = "horizontal-line"; AnnotationType3["VerticalLine"] = "vertical-line"; AnnotationType3["DisjointChannel"] = "disjoint-channel"; AnnotationType3["ParallelChannel"] = "parallel-channel"; AnnotationType3["FibonacciRetracement"] = "fibonacci-retracement"; AnnotationType3["FibonacciRetracementTrendBased"] = "fibonacci-retracement-trend-based"; AnnotationType3["Callout"] = "callout"; AnnotationType3["Comment"] = "comment"; AnnotationType3["Note"] = "note"; AnnotationType3["Text"] = "text"; AnnotationType3["Arrow"] = "arrow"; AnnotationType3["ArrowUp"] = "arrow-up"; AnnotationType3["ArrowDown"] = "arrow-down"; AnnotationType3["DateRange"] = "date-range"; AnnotationType3["PriceRange"] = "price-range"; AnnotationType3["DatePriceRange"] = "date-price-range"; AnnotationType3["QuickDatePriceRange"] = "quick-date-price-range"; return AnnotationType3; })(AnnotationType || {}); var ANNOTATION_TYPES = Object.values(AnnotationType); function stringToAnnotationType(value) { for (const t of ANNOTATION_TYPES) { if (t === value) return t; } } var import_ag_charts_community30 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community26 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN5, COLOR_STRING: COLOR_STRING22, DATE: DATE2, FONT_STYLE: FONT_STYLE22, FONT_WEIGHT: FONT_WEIGHT22, FUNCTION: FUNCTION2, LINE_DASH: LINE_DASH22, LINE_STYLE: LINE_STYLE2, NUMBER: NUMBER5, OBJECT: OBJECT4, OR: OR22, POSITIVE_NUMBER: POSITIVE_NUMBER4, RATIO: RATIO4, STRING: STRING22, TEXT_ALIGN: TEXT_ALIGN2, UNION: UNION4, BaseProperties: BaseProperties3, Validate: Validate12, predicateWithMessage: predicateWithMessage2, generateUUID: generateUUID2 } = import_ag_charts_community26._ModuleSupport; var GROUPING_VALUE_KEYS = ["value", "groupPercentage"]; var GROUPING_VALUE = predicateWithMessage2( (value) => isObject2(value) && Object.keys(value).every((key) => GROUPING_VALUE_KEYS.includes(key)), "objects with grouping value properties such as 'value' or 'groupPercentage'" ); var PointProperties = class extends BaseProperties3 { }; __decorateClass2([ Validate12(OR22(STRING22, NUMBER5, DATE2, GROUPING_VALUE)) ], PointProperties.prototype, "x", 2); __decorateClass2([ Validate12(OR22(STRING22, NUMBER5, DATE2, GROUPING_VALUE)) ], PointProperties.prototype, "y", 2); var ChannelAnnotationMiddleProperties = class extends Stroke(LineStyle(Visible(BaseProperties3))) { }; var AxisLabelProperties = class extends Stroke(LineStyle(Fill(Label2(Font(BaseProperties3))))) { constructor() { super(...arguments); this.cornerRadius = 2; } }; __decorateClass2([ Validate12(BOOLEAN5) ], AxisLabelProperties.prototype, "enabled", 2); __decorateClass2([ Validate12(POSITIVE_NUMBER4) ], AxisLabelProperties.prototype, "cornerRadius", 2); var BackgroundProperties = class extends Fill(BaseProperties3) { }; var HandleProperties = class extends Stroke(LineStyle(Fill(BaseProperties3))) { }; var LineTextProperties = class extends Font(BaseProperties3) { constructor() { super(...arguments); this.label = ""; this.position = "top"; this.alignment = "left"; } }; __decorateClass2([ Validate12(STRING22) ], LineTextProperties.prototype, "label", 2); __decorateClass2([ Validate12(UNION4(["top", "center", "bottom"]), { optional: true }) ], LineTextProperties.prototype, "position", 2); __decorateClass2([ Validate12(UNION4(["left", "center", "right"]), { optional: true }) ], LineTextProperties.prototype, "alignment", 2); var LabelTextProperties = class extends Font(BaseProperties3) { }; var ChannelTextProperties = class extends Font(BaseProperties3) { constructor() { super(...arguments); this.label = ""; } }; __decorateClass2([ Validate12(STRING22) ], ChannelTextProperties.prototype, "label", 2); __decorateClass2([ Validate12(UNION4(["top", "inside", "bottom"]), { optional: true }) ], ChannelTextProperties.prototype, "position", 2); __decorateClass2([ Validate12(UNION4(["left", "center", "right"]), { optional: true }) ], ChannelTextProperties.prototype, "alignment", 2); function Annotation(Parent) { class AnnotationInternal extends Lockable(Visible(Parent)) { constructor() { super(...arguments); this.id = generateUUID2(); } isValidWithContext(_context, warningPrefix) { return super.isValid(warningPrefix); } } return AnnotationInternal; } function Line22(Parent) { class LineInternal extends Parent { constructor() { super(...arguments); this.start = new PointProperties(); this.end = new PointProperties(); } } __decorateClass2([ Validate12(OBJECT4) ], LineInternal.prototype, "start", 2); __decorateClass2([ Validate12(OBJECT4) ], LineInternal.prototype, "end", 2); return LineInternal; } function Point(Parent) { class PointInternal extends Parent { } __decorateClass2([ Validate12(OR22(STRING22, NUMBER5, DATE2, GROUPING_VALUE)) ], PointInternal.prototype, "x", 2); __decorateClass2([ Validate12(OR22(STRING22, NUMBER5, DATE2, GROUPING_VALUE)) ], PointInternal.prototype, "y", 2); return PointInternal; } function Value(Parent) { class ValueInternal extends Parent { } __decorateClass2([ Validate12(OR22(STRING22, NUMBER5, DATE2, GROUPING_VALUE)) ], ValueInternal.prototype, "value", 2); return ValueInternal; } function Background2(Parent) { class BackgroundInternal extends Parent { constructor() { super(...arguments); this.background = new BackgroundProperties(); } } __decorateClass2([ Validate12(OBJECT4, { optional: true }) ], BackgroundInternal.prototype, "background", 2); return BackgroundInternal; } function Handle(Parent) { class HandleInternal extends Parent { constructor() { super(...arguments); this.handle = new HandleProperties(); } } __decorateClass2([ Validate12(OBJECT4, { optional: true }) ], HandleInternal.prototype, "handle", 2); return HandleInternal; } function AxisLabel2(Parent) { class AxisLabelInternal extends Parent { constructor() { super(...arguments); this.axisLabel = new AxisLabelProperties(); } } __decorateClass2([ Validate12(OBJECT4, { optional: true }) ], AxisLabelInternal.prototype, "axisLabel", 2); return AxisLabelInternal; } function Label2(Parent) { class LabelInternal extends Parent { constructor() { super(...arguments); this.padding = void 0; this.textAlign = "center"; this.formatter = void 0; } // TODO: making this generic causes issues with mixins sequence } __decorateClass2([ Validate12(POSITIVE_NUMBER4, { optional: true }) ], LabelInternal.prototype, "padding", 2); __decorateClass2([ Validate12(TEXT_ALIGN2, { optional: true }) ], LabelInternal.prototype, "textAlign", 2); __decorateClass2([ Validate12(FUNCTION2, { optional: true }) ], LabelInternal.prototype, "formatter", 2); return LabelInternal; } function Cappable(Parent) { class CappableInternal extends Parent { } return CappableInternal; } function Extendable(Parent) { class ExtendableInternal extends Parent { } __decorateClass2([ Validate12(BOOLEAN5, { optional: true }) ], ExtendableInternal.prototype, "extendStart", 2); __decorateClass2([ Validate12(BOOLEAN5, { optional: true }) ], ExtendableInternal.prototype, "extendEnd", 2); return ExtendableInternal; } function Lockable(Parent) { class LockableInternal extends Parent { } __decorateClass2([ Validate12(BOOLEAN5, { optional: true }) ], LockableInternal.prototype, "locked", 2); return LockableInternal; } function Localisable(Parent) { class LocalisableInternal extends Parent { setLocaleManager(localeManager) { this.localeManager ?? (this.localeManager = localeManager); } } return LocalisableInternal; } function Visible(Parent) { class VisibleInternal extends Parent { } __decorateClass2([ Validate12(BOOLEAN5, { optional: true }) ], VisibleInternal.prototype, "visible", 2); return VisibleInternal; } function Fill(Parent) { class FillInternal extends Parent { } __decorateClass2([ Validate12(COLOR_STRING22, { optional: true }) ], FillInternal.prototype, "fill", 2); __decorateClass2([ Validate12(RATIO4, { optional: true }) ], FillInternal.prototype, "fillOpacity", 2); return FillInternal; } function Stroke(Parent) { class StrokeInternal extends Parent { } __decorateClass2([ Validate12(COLOR_STRING22, { optional: true }) ], StrokeInternal.prototype, "stroke", 2); __decorateClass2([ Validate12(RATIO4, { optional: true }) ], StrokeInternal.prototype, "strokeOpacity", 2); __decorateClass2([ Validate12(NUMBER5, { optional: true }) ], StrokeInternal.prototype, "strokeWidth", 2); return StrokeInternal; } function LineStyle(Parent) { class LineDashInternal extends Parent { constructor() { super(...arguments); this.lineCap = void 0; this.computedLineDash = void 0; } } __decorateClass2([ Validate12(LINE_DASH22, { optional: true }) ], LineDashInternal.prototype, "lineDash", 2); __decorateClass2([ Validate12(NUMBER5, { optional: true }) ], LineDashInternal.prototype, "lineDashOffset", 2); __decorateClass2([ Validate12(LINE_STYLE2, { optional: true }) ], LineDashInternal.prototype, "lineStyle", 2); return LineDashInternal; } function Font(Parent) { class FontInternal extends Parent { constructor() { super(...arguments); this.fontSize = 12; this.fontFamily = "Verdana, sans-serif"; } } __decorateClass2([ Validate12(FONT_STYLE22, { optional: true }) ], FontInternal.prototype, "fontStyle", 2); __decorateClass2([ Validate12(FONT_WEIGHT22, { optional: true }) ], FontInternal.prototype, "fontWeight", 2); __decorateClass2([ Validate12(POSITIVE_NUMBER4) ], FontInternal.prototype, "fontSize", 2); __decorateClass2([ Validate12(STRING22) ], FontInternal.prototype, "fontFamily", 2); __decorateClass2([ Validate12(COLOR_STRING22, { optional: true }) ], FontInternal.prototype, "color", 2); return FontInternal; } var import_ag_charts_community29 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community27 = (init_main4(), __toCommonJS(main_exports)); function getGroupingValue(d) { if (isNumber2(d) || isString2(d) || isDate2(d)) { return { value: d, groupPercentage: 0 }; } return d ?? { value: void 0, groupPercentage: 0 }; } var { clampArray: clampArray2 } = import_ag_charts_community27._ModuleSupport; function convertLine(datum, context) { if (datum.start == null || datum.end == null) return; const start2 = convertPoint(datum.start, context); const end2 = convertPoint(datum.end, context); if (start2 == null || end2 == null) return; return { x1: start2.x, y1: start2.y, x2: end2.x, y2: end2.y }; } function convertPoint(point, context) { const x = convert(point.x, context.xAxis); const y = convert(point.y, context.yAxis); return { x, y }; } function convert(p, context) { if (p == null) return 0; const { value, groupPercentage } = getGroupingValue(p); const { scale: scale2, snapToGroup } = context; const width2 = scale2.bandwidth === 0 ? scale2.step ?? 0 : scale2.bandwidth ?? 0; const offset4 = snapToGroup ? width2 / 2 : width2 * groupPercentage; return scale2.convert(value) + offset4; } function invertCoords(coords, context) { const x = invert(coords.x, context.xAxis); const y = invert(coords.y, context.yAxis); return { x, y }; } function invert(n, context) { const { scale: scale2 } = context; if (context.continuous && scale2.step == null) { return context.scaleInvert(n); } const value = context.scaleInvertNearest(n); const width2 = scale2.bandwidth === 0 ? scale2.step : scale2.bandwidth ?? 0; const bandStart = scale2.convert(value); const bandEnd = bandStart + width2; const position = clampArray2(n, scale2.range); const groupPercentage = bandStart === bandEnd ? 0 : (position - bandStart) / (bandEnd - bandStart); return { value, groupPercentage }; } var import_ag_charts_community28 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties4 } = import_ag_charts_community28._ModuleSupport; var StartEndProperties = class extends Annotation(Line22(Handle(BaseProperties4))) { constructor() { super(...arguments); this.snapToAngle = 45; } isValidWithContext(_context, warningPrefix) { return super.isValid(warningPrefix); } getDefaultColor(_colorPickerType) { return void 0; } getDefaultOpacity(_colorPickerType) { return void 0; } }; var { STRING: STRING3, Validate: Validate13 } = import_ag_charts_community29._ModuleSupport; var TextualStartEndProperties = class extends Localisable(Label2(Font(StartEndProperties))) { constructor() { super(...arguments); this.text = ""; this.position = "top"; this.alignment = "left"; this.placement = "inside"; this.placeholderText = "inputTextareaPlaceholder"; } isValidWithContext(_context, warningPrefix) { return super.isValid(warningPrefix); } getDefaultColor(_colorPickerType) { return this.color; } getDefaultOpacity(_colorPickerType) { return void 0; } getPlaceholderColor() { return void 0; } getPadding() { const { padding = 0 } = this; return { top: padding, right: padding, bottom: padding, left: padding }; } getText() { const isPlaceholder = this.text.length == 0; let text22 = this.text; if (isPlaceholder) { text22 = this.placeholderText ?? ""; if (this.localeManager) text22 = this.localeManager.t(text22); } return { text: text22, isPlaceholder }; } getTextInputCoords(context, _height) { return convertPoint(this.end, context); } getTextPosition() { return this.position; } }; __decorateClass2([ Validate13(STRING3) ], TextualStartEndProperties.prototype, "text", 2); var { STRING: STRING4, Validate: Validate14, Color: Color2 } = import_ag_charts_community30._ModuleSupport; var DEFAULT_CALLOUT_PADDING = { top: 6, right: 12, bottom: 9, left: 12 }; var CalloutProperties = class extends Fill(Stroke(TextualStartEndProperties)) { constructor() { super(...arguments); this.type = "callout"; this.position = "bottom"; this.alignment = "left"; } static is(value) { return isObject2(value) && value.type === "callout"; } getDefaultColor(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.fill; case `line-color`: return this.stroke; case `text-color`: default: return this.color; } } getDefaultOpacity(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.fillOpacity; case `line-color`: return this.strokeOpacity; case `text-color`: default: return void 0; } } getPlaceholderColor() { const { r, g, b } = Color2.fromString(this.color ?? "#888888"); return new Color2(r, g, b, 0.66).toString(); } getPadding() { const { padding } = this; if (padding == null) { return { ...DEFAULT_CALLOUT_PADDING }; } return { top: padding, right: padding, bottom: padding, left: padding }; } getTextInputCoords(context, height2) { const coords = super.getTextInputCoords(context, height2); const padding = this.getPadding(); const paddingLeft = padding.left ?? 0; const paddingBottom = padding.bottom ?? 0; return { x: coords.x + paddingLeft, y: coords.y - paddingBottom }; } }; __decorateClass2([ Validate14(STRING4) ], CalloutProperties.prototype, "type", 2); var import_ag_charts_community32 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community31 = (init_main4(), __toCommonJS(main_exports)); var { STRING: STRING5, BaseProperties: BaseProperties5, Validate: Validate15 } = import_ag_charts_community31._ModuleSupport; var TextualPointProperties = class extends Annotation(Point(Handle(Label2(Font(BaseProperties5))))) { constructor() { super(...arguments); this.text = ""; this.position = "top"; this.alignment = "left"; this.placement = "inside"; this.placeholderText = "inputTextareaPlaceholder"; } isValidWithContext(_context, warningPrefix) { return super.isValid(warningPrefix); } getDefaultColor(_colorPickerType) { return this.color; } getDefaultOpacity(_colorPickerType) { return void 0; } getPlaceholderColor() { return void 0; } getPadding() { const { padding = 0 } = this; return { top: padding, right: padding, bottom: padding, left: padding }; } getText() { const isPlaceholder = this.text.length == 0; const text22 = !isPlaceholder ? this.text : this.placeholderText ?? ""; return { text: text22, isPlaceholder }; } getTextInputCoords(context, _height) { return convertPoint(this, context); } getTextPosition() { return this.position; } }; __decorateClass2([ Validate15(STRING5) ], TextualPointProperties.prototype, "text", 2); var { STRING: STRING6, Validate: Validate16, Color: Color22 } = import_ag_charts_community32._ModuleSupport; var DEFAULT_COMMENT_PADDING = { top: 8, right: 14, bottom: 8, left: 14 }; var CommentProperties = class extends Fill(Stroke(TextualPointProperties)) { constructor() { super(...arguments); this.type = "comment"; this.position = "bottom"; this.alignment = "left"; } static is(value) { return isObject2(value) && value.type === "comment"; } getDefaultColor(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.fill; case `line-color`: return this.stroke; case `text-color`: default: return this.color; } } getDefaultOpacity(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.fillOpacity; case `line-color`: return this.strokeOpacity; case `text-color`: default: return void 0; } } getPlaceholderColor() { const { r, g, b } = Color22.fromString(this.color ?? "#888888"); return new Color22(r, g, b, 0.66).toString(); } getPadding() { const { padding, fontSize } = this; if (padding == null) { return { top: Math.max(fontSize * 0.4, DEFAULT_COMMENT_PADDING.top), bottom: Math.max(fontSize * 0.4, DEFAULT_COMMENT_PADDING.bottom), left: Math.max(fontSize * 0.8, DEFAULT_COMMENT_PADDING.left), right: Math.max(fontSize * 0.8, DEFAULT_COMMENT_PADDING.right) }; } return { top: padding, right: padding, bottom: padding, left: padding }; } getTextInputCoords(context, height2) { const coords = super.getTextInputCoords(context, height2); const padding = this.getPadding(); return { x: coords.x + padding.left, y: coords.y - padding.bottom }; } }; __decorateClass2([ Validate16(STRING6) ], CommentProperties.prototype, "type", 2); var import_ag_charts_community34 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community33 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec22 } = import_ag_charts_community33._ModuleSupport; function getLineStyle(lineDash, lineStyle) { return lineDash ? "dashed" : lineStyle ?? "solid"; } function getComputedLineDash(strokeWidth, styleType) { switch (styleType) { case "solid": return []; case "dashed": return [strokeWidth * 4, strokeWidth * 2]; case "dotted": return [0, strokeWidth * 2]; } } function getLineDash(lineDash, computedLineDash, lineStyle, strokeWidth) { const styleType = getLineStyle(lineDash, lineStyle); return computedLineDash ?? lineDash ?? getComputedLineDash(strokeWidth ?? 1, styleType); } function getLineCap(lineCap, lineDash, lineStyle) { const styleType = getLineStyle(lineDash, lineStyle); return lineCap ?? styleType === "dotted" ? "round" : void 0; } function boundsIntersections(coords, bounds) { const [p1, p2] = Vec22.from(coords); const reflection = bounds.height; const gradient2 = Vec22.gradient(p2, p1, reflection); const intercept2 = Vec22.intercept(p2, gradient2, reflection); const fallback = [ { x: p1.x, y: reflection ?? 0 }, { x: p1.x, y: reflection == null ? bounds.height : reflection - bounds.height } ]; if (gradient2 === Infinity) { return fallback; } let points = [ Vec22.intersectAtY(gradient2, intercept2, 0, reflection), Vec22.intersectAtY(gradient2, intercept2, bounds.height, reflection), Vec22.intersectAtX(gradient2, intercept2, 0, reflection), Vec22.intersectAtX(gradient2, intercept2, bounds.width, reflection) ]; points = points.filter((p) => p.x >= bounds.x && p.x <= bounds.width && p.y >= bounds.y && p.y <= bounds.height).sort((a, b) => { if (a.x === b.x) return 0; return a.x < b.x ? -1 : 1; }); if (points.length !== 2) { return fallback; } return points; } var { BOOLEAN: BOOLEAN6, OBJECT: OBJECT5, STRING: STRING7, BaseProperties: BaseProperties6, Validate: Validate17 } = import_ag_charts_community34._ModuleSupport; var MeasurerStatisticsDivider = class extends Stroke(BaseProperties6) { }; var MeasurerStatistics = class extends Font(Fill(Stroke(BaseProperties6))) { constructor() { super(...arguments); this.divider = new MeasurerStatisticsDivider(); } }; __decorateClass2([ Validate17(OBJECT5, { optional: true }) ], MeasurerStatistics.prototype, "divider", 2); var MeasurerDirectionProperties = class extends Fill(Stroke(Handle(BaseProperties6))) { constructor() { super(...arguments); this.statistics = new MeasurerStatistics(); } }; __decorateClass2([ Validate17(OBJECT5, { optional: true }) ], MeasurerDirectionProperties.prototype, "statistics", 2); var MeasurerTypeProperties = class extends Localisable(Background2(Stroke(LineStyle(StartEndProperties)))) { constructor() { super(...arguments); this.direction = "both"; this.hasDateRange = false; this.hasPriceRange = false; this.statistics = new MeasurerStatistics(); this.getVolume = () => void 0; this.text = new LineTextProperties(); } getDefaultColor(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.background.fill; case `line-color`: return this.stroke; case `text-color`: return this.text.color; } } getDefaultOpacity(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.background.fillOpacity; case `line-color`: return this.strokeOpacity; } } getLineDash() { return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth); } getLineCap() { return getLineCap(this.lineCap, this.lineDash, this.lineStyle); } }; __decorateClass2([ Validate17(OBJECT5, { optional: true }) ], MeasurerTypeProperties.prototype, "statistics", 2); __decorateClass2([ Validate17(OBJECT5, { optional: true }) ], MeasurerTypeProperties.prototype, "text", 2); function DateRange(Parent) { class DateRangeInternal extends Parent { constructor() { super(...arguments); this.hasDateRange = true; } } return DateRangeInternal; } function PriceRange(Parent) { class PriceRangeInternal extends Parent { constructor() { super(...arguments); this.hasPriceRange = true; } } return PriceRangeInternal; } var DateRangeProperties = class extends DateRange(MeasurerTypeProperties) { constructor() { super(...arguments); this.type = "date-range"; this.direction = "horizontal"; } static is(value) { return isObject2(value) && value.type === "date-range"; } }; __decorateClass2([ Validate17(STRING7) ], DateRangeProperties.prototype, "type", 2); __decorateClass2([ Validate17(BOOLEAN6, { optional: true }) ], DateRangeProperties.prototype, "extendAbove", 2); __decorateClass2([ Validate17(BOOLEAN6, { optional: true }) ], DateRangeProperties.prototype, "extendBelow", 2); var PriceRangeProperties = class extends PriceRange(MeasurerTypeProperties) { constructor() { super(...arguments); this.type = "price-range"; this.direction = "vertical"; } static is(value) { return isObject2(value) && value.type === "price-range"; } }; __decorateClass2([ Validate17(STRING7) ], PriceRangeProperties.prototype, "type", 2); __decorateClass2([ Validate17(BOOLEAN6, { optional: true }) ], PriceRangeProperties.prototype, "extendLeft", 2); __decorateClass2([ Validate17(BOOLEAN6, { optional: true }) ], PriceRangeProperties.prototype, "extendRight", 2); var DatePriceRangeProperties = class extends DateRange(PriceRange(MeasurerTypeProperties)) { constructor() { super(...arguments); this.type = "date-price-range"; this.direction = "both"; } static is(value) { return isObject2(value) && value.type === "date-price-range"; } }; __decorateClass2([ Validate17(STRING7) ], DatePriceRangeProperties.prototype, "type", 2); var QuickDatePriceRangeProperties = class extends DateRange(PriceRange(MeasurerTypeProperties)) { constructor() { super(...arguments); this.type = "quick-date-price-range"; this.up = new MeasurerDirectionProperties(); this.down = new MeasurerDirectionProperties(); this.direction = "both"; } static is(value) { return isObject2(value) && value.type === "quick-date-price-range"; } }; __decorateClass2([ Validate17(STRING7) ], QuickDatePriceRangeProperties.prototype, "type", 2); __decorateClass2([ Validate17(OBJECT5, { optional: true }) ], QuickDatePriceRangeProperties.prototype, "up", 2); __decorateClass2([ Validate17(OBJECT5, { optional: true }) ], QuickDatePriceRangeProperties.prototype, "down", 2); var import_ag_charts_community36 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community35 = (init_main4(), __toCommonJS(main_exports)); var { TextWrapper: TextWrapper22, CachedTextMeasurerPool: CachedTextMeasurerPool2, BBox: BBox22 } = import_ag_charts_community35._ModuleSupport; var ANNOTATION_TEXT_LINE_HEIGHT = 1.38; function getTextWrapOptions(options) { return { font: { fontFamily: options.fontFamily, fontSize: options.fontSize, fontStyle: options.fontStyle, fontWeight: options.fontWeight }, textAlign: options.textAlign, textBaseline: options.position == "center" ? "middle" : options.position, lineHeight: ANNOTATION_TEXT_LINE_HEIGHT, avoidOrphans: false, textWrap: "always" }; } function wrapText(options, text22, width2) { return width2 ? TextWrapper22.wrapText(text22, { ...getTextWrapOptions(options), maxWidth: width2 }) : text22; } function measureAnnotationText(options, text22) { const textOptions = getTextWrapOptions(options); const { lineMetrics, width: width2 } = CachedTextMeasurerPool2.measureLines(text22, textOptions); const height2 = lineMetrics.length * (options.fontSize ?? 14) * ANNOTATION_TEXT_LINE_HEIGHT; return { width: width2, height: height2 }; } function getBBox(options, text22, coords, bbox) { let width2 = bbox?.width ?? 0; let height2 = bbox?.height ?? 0; if (!bbox) { const wrappedText = options.width != null ? wrapText(options, text22, options.width) : text22; ({ width: width2, height: height2 } = measureAnnotationText(options, wrappedText)); } return new BBox22(coords.x, coords.y, width2, height2); } function updateTextNode(node, text22, isPlaceholder, config, { x, y }) { const { visible = true, fontFamily, fontSize = 14, fontStyle, fontWeight, textAlign } = config; const lineHeight = fontSize * ANNOTATION_TEXT_LINE_HEIGHT; const textBaseline = config.position == "center" ? "middle" : config.position; const fill = isPlaceholder ? config.getPlaceholderColor() : config.color; node.setProperties({ x, y, visible, text: text22, fill, fontFamily, fontSize, fontStyle, fontWeight, textAlign, lineHeight, textBaseline }); } var { OBJECT: OBJECT6, STRING: STRING8, BaseProperties: BaseProperties7, Validate: Validate18, clamp: clamp22 } = import_ag_charts_community36._ModuleSupport; var DEFAULT_NOTE_PADDING = 10; var HANDLE_SIZE = 11; var ICON_HEIGHT = 20; var ICON_WIDTH = 22; var ICON_SPACING = 10; var LABEL_OFFSET = ICON_HEIGHT + ICON_SPACING; var TOOLBAR_OFFSET = 34; var NoteBackgroundProperties = class extends Fill(Stroke(BaseProperties7)) { }; var NoteProperties = class extends Fill(Stroke(TextualPointProperties)) { constructor() { super(...arguments); this.type = "note"; this.background = new NoteBackgroundProperties(); this.position = "bottom"; this.alignment = "center"; this.width = 200; } static is(value) { return isObject2(value) && value.type === "note"; } getDefaultColor(colorPickerType) { switch (colorPickerType) { case `line-color`: return this.fill; case `text-color`: return this.color; } } getDefaultOpacity(colorPickerType) { switch (colorPickerType) { case `line-color`: return this.fillOpacity; case `text-color`: return void 0; } } getPadding() { const padding = this.padding ?? DEFAULT_NOTE_PADDING; return { top: padding, right: padding, bottom: padding, left: padding }; } getTextInputCoords(context, height2) { const { width: width2, text: text22 } = this; const textInputCoords = super.getTextInputCoords(context, height2); const padding = this.getPadding().top; const bbox = getBBox(this, text22, textInputCoords); bbox.x = clamp22(width2 / 2, bbox.x, context.seriesRect.width - width2 / 2); const topY = bbox.y - LABEL_OFFSET - padding * 2; const bottomY = bbox.y + HANDLE_SIZE + padding * 2; const textHeight = Math.max(bbox.height, height2); if (topY - textHeight - TOOLBAR_OFFSET < 0) { bbox.y = bottomY; this.position = "top"; } else { bbox.y = topY + padding; this.position = "bottom"; } return { x: bbox.x, y: bbox.y }; } }; __decorateClass2([ Validate18(STRING8) ], NoteProperties.prototype, "type", 2); __decorateClass2([ Validate18(OBJECT6, { optional: true }) ], NoteProperties.prototype, "background", 2); var import_ag_charts_community37 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties8 } = import_ag_charts_community37._ModuleSupport; var PointProperties2 = class extends Annotation(Point(Handle(BaseProperties8))) { isValidWithContext(_context, warningPrefix) { return super.isValid(warningPrefix); } getDefaultColor(_colorPickerType) { return void 0; } getDefaultOpacity(_colorPickerType) { return void 0; } }; var ShapePointProperties = class _ShapePointProperties extends Fill(PointProperties2) { constructor() { super(...arguments); this.size = 32; } static is(value) { return value instanceof _ShapePointProperties; } getDefaultColor(colorPickerType) { return colorPickerType === `fill-color` ? this.fill : void 0; } getDefaultOpacity(colorPickerType) { return colorPickerType === `fill-color` ? this.fillOpacity : void 0; } }; var import_ag_charts_community39 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community38 = (init_main4(), __toCommonJS(main_exports)); function validateDatumLine(context, datum, directions2, warningPrefix) { let valid = true; valid && (valid = validateDatumPoint(context, datum.start, directions2, warningPrefix && `${warningPrefix}[start] `)); valid && (valid = validateDatumPoint(context, datum.end, directions2, warningPrefix && `${warningPrefix}[end] `)); return valid; } function validateDatumValue(context, datum, warningPrefix) { const axis = datum.direction === "horizontal" ? context.yAxis : context.xAxis; const valid = validateDatumPointDirection(datum.value, axis); if (!valid && warningPrefix) { const { value } = getGroupingValue(datum.value); logger_exports2.warnOnce(`${warningPrefix}is outside the axis domain, ignoring. - value: [${value}]]`); } return valid; } function validateDatumPoint(context, point, directions2, warningPrefix) { if (point.x == null || point.y == null) { if (warningPrefix) { logger_exports2.warnOnce(`${warningPrefix}requires both an [x] and [y] property, ignoring.`); } return false; } const validX = directions2?.x === false ? true : validateDatumPointDirection(point.x, context.xAxis); const validY = directions2?.y === false ? true : validateDatumPointDirection(point.y, context.yAxis); if (!validX || !validY) { let text22 = "x & y domains"; if (validX) text22 = "y domain"; if (validY) text22 = "x domain"; if (warningPrefix) { const { value: xValue } = getGroupingValue(point.x); const { value: yValue } = getGroupingValue(point.y); logger_exports2.warnOnce(`${warningPrefix}is outside the ${text22}, ignoring. - x: [${xValue}], y: ${yValue}]`); } return false; } return true; } function validateDatumPointDirection(d, context) { const { domain } = context.scale; const { value } = getGroupingValue(d); if (domain && value != null && context.continuous) { return value >= domain[0] && value <= domain.at(-1); } return true; } function isPoint(point) { return point?.x != null && point?.y != null; } var { OBJECT: OBJECT7, STRING: STRING9, BaseProperties: BaseProperties9, Validate: Validate19 } = import_ag_charts_community39._ModuleSupport; var HorizontalLineProperties = class extends Annotation(Value(Handle(AxisLabel2(Stroke(LineStyle(BaseProperties9)))))) { constructor() { super(...arguments); this.direction = "horizontal"; this.type = "horizontal-line"; this.text = new LineTextProperties(); } static is(value) { return isObject2(value) && value.type === "horizontal-line"; } isValidWithContext(context, warningPrefix) { return super.isValid(warningPrefix) && validateDatumValue(context, this, warningPrefix); } getDefaultColor() { return this.stroke; } getDefaultOpacity() { return this.strokeOpacity; } getLineDash() { return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth); } getLineCap() { return getLineCap(this.lineCap, this.lineDash, this.lineStyle); } }; __decorateClass2([ Validate19(STRING9) ], HorizontalLineProperties.prototype, "type", 2); __decorateClass2([ Validate19(OBJECT7, { optional: true }) ], HorizontalLineProperties.prototype, "text", 2); var VerticalLineProperties = class extends Annotation(Value(Handle(AxisLabel2(Stroke(LineStyle(BaseProperties9)))))) { constructor() { super(...arguments); this.direction = "vertical"; this.type = "vertical-line"; this.text = new LineTextProperties(); } static is(value) { return isObject2(value) && value.type === "vertical-line"; } isValidWithContext(context, warningPrefix) { return super.isValid(warningPrefix) && validateDatumValue(context, this, warningPrefix); } getDefaultColor() { return this.stroke; } getDefaultOpacity() { return this.strokeOpacity; } getLineDash() { return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth); } getLineCap() { return getLineCap(this.lineCap, this.lineDash, this.lineStyle); } }; __decorateClass2([ Validate19(STRING9) ], VerticalLineProperties.prototype, "type", 2); __decorateClass2([ Validate19(OBJECT7, { optional: true }) ], VerticalLineProperties.prototype, "text", 2); var import_ag_charts_community40 = (init_main4(), __toCommonJS(main_exports)); var { NUMBER: NUMBER6, OBJECT: OBJECT8, STRING: STRING10, BaseProperties: BaseProperties10, Validate: Validate20 } = import_ag_charts_community40._ModuleSupport; var DisjointChannelProperties = class extends Annotation( Background2(Line22(Handle(Extendable(Stroke(LineStyle(BaseProperties10)))))) ) { constructor() { super(...arguments); this.type = "disjoint-channel"; this.text = new ChannelTextProperties(); this.snapToAngle = 45; } static is(value) { return isObject2(value) && value.type === "disjoint-channel"; } get bottom() { const bottom = { start: { x: this.start.x, y: this.start.y }, end: { x: this.end.x, y: this.end.y } }; if (typeof bottom.start.y === "number" && typeof bottom.end.y === "number") { bottom.start.y -= this.startHeight; bottom.end.y -= this.endHeight; } else { logger_exports2.warnOnce(`Annotation [${this.type}] can only be used with a numeric y-axis.`); } return bottom; } isValidWithContext(context, warningPrefix) { return super.isValid(warningPrefix) && validateDatumLine(context, this, { y: false }, warningPrefix) && validateDatumLine(context, this.bottom, { y: false }, warningPrefix); } getDefaultColor(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.background.fill; case `line-color`: return this.stroke; case "text-color": return this.text.color; } } getDefaultOpacity(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.background.fillOpacity; case `line-color`: return this.strokeOpacity; } } getLineDash() { return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth); } getLineCap() { return getLineCap(this.lineCap, this.lineDash, this.lineStyle); } }; __decorateClass2([ Validate20(STRING10) ], DisjointChannelProperties.prototype, "type", 2); __decorateClass2([ Validate20(NUMBER6) ], DisjointChannelProperties.prototype, "startHeight", 2); __decorateClass2([ Validate20(NUMBER6) ], DisjointChannelProperties.prototype, "endHeight", 2); __decorateClass2([ Validate20(OBJECT8, { optional: true }) ], DisjointChannelProperties.prototype, "text", 2); var import_ag_charts_community43 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community42 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community41 = (init_main4(), __toCommonJS(main_exports)); var { OBJECT: OBJECT9, STRING: STRING11, Validate: Validate21 } = import_ag_charts_community41._ModuleSupport; var LineTypeProperties = class extends Localisable( Cappable(Extendable(Stroke(LineStyle(StartEndProperties)))) ) { constructor() { super(...arguments); this.text = new LineTextProperties(); } isValidWithContext(context, warningPrefix) { return super.isValid(warningPrefix) && validateDatumLine(context, this, void 0, warningPrefix); } getDefaultColor(colorPickerType) { switch (colorPickerType) { case "line-color": return this.stroke; case "text-color": return this.text.color; } } getDefaultOpacity() { return this.strokeOpacity; } getLineDash() { return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth); } getLineCap() { return getLineCap(this.lineCap, this.lineDash, this.lineStyle); } }; __decorateClass2([ Validate21(OBJECT9, { optional: true }) ], LineTypeProperties.prototype, "text", 2); var ArrowProperties = class extends LineTypeProperties { constructor() { super(...arguments); this.type = "arrow"; this.endCap = "arrow"; } static is(value) { return isObject2(value) && value.type === "arrow"; } }; __decorateClass2([ Validate21(STRING11) ], ArrowProperties.prototype, "type", 2); var LineProperties = class extends LineTypeProperties { constructor() { super(...arguments); this.type = "line"; } static is(value) { return isObject2(value) && value.type === "line"; } }; __decorateClass2([ Validate21(STRING11) ], LineProperties.prototype, "type", 2); var { OBJECT: OBJECT10, BOOLEAN: BOOLEAN7, COLOR_STRING: COLOR_STRING3, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY2, Validate: Validate222, predicateWithMessage: predicateWithMessage22 } = import_ag_charts_community42._ModuleSupport; var fibonacciBands = [10, 6, 4]; var FIBONACCI_BANDS = predicateWithMessage22( (value) => isFiniteNumber2(value) && fibonacciBands.includes(value), "Number of fibonacci ranges, 10, 6 or 4" ); var FibonacciProperties = class extends LineTypeProperties { constructor() { super(...arguments); this.label = new LabelTextProperties(); this.reverse = false; this.showFill = true; this.isMultiColor = true; this.strokes = []; this.bands = 10; } getDefaultColor(colorPickerType) { switch (colorPickerType) { case "line-color": return this.rangeStroke ?? this.stroke; case "text-color": return this.text.color; } } }; __decorateClass2([ Validate222(OBJECT10, { optional: true }) ], FibonacciProperties.prototype, "label", 2); __decorateClass2([ Validate222(BOOLEAN7, { optional: true }) ], FibonacciProperties.prototype, "reverse", 2); __decorateClass2([ Validate222(BOOLEAN7, { optional: true }) ], FibonacciProperties.prototype, "showFill", 2); __decorateClass2([ Validate222(BOOLEAN7, { optional: true }) ], FibonacciProperties.prototype, "isMultiColor", 2); __decorateClass2([ Validate222(COLOR_STRING_ARRAY2, { optional: true }) ], FibonacciProperties.prototype, "strokes", 2); __decorateClass2([ Validate222(COLOR_STRING3, { optional: true }) ], FibonacciProperties.prototype, "rangeStroke", 2); __decorateClass2([ Validate222(FIBONACCI_BANDS, { optional: true }) ], FibonacciProperties.prototype, "bands", 2); var { STRING: STRING12, OBJECT: OBJECT11, Validate: Validate23 } = import_ag_charts_community43._ModuleSupport; var FibonacciRetracementTrendBasedProperties = class extends FibonacciProperties { constructor() { super(...arguments); this.type = "fibonacci-retracement-trend-based"; this.endRetracement = new PointProperties(); } static is(value) { return isObject2(value) && value.type === "fibonacci-retracement-trend-based"; } }; __decorateClass2([ Validate23(STRING12) ], FibonacciRetracementTrendBasedProperties.prototype, "type", 2); __decorateClass2([ Validate23(OBJECT11) ], FibonacciRetracementTrendBasedProperties.prototype, "endRetracement", 2); var import_ag_charts_community44 = (init_main4(), __toCommonJS(main_exports)); var { STRING: STRING13, Validate: Validate24 } = import_ag_charts_community44._ModuleSupport; var FibonacciRetracementProperties = class extends FibonacciProperties { constructor() { super(...arguments); this.type = "fibonacci-retracement"; } static is(value) { return isObject2(value) && value.type === "fibonacci-retracement"; } }; __decorateClass2([ Validate24(STRING13) ], FibonacciRetracementProperties.prototype, "type", 2); var import_ag_charts_community45 = (init_main4(), __toCommonJS(main_exports)); var { NUMBER: NUMBER7, STRING: STRING14, OBJECT: OBJECT12, BaseProperties: BaseProperties11, Validate: Validate25 } = import_ag_charts_community45._ModuleSupport; var ParallelChannelProperties = class extends Annotation( Background2(Line22(Handle(Extendable(Stroke(LineStyle(BaseProperties11)))))) ) { constructor() { super(...arguments); this.type = "parallel-channel"; this.middle = new ChannelAnnotationMiddleProperties(); this.text = new ChannelTextProperties(); this.snapToAngle = 45; } static is(value) { return isObject2(value) && value.type === "parallel-channel"; } get bottom() { const bottom = { start: { x: this.start.x, y: this.start.y }, end: { x: this.end.x, y: this.end.y } }; if (typeof bottom.start.y === "number" && typeof bottom.end.y === "number") { bottom.start.y -= this.height; bottom.end.y -= this.height; } else { logger_exports2.warnOnce(`Annotation [${this.type}] can only be used with a numeric y-axis.`); } return bottom; } isValidWithContext(context, warningPrefix) { return super.isValid(warningPrefix) && validateDatumLine(context, this, { y: false }, warningPrefix) && validateDatumLine(context, this.bottom, { y: false }, warningPrefix); } getDefaultColor(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.background.fill; case `line-color`: return this.stroke; case "text-color": return this.text.color; } } getDefaultOpacity(colorPickerType) { switch (colorPickerType) { case `fill-color`: return this.background.fillOpacity; case `line-color`: return this.strokeOpacity; } } getLineDash() { return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth); } getLineCap() { return getLineCap(this.lineCap, this.lineDash, this.lineStyle); } }; __decorateClass2([ Validate25(STRING14) ], ParallelChannelProperties.prototype, "type", 2); __decorateClass2([ Validate25(NUMBER7) ], ParallelChannelProperties.prototype, "height", 2); __decorateClass2([ Validate25(OBJECT12, { optional: true }) ], ParallelChannelProperties.prototype, "middle", 2); __decorateClass2([ Validate25(OBJECT12, { optional: true }) ], ParallelChannelProperties.prototype, "text", 2); var import_ag_charts_community46 = (init_main4(), __toCommonJS(main_exports)); var { STRING: STRING15, Validate: Validate26 } = import_ag_charts_community46._ModuleSupport; var TextProperties = class extends TextualPointProperties { constructor() { super(...arguments); this.type = "text"; this.position = "bottom"; } static is(value) { return isObject2(value) && value.type === "text"; } }; __decorateClass2([ Validate26(STRING15) ], TextProperties.prototype, "type", 2); function isEphemeralType(datum) { return QuickDatePriceRangeProperties.is(datum); } function isLineType(datum) { return LineProperties.is(datum) || HorizontalLineProperties.is(datum) || VerticalLineProperties.is(datum) || ArrowProperties.is(datum) || isFibonacciType(datum); } function isChannelType(datum) { return DisjointChannelProperties.is(datum) || ParallelChannelProperties.is(datum); } function isFibonacciType(datum) { return FibonacciRetracementProperties.is(datum) || FibonacciRetracementTrendBasedProperties.is(datum); } function isTextType(datum) { return CalloutProperties.is(datum) || CommentProperties.is(datum) || NoteProperties.is(datum) || TextProperties.is(datum); } function isMeasurerType(datum) { return DateRangeProperties.is(datum) || PriceRangeProperties.is(datum) || DatePriceRangeProperties.is(datum) || QuickDatePriceRangeProperties.is(datum); } function hasFontSize(datum) { return isTextType(datum) && !NoteProperties.is(datum); } function hasLineStyle(datum) { return isLineType(datum) || isChannelType(datum) || isMeasurerType(datum) && !QuickDatePriceRangeProperties.is(datum); } function hasLineColor(datum) { return isLineType(datum) || isChannelType(datum) || isMeasurerType(datum) || CalloutProperties.is(datum) || NoteProperties.is(datum); } function hasIconColor(datum) { return NoteProperties.is(datum); } function hasFillColor(datum) { return isChannelType(datum) || isMeasurerType(datum) || CalloutProperties.is(datum) || CommentProperties.is(datum) || ShapePointProperties.is(datum); } function hasTextColor(datum) { return isTextType(datum) && !NoteProperties.is(datum); } function hasLineText(datum) { return (isLineType(datum) || isChannelType(datum) || isMeasurerType(datum)) && !isEphemeralType(datum) && isObject2(datum.text); } function setFontSize(datum, fontSize) { if ("fontSize" in datum) datum.fontSize = fontSize; if (hasLineText(datum)) datum.text.fontSize = fontSize; } function setLineStyle(datum, style) { const strokeWidth = style?.strokeWidth ?? datum.strokeWidth ?? 1; const lineType = style?.type ?? datum.lineStyle; const lineStyle = lineType ?? getLineStyle(datum.lineDash, lineType); const computedLineDash = getComputedLineDash(strokeWidth, lineStyle); datum.strokeWidth = strokeWidth; datum.computedLineDash = computedLineDash; datum.lineStyle = lineStyle; datum.lineCap = lineStyle === "dotted" ? "round" : void 0; } function setColor(datum, colorPickerType, colorOpacity, color, opacity, isMultiColor) { switch (colorPickerType) { case `fill-color`: { if ("fill" in datum) datum.fill = color; if ("fillOpacity" in datum) datum.fillOpacity = opacity; if ("background" in datum) { datum.background.fill = color; datum.background.fillOpacity = opacity; } break; } case `line-color`: { if ("axisLabel" in datum) { datum.axisLabel.fill = color; datum.axisLabel.fillOpacity = opacity; datum.axisLabel.stroke = color; datum.axisLabel.strokeOpacity = opacity; } if ("fill" in datum && "fillOpacity" in datum && hasIconColor(datum)) { datum.fill = color; datum.fillOpacity = opacity; } else { if ("strokeOpacity" in datum) datum.strokeOpacity = opacity; if ("isMultiColor" in datum && "rangeStroke" in datum) { datum.isMultiColor = isMultiColor; datum.rangeStroke = color; } else if ("stroke" in datum) { datum.stroke = color; } } break; } case `text-color`: { if ("color" in datum) datum.color = colorOpacity; if (hasLineText(datum)) datum.text.color = color; break; } } } var { deepClone: deepClone2 } = import_ag_charts_community47._ModuleSupport; var AnnotationDefaults = class { constructor() { this.mementoOriginatorKey = "annotation-defaults"; this.colors = new Map( Object.values(AnnotationType).map((type) => [ type, /* @__PURE__ */ new Map([ ["line-color", void 0], ["fill-color", void 0], ["text-color", void 0] ]) ]) ); this.fontSizes = /* @__PURE__ */ new Map([ ["callout", void 0], ["comment", void 0], ["text", void 0], ["arrow", void 0], ["line", void 0], ["disjoint-channel", void 0], ["parallel-channel", void 0], ["date-range", void 0], ["price-range", void 0], ["date-price-range", void 0] ]); this.lineStyles = /* @__PURE__ */ new Map([ ["line", void 0], ["horizontal-line", void 0], ["vertical-line", void 0], ["disjoint-channel", void 0], ["parallel-channel", void 0], ["arrow", void 0], ["date-range", void 0], ["price-range", void 0], ["date-price-range", void 0] ]); this.lineTextAlignments = /* @__PURE__ */ new Map([ ["line", void 0], ["horizontal-line", void 0], ["vertical-line", void 0], ["disjoint-channel", void 0], ["parallel-channel", void 0], ["arrow", void 0], ["date-range", void 0], ["price-range", void 0], ["date-price-range", void 0] ]); this.lineTextPositions = /* @__PURE__ */ new Map([ ["line", void 0], ["horizontal-line", void 0], ["vertical-line", void 0], ["disjoint-channel", void 0], ["parallel-channel", void 0], ["arrow", void 0], ["date-range", void 0], ["price-range", void 0], ["date-price-range", void 0] ]); this.fibonacciOptions = /* @__PURE__ */ new Map([ [ "fibonacci-retracement", { bands: void 0, reverse: void 0, showFill: void 0 } ], [ "fibonacci-retracement-trend-based", { bands: void 0, reverse: void 0, showFill: void 0 } ] ]); } createMemento() { return { colors: deepClone2(this.colors), fontSizes: deepClone2(this.fontSizes), lineStyles: deepClone2(this.lineStyles), lineTextAlignments: deepClone2(this.lineTextAlignments), lineTextPositions: deepClone2(this.lineTextPositions), fibonacciOptions: deepClone2(this.fibonacciOptions) }; } guardMemento(_blob) { return true; } restoreMemento(_version, _mementoVersion, blob) { this.colors = deepClone2(blob.colors); this.fontSizes = deepClone2(blob.fontSizes); this.lineStyles = deepClone2(blob.lineStyles); this.lineTextAlignments = deepClone2(blob.lineTextAlignments); this.lineTextPositions = deepClone2(blob.lineTextPositions); this.fibonacciOptions = deepClone2(blob.fibonacciOptions); } setDefaultColor(type, colorType, colorOpacity, color, opacity, isMultiColor) { this.colors.get(type)?.set(colorType, [colorOpacity, color, opacity, isMultiColor]); } setDefaultFontSize(type, fontSize) { this.fontSizes.set(type, fontSize); } setDefaultLineStyleType(type, lineStyleType) { const defaultStyle = this.lineStyles.get(type); if (defaultStyle) { defaultStyle.type = lineStyleType; } else { this.lineStyles.set(type, { type: lineStyleType }); } } setDefaultLineStyleWidth(type, strokeWidth) { const defaultStyle = this.lineStyles.get(type); if (defaultStyle) { defaultStyle.strokeWidth = strokeWidth; } else { this.lineStyles.set(type, { strokeWidth }); } } setDefaultLineTextAlignment(type, alignment) { this.lineTextAlignments.set(type, alignment); } setDefaultLineTextPosition(type, position) { this.lineTextPositions.set(type, position); } setDefaultFibonacciOptions(type, key, value) { if (type != "fibonacci-retracement" && type != "fibonacci-retracement-trend-based") return; const options = this.fibonacciOptions.get(type); options[key] = value; this.fibonacciOptions.set(type, options); } applyDefaults(datum) { for (const [annotationType, colors] of this.colors) { if (datum.type !== annotationType) continue; for (const [colorPickerType, [colorOpacity, color, opacity, isMultiColor] = []] of colors) { if (colorOpacity && color && opacity != null && isMultiColor != null) { setColor(datum, colorPickerType, colorOpacity, color, opacity, isMultiColor); } } } for (const [annotationType, size] of this.fontSizes) { if (datum.type !== annotationType || size == null) continue; setFontSize(datum, size); } for (const [annotationType, style] of this.lineStyles) { if (datum.type !== annotationType || style == null) continue; setLineStyle(datum, style); } for (const [annotationType, position] of this.lineTextPositions) { if (datum.type !== annotationType || position == null) continue; datum.text.position = position; } for (const [annotationType, alignment] of this.lineTextAlignments) { if (datum.type !== annotationType || alignment == null) continue; datum.text.alignment = alignment; } for (const [annotationType, options] of this.fibonacciOptions) { if (datum.type !== annotationType || options == null) continue; Object.entries(options).forEach(([option, value]) => { if (value == null) { return; } datum.set({ [option]: value }); }); } } }; var import_ag_charts_community50 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community48 = (init_main4(), __toCommonJS(main_exports)); var colorPickerTemplate_default = '
'; var { Color: Color3, clamp: clamp3, createElement: createElement2 } = import_ag_charts_community48._ModuleSupport; var getHsva = (input) => { try { const color = Color3.fromString(input); const [h, s, v] = color.toHSB(); return [h, s, v, color.a]; } catch { return; } }; var ColorPicker = class extends import_ag_charts_community48._ModuleSupport.AnchoredPopover { constructor(ctx, options) { super(ctx, "color-picker", options); this.hasChanged = false; this.hideFns.push(() => { if (this.hasChanged) this.onChangeHide?.(); }); } show(options) { this.hasChanged = false; this.onChangeHide = options.onChangeHide; const { element: element2, initialFocus } = this.createColorPicker(options); const popover = this.showWithChildren([element2], { initialFocus, ...options }); popover.classList.add("ag-charts-color-picker"); popover.setAttribute("role", "dialog"); } createColorPicker(opts) { let isMultiColor = opts.isMultiColor ?? false; let [h, s, v, a] = getHsva(opts.color ?? "#f00") ?? [0, 1, 0.5, 1]; a = opts.opacity ?? a; const colorPicker = createElement2("div", "ag-charts-color-picker__content"); colorPicker.innerHTML = colorPickerTemplate_default; colorPicker.ariaLabel = this.ctx.localeManager.t("ariaLabelColorPicker"); const paletteInput = colorPicker.querySelector(".ag-charts-color-picker__palette"); const hueInput = colorPicker.querySelector(".ag-charts-color-picker__hue-input"); const multiColorButton = colorPicker.querySelector( ".ag-charts-color-picker__multi-color-button" ); const alphaInput = colorPicker.querySelector(".ag-charts-color-picker__alpha-input"); const colorInput = colorPicker.querySelector(".ag-charts-color-picker__color-input"); const colorInputLabel = colorPicker.querySelector(".ag-charts-color-picker__color-label"); multiColorButton.classList.toggle( "ag-charts-color-picker__multi-color-button--hidden", !opts.hasMultiColorOption ); const update = (trackChange = true) => { const color = Color3.fromHSB(h, s, v, a); const colorString = color.toHexString(); colorPicker.style.setProperty("--h", `${h}`); colorPicker.style.setProperty("--s", `${s}`); colorPicker.style.setProperty("--v", `${v}`); colorPicker.style.setProperty("--a", `${a}`); colorPicker.style.setProperty("--color", colorString.slice(0, 7)); colorPicker.style.setProperty("--color-a", colorString); hueInput.value = `${h}`; alphaInput.value = `${a}`; alphaInput.classList.toggle("ag-charts-color-picker__alpha-input--opaque", a === 1); multiColorButton.classList.toggle("ag-charts-color-picker__multi-color-button--active", isMultiColor); colorInputLabel.classList.toggle("ag-charts-color-picker__color-label--multi-color", isMultiColor); if (document.activeElement !== colorInput) { colorInput.value = isMultiColor ? "Multi Colour" : colorString.toUpperCase(); } if (trackChange || opts.color == null) { const plainColor = Color3.fromHSB(h, s, v, 1).toHexString(); opts.onChange?.(colorString, plainColor, a, isMultiColor); } if (trackChange) this.hasChanged = true; }; update(false); const preventDefault = (event) => event.preventDefault(); const stopPropagation = (event) => event.stopPropagation(); const beginPaletteInteraction = (e) => { e.preventDefault(); const currentTarget = e.currentTarget; currentTarget.focus(); const rect = currentTarget.getBoundingClientRect(); const pointerMove = ({ pageX, pageY }) => { isMultiColor = false; s = Math.min(Math.max((pageX - rect.left) / rect.width, 0), 1); v = 1 - Math.min(Math.max((pageY - rect.top) / rect.height, 0), 1); update(); }; const pointerUp = () => { window.removeEventListener("pointermove", pointerMove); }; pointerMove(e); window.addEventListener("pointermove", pointerMove); window.addEventListener("pointerup", pointerUp, { once: true }); }; colorPicker.addEventListener("mousedown", stopPropagation); colorPicker.addEventListener("touchstart", stopPropagation); colorPicker.addEventListener("touchmove", stopPropagation); colorPicker.addEventListener("keydown", (e) => { e.stopPropagation(); switch (e.key) { case "Enter": case "Escape": this.hide(); break; default: return; } e.preventDefault(); }); paletteInput.addEventListener("pointerdown", beginPaletteInteraction); paletteInput.addEventListener("touchstart", preventDefault, { passive: false }); paletteInput.addEventListener("touchmove", preventDefault, { passive: false }); paletteInput.addEventListener("keydown", (e) => { if (e.key === "ArrowLeft") { s = clamp3(0, s - 0.01, 1); } else if (e.key === "ArrowRight") { s = clamp3(0, s + 0.01, 1); } else if (e.key === "ArrowUp") { v = clamp3(0, v + 0.01, 1); } else if (e.key === "ArrowDown") { v = clamp3(0, v - 0.01, 1); } else { return; } e.preventDefault(); update(); }); multiColorButton.addEventListener("click", () => { isMultiColor = !isMultiColor; update(); }); hueInput.addEventListener("input", (e) => { isMultiColor = false; h = e.currentTarget.valueAsNumber ?? 0; update(); }); alphaInput.addEventListener("input", (e) => { isMultiColor = false; a = e.currentTarget.valueAsNumber ?? 0; update(); }); colorInput.addEventListener("input", (e) => { isMultiColor = false; const hsva = getHsva(e.currentTarget.value); if (hsva == null) return; [h, s, v, a] = hsva; update(); }); colorInput.addEventListener("blur", () => update()); colorInput.addEventListener("keydown", (e) => { if (e.key === "Enter") { e.currentTarget.blur(); update(); } }); return { element: colorPicker, initialFocus: paletteInput }; } }; var import_ag_charts_community49 = (init_main4(), __toCommonJS(main_exports)); function channelMenuItemVisible(scale2) { return !(scale2 instanceof import_ag_charts_community49._ModuleSupport.LogScale) && !(scale2 instanceof import_ag_charts_community49._ModuleSupport.BandScale); } var LINE_ANNOTATION_ITEMS = [ { label: "toolbarAnnotationsTrendLine", icon: "trend-line-drawing", value: "line" /* Line */ }, { label: "toolbarAnnotationsHorizontalLine", icon: "horizontal-line-drawing", value: "horizontal-line" /* HorizontalLine */ }, { label: "toolbarAnnotationsVerticalLine", icon: "vertical-line-drawing", value: "vertical-line" /* VerticalLine */ }, { label: "toolbarAnnotationsParallelChannel", icon: "parallel-channel-drawing", value: "parallel-channel", visible: channelMenuItemVisible }, { label: "toolbarAnnotationsDisjointChannel", icon: "disjoint-channel-drawing", value: "disjoint-channel", visible: channelMenuItemVisible } ]; var FIBONACCI_ANNOTATION_ITEMS = [ { label: "toolbarAnnotationsFibonacciRetracement", icon: "fibonacci-retracement-drawing", value: "fibonacci-retracement" /* FibonacciRetracement */ }, { label: "toolbarAnnotationsFibonacciRetracementTrendBased", icon: "fibonacci-retracement-trend-based-drawing", value: "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */ } ]; var FIBONACCI_RATIO_ITEMS = [ { label: "Fibonacci - Extended", value: 10 }, { label: "Fibonacci - 6 Band", value: 6 }, { label: "Fibonacci - 4 Band", value: 4 } ]; var TEXT_ANNOTATION_ITEMS = [ { label: "toolbarAnnotationsText", icon: "text-annotation", value: "text" /* Text */ }, { label: "toolbarAnnotationsComment", icon: "comment-annotation", value: "comment" /* Comment */ }, { label: "toolbarAnnotationsCallout", icon: "callout-annotation", value: "callout" /* Callout */ }, { label: "toolbarAnnotationsNote", icon: "note-annotation", value: "note" /* Note */ } ]; var SHAPE_ANNOTATION_ITEMS = [ { label: "toolbarAnnotationsArrow", icon: "arrow-drawing", value: "arrow" /* Arrow */ }, { label: "toolbarAnnotationsArrowUp", icon: "arrow-up-drawing", value: "arrow-up" /* ArrowUp */ }, { label: "toolbarAnnotationsArrowDown", icon: "arrow-down-drawing", value: "arrow-down" /* ArrowDown */ } ]; var MEASURER_ANNOTATION_ITEMS = [ { label: "toolbarAnnotationsQuickDatePriceRange", icon: "measurer-drawing", value: "quick-date-price-range" /* QuickDatePriceRange */ }, { label: "toolbarAnnotationsDateRange", icon: "date-range-drawing", value: "date-range" /* DateRange */ }, { label: "toolbarAnnotationsPriceRange", icon: "price-range-drawing", value: "price-range" /* PriceRange */ }, { label: "toolbarAnnotationsDatePriceRange", icon: "date-price-range-drawing", value: "date-price-range" /* DatePriceRange */ } ]; var LINE_STROKE_WIDTH_ITEMS = [ { strokeWidth: 1, label: "1", value: 1 }, { strokeWidth: 2, label: "2", value: 2 }, { strokeWidth: 3, label: "3", value: 3 }, { strokeWidth: 4, label: "4", value: 4 }, { strokeWidth: 8, label: "8", value: 8 } ]; var LINE_STYLE_TYPE_ITEMS = [ { icon: "line-style-solid", altText: "iconAltTextLineStyleSolid", value: "solid" }, { icon: "line-style-dashed", altText: "iconAltTextLineStyleDashed", value: "dashed" }, { icon: "line-style-dotted", altText: "iconAltTextLineStyleDotted", value: "dotted" } ]; var TEXT_SIZE_ITEMS = [ { label: "10", value: 10 }, { label: "12", value: 12 }, { label: "14", value: 14 }, { label: "16", value: 16 }, { label: "18", value: 18 }, { label: "22", value: 22 }, { label: "28", value: 28 }, { label: "36", value: 36 }, { label: "46", value: 46 } ]; var { ARRAY: ARRAY22, BOOLEAN: BOOLEAN8, NUMBER: NUMBER8, OBJECT: OBJECT13, STRING: STRING16, UNION: UNION5, Color: Color4, FloatingToolbar: FloatingToolbar2, Listeners: Listeners2, Menu: Menu2, PropertiesArray: PropertiesArray2, ToolbarButtonProperties: ToolbarButtonProperties2, ToolbarButtonWidget: ToolbarButtonWidget2, Validate: Validate27 } = import_ag_charts_community50._ModuleSupport; var AnnotationOptionsButtonProperties = class extends ToolbarButtonProperties2 { constructor() { super(...arguments); this.checkedOverrides = new ToolbarButtonProperties2(); } }; __decorateClass2([ Validate27( UNION5([ "line-stroke-width", "line-style-type", "line-color", "fill-color", "text-color", "text-size", "delete", "settings", "lock" ]) ) ], AnnotationOptionsButtonProperties.prototype, "value", 2); __decorateClass2([ Validate27(OBJECT13, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "checkedOverrides", 2); __decorateClass2([ Validate27(STRING16, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "color", 2); __decorateClass2([ Validate27(NUMBER8, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate27(Boolean, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "isMultiColor", 2); var AnnotationOptionsButtonWidget = class extends ToolbarButtonWidget2 { update(options) { super.update(options); if (options.value === "line-stroke-width") { this.updateLineStrokeWidth(options); } if (options.value === "fill-color" || options.value === "line-color" || options.value === "text-color") { this.updateFillColor(options); } } updateFillColor(options) { const element2 = this.getElement(); element2.classList.add("ag-charts-annotations__color-picker-button"); element2.classList.toggle("ag-charts-annotations__color-picker-button--multi-color", options.isMultiColor); element2.style.setProperty("--color", options.color ?? null); } updateLineStrokeWidth(options) { const element2 = this.getElement(); element2.classList.add("ag-charts-annotations__stroke-width-button"); element2.style.setProperty("--stroke-width", `${options.strokeWidth}px`); } }; var FloatingAnnotationOptionsToolbar = class extends FloatingToolbar2 { createButtonWidget() { return new AnnotationOptionsButtonWidget(this.localeManager); } }; var AnnotationOptionsToolbar = class extends import_ag_charts_community50._ModuleSupport.BaseProperties { constructor(ctx, getActiveDatum) { super(); this.ctx = ctx; this.getActiveDatum = getActiveDatum; this.enabled = true; this.buttons = new PropertiesArray2(AnnotationOptionsButtonProperties); this.destroyFns = []; this.events = new Listeners2(); this.visibleButtons = []; this.toolbar = new FloatingAnnotationOptionsToolbar(this.ctx, "annotation-options"); this.colorPicker = new ColorPicker(this.ctx); this.textSizeMenu = new Menu2(this.ctx, "text-size"); this.lineStyleTypeMenu = new Menu2(this.ctx, "annotations-line-style-type"); this.lineStrokeWidthMenu = new Menu2(this.ctx, "annotations-line-stroke-width"); this.destroyFns.push( this.toolbar.addToolbarListener("button-pressed", this.onButtonPress.bind(this)), this.toolbar.addToolbarListener("toolbar-moved", this.onToolbarMoved.bind(this)), ctx.widgets.seriesWidget.addListener("drag-start", this.onDragStart.bind(this)), ctx.widgets.seriesWidget.addListener("drag-end", this.onDragEnd.bind(this)), () => this.colorPicker.destroy() ); } onDragStart() { this.toolbar.ignorePointerEvents(); } onDragEnd() { this.toolbar.capturePointerEvents(); } destroy() { for (const destroyFn of this.destroyFns) { destroyFn(); } } addListener(eventType, handler) { return this.events.addListener(eventType, handler); } show() { if (!this.enabled) return; this.toolbar.show(); } hide() { this.toolbar.hide(); } updateButtons(datum) { if (!this.enabled) return; const visible = { [ "line-style-type" /* LineStyleType */ ]: hasLineStyle(datum), [ "line-stroke-width" /* LineStrokeWidth */ ]: hasLineStyle(datum), [ "line-color" /* LineColor */ ]: hasLineColor(datum), [ "text-color" /* TextColor */ ]: hasTextColor(datum), [ "fill-color" /* FillColor */ ]: hasFillColor(datum), [ "text-size" /* TextSize */ ]: hasFontSize(datum), [ "settings" /* Settings */ ]: hasLineText(datum), [ "lock" /* Lock */ ]: true, [ "delete" /* Delete */ ]: true }; this.visibleButtons = this.buttons.filter((button) => visible[button.value]); this.toolbar.clearButtons(); this.toolbar.updateButtons(this.visibleButtons); this.refreshButtons(datum); } setAnchorScene(scene) { if (this.toolbar.hasBeenDragged()) return; this.toolbar.setAnchor(scene.getAnchor()); } hideOverlays() { this.toolbar.clearActiveButton(); this.colorPicker.hide({ lastFocus: null }); this.textSizeMenu.hide(); this.lineStyleTypeMenu.hide(); this.lineStrokeWidthMenu.hide(); this.dispatch("hid-overlays"); } clearActiveButton() { this.toolbar.clearActiveButton(); } updateColors(datum) { this.updateColorPickerColor( "line-color", datum.getDefaultColor( "line-color" /* LineColor */ ), datum.getDefaultOpacity( "line-color" /* LineColor */ ), "isMultiColor" in datum && datum?.isMultiColor ); this.updateColorPickerColor( "fill-color", datum.getDefaultColor( "fill-color" /* FillColor */ ), datum.getDefaultOpacity( "fill-color" /* FillColor */ ), "isMultiColor" in datum && datum?.isMultiColor ); this.updateColorPickerColor( "text-color", datum.getDefaultColor( "text-color" /* TextColor */ ), datum.getDefaultOpacity( "text-color" /* TextColor */ ), "isMultiColor" in datum && datum?.isMultiColor ); } updateColorPickerColor(colorPickerType, color, opacity, isMultiColor) { if (color != null && opacity != null) { const { r, g, b } = Color4.fromString(color); color = Color4.fromArray([r, g, b, opacity]).toHexString(); } this.updateButtonByValue(colorPickerType, { color, isMultiColor }); } updateFontSize(fontSize) { this.updateButtonByValue("text-size", { label: fontSize != null ? String(fontSize) : void 0 }); } updateLineStyleType(item) { this.updateButtonByValue("line-style-type", { icon: item.icon }); } updateStrokeWidth(item) { this.updateButtonByValue("line-stroke-width", { label: item.label, strokeWidth: item.value }); } dispatch(eventType, event) { this.events.dispatch(eventType, event); } onButtonPress({ event, button }) { const datum = this.getActiveDatum(); if (!datum) return; this.hideOverlays(); switch (button.value) { case "line-style-type": { const lineStyle = hasLineStyle(datum) ? getLineStyle(datum.lineDash, datum.lineStyle) : void 0; this.lineStyleTypeMenu.show({ items: LINE_STYLE_TYPE_ITEMS, ariaLabel: this.ctx.localeManager.t("toolbarAnnotationsLineStyle"), value: lineStyle, sourceEvent: event.sourceEvent, onPress: (item) => this.onLineStyleTypeMenuPress(item, datum), class: "ag-charts-annotations__line-style-type-menu" }); break; } case "line-stroke-width": { const strokeWidth = hasLineStyle(datum) ? datum.strokeWidth : void 0; this.lineStrokeWidthMenu.show({ items: LINE_STROKE_WIDTH_ITEMS, ariaLabel: this.ctx.localeManager.t("toolbarAnnotationsLineStrokeWidth"), value: strokeWidth, sourceEvent: event.sourceEvent, onPress: (item) => this.onLineStrokeWidthMenuPress(item, datum), class: "ag-charts-annotations__line-stroke-width-menu" }); break; } case "line-color": case "fill-color": case "text-color": { this.toolbar.toggleActiveButtonByIndex(button.index); this.colorPicker.show({ color: datum?.getDefaultColor(button.value), opacity: datum?.getDefaultOpacity(button.value), sourceEvent: event.sourceEvent, hasMultiColorOption: "isMultiColor" in datum, isMultiColor: "isMultiColor" in datum && datum?.isMultiColor, onChange: datum != null ? this.onColorPickerChange.bind(this, button.value, datum) : void 0, onChangeHide: ((type) => { this.dispatch("saved-color", { type: datum.type, colorPickerType: button.value, color: datum.getDefaultColor(type) }); }).bind(this, button.value) }); break; } case "text-size": { const fontSize = isTextType(datum) ? datum.fontSize : void 0; this.textSizeMenu.show({ items: TEXT_SIZE_ITEMS, ariaLabel: this.ctx.localeManager.t("toolbarAnnotationsTextSize"), value: fontSize, sourceEvent: event.sourceEvent, onPress: (item) => this.onTextSizeMenuPress(item, datum), class: "ag-charts-annotations__text-size-menu" }); break; } case "delete": { this.dispatch("pressed-delete"); break; } case "lock": { datum.locked = !datum.locked; this.refreshButtons(datum); this.dispatch("pressed-lock"); break; } case "settings": { this.toolbar.toggleActiveButtonByIndex(button.index); this.dispatch("pressed-settings", event); break; } } } onToolbarMoved(event) { const { buttonBounds, popoverBounds } = event; const colorPickerAnchor = { x: popoverBounds.x, y: popoverBounds.y + popoverBounds.height + 4 }; const colorPickerFallbackAnchor = { y: popoverBounds.y - 4 }; this.colorPicker.setAnchor(colorPickerAnchor, colorPickerFallbackAnchor); for (const [index, bounds] of buttonBounds.entries()) { const button = this.visibleButtons.at(index); if (!button) continue; const anchor = { x: bounds.x, y: bounds.y + bounds.height - 1 }; const fallbackAnchor = { y: bounds.y }; switch (button.value) { case "line-stroke-width": this.lineStrokeWidthMenu.setAnchor(anchor, fallbackAnchor); break; case "line-style-type": this.lineStyleTypeMenu.setAnchor(anchor, fallbackAnchor); break; case "text-size": this.textSizeMenu.setAnchor(anchor, fallbackAnchor); break; } } } onColorPickerChange(colorPickerType, datum, colorOpacity, color, opacity, isMultiColor) { this.dispatch("updated-color", { type: datum.type, colorPickerType, colorOpacity, color, opacity, isMultiColor }); this.updateColorPickerColor(colorPickerType, colorOpacity, opacity, isMultiColor); } onTextSizeMenuPress(item, datum) { if (!hasFontSize(datum)) return; const fontSize = item.value; this.dispatch("updated-font-size", { type: datum.type, fontSize }); this.textSizeMenu.hide(); this.updateFontSize(fontSize); } onLineStyleTypeMenuPress(item, datum) { if (!hasLineStyle(datum)) return; const type = item.value; this.dispatch("updated-line-style", { type: datum.type, lineStyleType: type }); this.lineStyleTypeMenu.hide(); this.updateLineStyleType(item); } onLineStrokeWidthMenuPress(item, datum) { if (!hasLineStyle(datum)) { return; } const strokeWidth = item.value; this.dispatch("updated-line-width", { type: datum.type, strokeWidth }); this.lineStrokeWidthMenu.hide(); this.updateStrokeWidth(item); } refreshButtons(datum) { const locked = datum.locked ?? false; for (const [index, button] of this.visibleButtons.entries()) { if (!button) continue; if (button.value === "lock") { this.toolbar.toggleSwitchCheckedByIndex(index, locked); this.updateButtonByIndex(index, locked ? button.checkedOverrides.toJson() : button.toJson()); } else { this.toolbar.toggleButtonEnabledByIndex(index, !locked); } } if (hasFontSize(datum)) this.updateFontSize(datum.fontSize); this.updateColors(datum); this.updateLineStyles(datum); } updateLineStyles(datum) { if (!hasLineStyle(datum)) return; const strokeWidth = datum.strokeWidth ?? 1; const lineStyleType = getLineStyle(datum.lineDash, datum.lineStyle); this.updateStrokeWidth({ strokeWidth, value: strokeWidth, label: String(strokeWidth) }); this.updateLineStyleType( LINE_STYLE_TYPE_ITEMS.find((item) => item.value === lineStyleType) ?? LINE_STYLE_TYPE_ITEMS[0] ); } updateButtonByValue(value, change) { const index = this.visibleButtons.findIndex((button) => button.value === value); if (index === -1) return; this.updateButtonByIndex(index, change); } updateButtonByIndex(index, change) { const button = this.visibleButtons.at(index); if (!button) return; this.toolbar.updateButtonByIndex(index, { ...button.toJson(), ...change, value: change.value ?? button.value }); } }; __decorateClass2([ Validate27(BOOLEAN8) ], AnnotationOptionsToolbar.prototype, "enabled", 2); __decorateClass2([ Validate27(ARRAY22) ], AnnotationOptionsToolbar.prototype, "buttons", 2); var import_ag_charts_community51 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine2, StateMachineProperty: StateMachineProperty2, Vec2: Vec222, Debug: Debug2 } = import_ag_charts_community51._ModuleSupport; var DragStateMachine = class extends StateMachine2 { constructor(ctx) { const actionKeyChange = ({ context }) => { this.node?.drag(this.datum, this.offset, context, this.snapping); ctx.update(); }; super("idle", { idle: { dragStart: { target: "dragging", action: ({ offset: offset4, context }) => { this.hasMoved = false; this.dragStart = offset4; this.offset = offset4; this.node?.dragStart(this.datum, offset4, context); } } }, dragging: { keyDown: actionKeyChange, keyUp: actionKeyChange, drag: ({ offset: offset4, context }) => { this.hasMoved = Vec222.lengthSquared(Vec222.sub(offset4, this.dragStart)) > 0; this.offset = offset4; this.node?.drag(this.datum, offset4, context, this.snapping); ctx.update(); }, dragEnd: { target: StateMachine2.parent, action: () => { this.node?.stopDragging(); if (this.hasMoved) ctx.recordAction("Move annotation"); ctx.update(); } } } }); this.debug = Debug2.create(true, "annotations"); this.hasMoved = false; this.snapping = false; } }; __decorateClass2([ StateMachineProperty2() ], DragStateMachine.prototype, "snapping", 2); __decorateClass2([ StateMachineProperty2() ], DragStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty2() ], DragStateMachine.prototype, "node", 2); var import_ag_charts_community52 = (init_main4(), __toCommonJS(main_exports)); var { STRING: STRING17, Validate: Validate28 } = import_ag_charts_community52._ModuleSupport; var ArrowDownProperties = class extends ShapePointProperties { constructor() { super(...arguments); this.type = "arrow-down"; } static is(value) { return isObject2(value) && value.type === "arrow-down"; } }; __decorateClass2([ Validate28(STRING17) ], ArrowDownProperties.prototype, "type", 2); var import_ag_charts_community58 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community57 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community54 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community53 = (init_main4(), __toCommonJS(main_exports)); var _Handle = class _Handle2 extends import_ag_charts_community53._ModuleSupport.Group { constructor() { super(...arguments); this.active = false; this.locked = false; this.visible = false; this.zIndex = 1; } drag(target) { const { handle: handle22, locked } = this; if (locked) { return { point: { x: handle22.x, y: handle22.y }, offset: { x: 0, y: 0 } }; } return { point: target, offset: { x: target.x - handle22.x, y: target.y - handle22.y } }; } toggleActive(active) { this.active = active; if (!active) { this.handle.strokeWidth = _Handle2.INACTIVE_STROKE_WIDTH; } } toggleHovered(hovered) { this.glow.visible = !this.locked && hovered; this.glow.dirtyPath = true; } toggleDragging(dragging) { if (this.locked) return; this.handle.visible = !dragging; this.glow.visible = this.glow.visible && !dragging; this.handle.dirtyPath = true; this.glow.dirtyPath = true; } toggleLocked(locked) { this.locked = locked; } getCursor() { return void 0; } containsPoint(x, y) { return this.handle.containsPoint(x, y); } }; _Handle.INACTIVE_STROKE_WIDTH = 2; var Handle2 = _Handle; var _InvariantHandle = class _InvariantHandle2 extends Handle2 { constructor() { super(); this.handle = new import_ag_charts_community53._ModuleSupport.Marker({ shape: "circle" }); this.glow = new import_ag_charts_community53._ModuleSupport.Marker({ shape: "circle" }); this.append([this.handle]); this.handle.size = _InvariantHandle2.HANDLE_SIZE; this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH; this.handle.zIndex = 2; } update(styles) { this.handle.setProperties({ ...styles, strokeWidth: Handle2.INACTIVE_STROKE_WIDTH }); } drag(target) { return { point: target, offset: { x: 0, y: 0 } }; } }; _InvariantHandle.HANDLE_SIZE = 7; _InvariantHandle.GLOW_SIZE = 9; var InvariantHandle = _InvariantHandle; var _UnivariantHandle = class _UnivariantHandle2 extends Handle2 { constructor() { super(); this.handle = new import_ag_charts_community53._ModuleSupport.Rect(); this.glow = new import_ag_charts_community53._ModuleSupport.Rect(); this.gradient = "horizontal"; this.append([this.glow, this.handle]); this.handle.cornerRadius = _UnivariantHandle2.CORNER_RADIUS; this.handle.width = _UnivariantHandle2.HANDLE_SIZE; this.handle.height = _UnivariantHandle2.HANDLE_SIZE; this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH; this.handle.zIndex = 2; this.glow.cornerRadius = _UnivariantHandle2.CORNER_RADIUS; this.glow.width = _UnivariantHandle2.GLOW_SIZE; this.glow.height = _UnivariantHandle2.GLOW_SIZE; this.glow.strokeWidth = 0; this.glow.fillOpacity = 0.2; this.glow.zIndex = 1; this.glow.visible = false; } toggleLocked(locked) { super.toggleLocked(locked); if (locked) { const offset4 = (_UnivariantHandle2.HANDLE_SIZE - InvariantHandle.HANDLE_SIZE) / 2; this.handle.cornerRadius = 1; this.handle.fill = this.handle.stroke; this.handle.strokeWidth = 0; this.handle.x += offset4; this.handle.y += offset4; this.handle.width = InvariantHandle.HANDLE_SIZE; this.handle.height = InvariantHandle.HANDLE_SIZE; this.glow.width = InvariantHandle.GLOW_SIZE; this.glow.height = InvariantHandle.GLOW_SIZE; } else { this.handle.cornerRadius = _UnivariantHandle2.CORNER_RADIUS; this.handle.width = _UnivariantHandle2.HANDLE_SIZE; this.handle.height = _UnivariantHandle2.HANDLE_SIZE; this.glow.width = _UnivariantHandle2.GLOW_SIZE; this.glow.height = _UnivariantHandle2.GLOW_SIZE; if (this.cachedStyles) { this.handle.setProperties(this.cachedStyles); } } } update(styles) { this.cachedStyles = { ...styles }; if (!this.active) { delete styles.strokeWidth; } if (this.locked) { delete styles.fill; delete styles.strokeWidth; const offset4 = (_UnivariantHandle2.HANDLE_SIZE - InvariantHandle.HANDLE_SIZE) / 2; styles.x -= offset4; styles.y -= offset4; this.cachedStyles.x -= offset4; this.cachedStyles.y -= offset4; } this.handle.setProperties(styles); this.glow.setProperties({ ...styles, x: (styles.x ?? this.glow.x) - 2, y: (styles.y ?? this.glow.y) - 2, strokeWidth: 0, fill: styles.stroke }); } drag(target) { if (this.locked) { return { point: target, offset: { x: 0, y: 0 } }; } if (this.gradient === "vertical") { return { point: { x: target.x, y: this.handle.y }, offset: { x: target.x - this.handle.x, y: 0 } }; } return { point: { x: this.handle.x, y: target.y }, offset: { x: 0, y: target.y - this.handle.y } }; } getCursor() { if (this.locked) return; return this.gradient === "vertical" ? "col-resize" : "row-resize"; } }; _UnivariantHandle.HANDLE_SIZE = 12; _UnivariantHandle.GLOW_SIZE = 16; _UnivariantHandle.CORNER_RADIUS = 4; var UnivariantHandle = _UnivariantHandle; var _DivariantHandle = class _DivariantHandle2 extends Handle2 { constructor() { super(); this.handle = new import_ag_charts_community53._ModuleSupport.Marker({ shape: "circle" }); this.glow = new import_ag_charts_community53._ModuleSupport.Marker({ shape: "circle" }); this.append([this.glow, this.handle]); this.handle.size = _DivariantHandle2.HANDLE_SIZE; this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH; this.handle.zIndex = 2; this.glow.size = _DivariantHandle2.GLOW_SIZE; this.glow.strokeWidth = 0; this.glow.fillOpacity = 0.2; this.glow.zIndex = 1; this.glow.visible = false; } toggleLocked(locked) { super.toggleLocked(locked); if (locked) { this.handle.fill = this.handle.stroke; this.handle.strokeWidth = 0; this.handle.size = InvariantHandle.HANDLE_SIZE; this.glow.size = InvariantHandle.GLOW_SIZE; } else { this.handle.size = _DivariantHandle2.HANDLE_SIZE; this.glow.size = _DivariantHandle2.GLOW_SIZE; if (this.cachedStyles) { this.handle.setProperties(this.cachedStyles); } } } update(styles) { this.cachedStyles = { ...styles }; if (!this.active) { delete styles.strokeWidth; } if (this.locked) { delete styles.fill; delete styles.strokeWidth; } this.handle.setProperties(styles); this.glow.setProperties({ ...styles, strokeWidth: 0, fill: styles.stroke }); } getCursor() { return "pointer"; } }; _DivariantHandle.HANDLE_SIZE = 11; _DivariantHandle.GLOW_SIZE = 17; var DivariantHandle = _DivariantHandle; var { ZIndexMap: ZIndexMap22 } = import_ag_charts_community54._ModuleSupport; var AnnotationScene = class extends import_ag_charts_community54._ModuleSupport.Group { constructor() { super(...arguments); this.name = "AnnotationScene"; this.zIndex = ZIndexMap22.CHART_ANNOTATION; } static isCheck(value, type) { return isObject2(value) && Object.hasOwn(value, "type") && value.type === type; } toggleHovered(hovered) { this.toggleHandles(hovered); } *nonHandleChildren() { for (const child of this.children()) { if (!(child instanceof Handle2)) { yield child; } } } computeBBoxWithoutHandles() { return import_ag_charts_community54._ModuleSupport.Transformable.toCanvas( this, import_ag_charts_community54._ModuleSupport.Group.computeChildrenBBox(this.nonHandleChildren()) ); } updateNode(constructor, node, isConfigured) { if (!isConfigured && node) { this.removeChild(node); return; } if (isConfigured && node == null) { node = new constructor(); this.appendChild(node); } return node; } }; var import_ag_charts_community56 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community55 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec23, toRadians: toRadians4 } = import_ag_charts_community55._ModuleSupport; function snapPoint(offset4, context, snapping = false, origin3, angleStep = 1) { if (!snapping) return invertCoords(offset4, context); const center2 = origin3 ? convertPoint(origin3, context) : Vec23.origin(); return invertCoords(snapToAngle(offset4, center2, angleStep), context); } function snapToAngle({ x, y }, center2, step, direction = 1) { const { x: cx, y: cy } = center2; const r = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(y - cy, 2)); const theta = Math.atan2(y - cy, x - cx); const stepRadians = toRadians4(step); const snapTheta = Math.round(theta / stepRadians) * stepRadians; return { x: cx + r * Math.cos(snapTheta), y: cy + r * Math.sin(snapTheta) * direction }; } function getDragStartState(points, context) { const dragState = {}; Object.entries(points).forEach(([name, point]) => { dragState[name] = convertPoint(point, context); }); return dragState; } function translate(vectors, translation, context) { const vecs = []; const result = {}; Object.entries(vectors).forEach(([name, vector]) => { const translatedVec = Vec23.add(vector, translation); vecs.push(translatedVec); result[name] = invertCoords(translatedVec, context); }); const { xAxis, yAxis } = context; const within = (min, value, max) => value >= min && value <= max; const translateX = vecs.every((vec) => within(xAxis.bounds.x, vec.x, xAxis.bounds.x + xAxis.bounds.width)); const translateY = vecs.every((vec) => within(yAxis.bounds.y, vec.y, yAxis.bounds.y + yAxis.bounds.height)); return { vectors: result, translateX, translateY }; } var { Vec2: Vec24 } = import_ag_charts_community56._ModuleSupport; var PointScene = class extends AnnotationScene { constructor() { super(...arguments); this.handle = new DivariantHandle(); this.anchor = { x: 0, y: 0, position: "above" }; } update(datum, context) { const coords = convertPoint(datum, context); this.updateHandle(datum, coords); this.anchor = this.updateAnchor(datum, coords, context); } dragStart(datum, target, context) { this.dragState = { offset: target, ...getDragStartState({ handle: datum }, context) }; } drag(datum, target, context) { const { dragState } = this; if (datum.locked || !dragState) return; const coords = Vec24.add(dragState.handle, Vec24.sub(target, dragState.offset)); const point = invertCoords(coords, context); if (!validateDatumPoint(context, point)) return; datum.x = point.x; datum.y = point.y; } translate(datum, translation, context) { const coords = Vec24.add(convertPoint(datum, context), translation); const point = invertCoords(coords, context); if (!validateDatumPoint(context, point)) { return; } datum.x = point.x; datum.y = point.y; } toggleHandles(show) { this.handle.visible = Boolean(show); this.handle.toggleHovered(this.activeHandle === "handle"); } toggleActive(active) { this.toggleHandles(active); this.handle.toggleActive(active); } stopDragging() { this.handle.toggleDragging(false); } copy(datum, copiedDatum, context) { const coords = convertPoint(datum, context); const point = invertCoords({ x: coords.x - 30, y: coords.y - 30 }, context); copiedDatum.x = point.x; copiedDatum.y = point.y; return copiedDatum; } getAnchor() { return this.anchor; } getCursor() { return "pointer"; } containsPoint(x, y) { const { handle: handle22 } = this; this.activeHandle = void 0; if (handle22.containsPoint(x, y)) { this.activeHandle = "handle"; return true; } return false; } getNodeAtCoords(x, y) { if (this.handle.containsPoint(x, y)) return "handle"; } updateHandle(datum, point, bbox) { const { x, y } = this.getHandleCoords(datum, point, bbox); const styles = this.getHandleStyles(datum); this.handle.update({ ...styles, x, y }); this.handle.toggleLocked(datum.locked ?? false); } updateAnchor(datum, point, context) { const coords = this.getHandleCoords(datum, point); return { x: coords.x + context.seriesRect.x, y: coords.y + context.seriesRect.y, position: this.anchor.position }; } getHandleCoords(_datum, point, _bbox) { return { x: point.x, y: point.y }; } getHandleStyles(datum) { return { fill: datum.handle.fill, stroke: datum.handle.stroke, strokeOpacity: datum.handle.strokeOpacity, strokeWidth: datum.handle.strokeWidth }; } }; var ShapePointScene = class extends PointScene { constructor() { super(); this.append([this.handle]); } update(datum, context) { super.update(datum, context); const coords = convertPoint(datum, context); this.updateShape(datum, coords); } updateShape(datum, point) { this.updateShapeStyles(datum); this.updateShapePath(datum, point); } updateShapeStyles(datum) { const { shape } = this; shape.fill = datum.fill; shape.fillOpacity = datum.fillOpacity ?? 1; } updateShapePath(datum, point) { const { shape } = this; shape.x = point.x; shape.y = point.y; shape.size = datum.size; } containsPoint(x, y) { return super.containsPoint(x, y) || this.shape.containsPoint(x, y); } getNodeAtCoords(x, y) { if (this.shape.containsPoint(x, y)) return "shape"; return super.getNodeAtCoords(x, y); } }; var arrowUpPoints = [ [0.5, 0], [1, 0.5], [0.75, 0.5], [0.75, 1], [0.25, 1], [0.25, 0.5], [0, 0.5] ]; function arrowUp(params) { import_ag_charts_community57._ModuleSupport.drawMarkerUnitPolygon(params, arrowUpPoints); } arrowUp.anchor = { x: 0.5, y: 0 }; var ArrowUpScene = class extends ShapePointScene { constructor() { super(); this.type = "arrow-up"; this.shape = new import_ag_charts_community57._ModuleSupport.Marker({ shape: arrowUp }); this.append([this.shape]); } static is(value) { return AnnotationScene.isCheck( value, "arrow-up" /* ArrowUp */ ); } getHandleCoords(datum, point) { const halfSize = DivariantHandle.HANDLE_SIZE / 2; const handleCoords = super.getHandleCoords(datum, point); handleCoords.y -= halfSize; return handleCoords; } }; var arrowDownPoints = arrowUpPoints.map(([x, y]) => [x, 1 - y]); function arrowDown(params) { import_ag_charts_community58._ModuleSupport.drawMarkerUnitPolygon(params, arrowDownPoints); } arrowDown.anchor = { x: 0.5, y: 1 }; var ArrowDownScene = class extends ShapePointScene { constructor() { super(); this.type = "arrow-down"; this.shape = new import_ag_charts_community58._ModuleSupport.Marker({ shape: arrowDown }); this.append([this.shape]); } static is(value) { return AnnotationScene.isCheck( value, "arrow-down" /* ArrowDown */ ); } updateAnchor(datum, point, context) { const anchor = super.updateAnchor(datum, point, context); anchor.y -= datum.size; return anchor; } getHandleCoords(datum, point) { const halfSize = DivariantHandle.HANDLE_SIZE / 2; const handleCoords = super.getHandleCoords(datum, point); handleCoords.y += halfSize; return handleCoords; } }; var import_ag_charts_community59 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine22, StateMachineProperty: StateMachineProperty22, Debug: Debug22 } = import_ag_charts_community59._ModuleSupport; var PointStateMachine = class extends StateMachine22 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = this.createDatum(); datum.set({ x: point.x, y: point.y }); ctx.create(datum); }; const actionFirstRender = () => { this.node?.toggleActive(true); ctx.showAnnotationOptions(); ctx.update(); }; super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, drag: { target: "waiting-first-render", action: actionCreate }, cancel: StateMachine22.parent, reset: StateMachine22.parent }, "waiting-first-render": { render: { target: StateMachine22.parent, action: actionFirstRender } } }); this.debug = Debug22.create(true, "annotations"); } }; __decorateClass2([ StateMachineProperty22() ], PointStateMachine.prototype, "node", 2); var ArrowDownStateMachine = class extends PointStateMachine { createDatum() { return new ArrowDownProperties(); } }; var arrowDownConfig = { type: "arrow-down", datum: ArrowDownProperties, scene: ArrowDownScene, isDatum: ArrowDownProperties.is, translate: (node, datum, translation, context) => { if (ArrowDownProperties.is(datum) && ArrowDownScene.is(node)) node.translate(datum, translation, context); }, copy: (node, datum, copiedDatum, context) => { if (ArrowDownProperties.is(datum) && ArrowDownProperties.is(copiedDatum) && ArrowDownScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (ArrowDownProperties.is(datum) && ArrowDownScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new ArrowDownStateMachine({ ...ctx, create: createDatum( "arrow-down" /* ArrowDown */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community60 = (init_main4(), __toCommonJS(main_exports)); var { STRING: STRING18, Validate: Validate29 } = import_ag_charts_community60._ModuleSupport; var ArrowUpProperties = class extends ShapePointProperties { constructor() { super(...arguments); this.type = "arrow-up"; } static is(value) { return isObject2(value) && value.type === "arrow-up"; } }; __decorateClass2([ Validate29(STRING18) ], ArrowUpProperties.prototype, "type", 2); var ArrowUpStateMachine = class extends PointStateMachine { createDatum() { return new ArrowUpProperties(); } }; var arrowUpConfig = { type: "arrow-up", datum: ArrowUpProperties, scene: ArrowUpScene, isDatum: ArrowUpProperties.is, translate: (node, datum, translation, context) => { if (ArrowUpProperties.is(datum) && ArrowUpScene.is(node)) node.translate(datum, translation, context); }, copy: (node, datum, copiedDatum, context) => { if (ArrowUpProperties.is(datum) && ArrowUpProperties.is(copiedDatum) && ArrowUpScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (ArrowUpProperties.is(datum) && ArrowUpScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new ArrowUpStateMachine({ ...ctx, create: createDatum( "arrow-up" /* ArrowUp */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community64 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community63 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community62 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community61 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec25, Vec4: Vec42 } = import_ag_charts_community61._ModuleSupport; var LinearScene = class extends AnnotationScene { extendLine({ x1, y1, x2, y2 }, datum, context) { const linePoints = { x1, y1, x2, y2 }; if (!datum.extendStart && !datum.extendEnd) { return linePoints; } const [left, right] = boundsIntersections(linePoints, context.yAxis.bounds); const isFlippedX = linePoints.x2 < linePoints.x1; const isFlippedY = linePoints.y1 >= linePoints.y2; const isVertical = linePoints.x2 === linePoints.x1; if (datum.extendEnd) { if (isVertical) { linePoints.y2 = isFlippedY ? right.y : left.y; } else { linePoints.x2 = isFlippedX ? left.x : right.x; linePoints.y2 = isFlippedX ? left.y : right.y; } } if (datum.extendStart) { if (isVertical) { linePoints.y1 = isFlippedY ? left.y : right.y; } else { linePoints.x1 = isFlippedX ? right.x : left.x; linePoints.y1 = isFlippedX ? right.y : left.y; } } return linePoints; } dragStart(datum, target, context) { this.dragState = { offset: target, ...getDragStartState({ start: datum.start, end: datum.end }, context) }; } drag(datum, target, context, snapping) { if (datum.locked) return; if (this.activeHandle) { this.dragHandle(datum, target, context, snapping); } else { this.dragAll(datum, target, context); } } dragAll(datum, target, context) { const { dragState } = this; if (!dragState) return; this.translatePoints(datum, dragState.start, dragState.end, Vec25.sub(target, dragState.offset), context); } translatePoints(datum, start2, end2, translation, context) { const { vectors, translateX, translateY } = translate({ start: start2, end: end2 }, translation, context); if (translateX) { datum.start.x = vectors.start?.x; datum.end.x = vectors.end?.x; } if (this.ignoreYBounds || translateY) { datum.start.y = vectors.start?.y; datum.end.y = vectors.end?.y; } } translate(datum, translation, context) { this.translatePoints( datum, convertPoint(datum.start, context), convertPoint(datum.end, context), translation, context ); } copy(datum, copiedDatum, context) { const coords = convertLine(datum, context); if (!coords) { return; } const bbox = this.computeBBoxWithoutHandles(); const translation = { x: -bbox.width / 2, y: -bbox.height / 2 }; this.translatePoints(copiedDatum, Vec42.start(coords), Vec42.end(coords), translation, context); return copiedDatum; } }; var { Vec4: Vec422 } = import_ag_charts_community62._ModuleSupport; var StartEndScene = class extends LinearScene { constructor() { super(...arguments); this.start = new DivariantHandle(); this.end = new DivariantHandle(); this.anchor = { x: 0, y: 0, position: "above" }; } update(datum, context) { const coords = convertLine(datum, context); if (coords == null) { return; } this.updateHandles(datum, coords); this.updateAnchor(datum, coords, context); } toggleHandles(show) { if (typeof show === "boolean") { this.start.visible = show; this.end.visible = show; } else { for (const [handle22, visible] of Object.entries(show)) { this[handle22].visible = visible; } } this.start.toggleHovered(this.activeHandle === "start"); this.end.toggleHovered(this.activeHandle === "end"); } toggleActive(active) { this.toggleHandles(active); this.start.toggleActive(active); this.end.toggleActive(active); } dragHandle(datum, target, context, snapping) { const { activeHandle, dragState } = this; if (!activeHandle || !dragState) return; this[activeHandle].toggleDragging(true); const point = snapping ? this.snapToAngle(datum, target, context) : invertCoords(this[activeHandle].drag(target).point, context); if (!point || !validateDatumPoint(context, point)) return; datum[activeHandle].x = point.x; datum[activeHandle].y = point.y; } snapToAngle(datum, coords, context) { const { activeHandle } = this; const handles = ["start", "end"]; const fixedHandle = handles.find((handle22) => handle22 !== activeHandle); if (!activeHandle || !fixedHandle) return; this[activeHandle].toggleDragging(true); const fixed = convertPoint(datum[fixedHandle], context); return invertCoords(snapToAngle(coords, fixed, datum.snapToAngle), context); } stopDragging() { this.start.toggleDragging(false); this.end.toggleDragging(false); } getAnchor() { return this.anchor; } getCursor() { return "pointer"; } containsPoint(x, y) { const { start: start2, end: end2 } = this; this.activeHandle = void 0; if (start2.containsPoint(x, y)) { this.activeHandle = "start"; return true; } if (end2.containsPoint(x, y)) { this.activeHandle = "end"; return true; } return false; } getNodeAtCoords(x, y) { if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y)) return "handle"; } updateHandles(datum, coords, bbox) { this.start.update({ ...this.getHandleStyles(datum, "start"), ...this.getHandleCoords(datum, coords, "start") }); this.end.update({ ...this.getHandleStyles(datum, "end"), ...this.getHandleCoords(datum, coords, "end", bbox) }); this.start.toggleLocked(datum.locked ?? false); this.end.toggleLocked(datum.locked ?? false); } updateAnchor(_datum, coords, context, _bbox) { this.anchor = { x: coords.x1 + context.seriesRect.x, y: coords.y1 + context.seriesRect.y, position: this.anchor.position }; } getHandleCoords(_datum, coords, handle22, _bbox) { return handle22 === "start" ? Vec422.start(coords) : Vec422.end(coords); } getHandleStyles(datum, _handle) { return { fill: datum.handle.fill, stroke: datum.handle.stroke, strokeOpacity: datum.handle.strokeOpacity, strokeWidth: datum.handle.strokeWidth }; } }; var { Vec2: Vec26, Vec4: Vec43 } = import_ag_charts_community63._ModuleSupport; var TextualStartEndScene = class extends StartEndScene { constructor() { super(...arguments); this.label = new import_ag_charts_community63._ModuleSupport.Text({ zIndex: 1 }); this.anchor = { x: 0, y: 0, position: "above-left" }; } setTextInputBBox(bbox) { this.textInputBBox = bbox; this.markDirty(); } update(datum, context) { const coords = convertLine(datum, context); if (coords == null) { return; } const bbox = this.getTextBBox(datum, coords); this.updateLabel(datum, bbox, coords); this.updateHandles(datum, coords, bbox); this.updateShape(datum, bbox, coords); this.updateAnchor(datum, coords, context, bbox); } dragHandle(datum, target, context, snapping) { const { activeHandle, dragState } = this; if (!activeHandle || !dragState) return; this[activeHandle].toggleDragging(true); const coords = Vec26.add(dragState.end, Vec26.sub(target, dragState.offset)); const point = snapping ? this.snapToAngle(datum, coords, context) : invertCoords(coords, context); if (!point || !validateDatumPoint(context, point)) return; datum[activeHandle].x = point.x; datum[activeHandle].y = point.y; } containsPoint(x, y) { const { label } = this; return super.containsPoint(x, y) || label.containsPoint(x, y); } getNodeAtCoords(x, y) { if (this.label.containsPoint(x, y)) return "text"; return super.getNodeAtCoords(x, y); } getTextBBox(datum, coords) { const { text: text22 } = datum.getText(); return getBBox(datum, text22, Vec43.end(coords), this.textInputBBox); } updateLabel(datum, bbox, coords) { const { text: text22, isPlaceholder } = datum.getText(); updateTextNode(this.label, text22, isPlaceholder, datum, this.getLabelCoords(datum, bbox, coords)); } updateShape(_datum, _textBBox, _coords) { } getLabelCoords(_datum, _bbox, coords) { return Vec43.end(coords); } getHandleStyles(datum, handle22) { return { ...super.getHandleStyles(datum, handle22), stroke: datum.handle.stroke ?? datum.color }; } }; var { drawCorner: drawCorner2, Path: Path5 } = import_ag_charts_community64._ModuleSupport; var CalloutScene = class extends TextualStartEndScene { constructor() { super(); this.type = "callout"; this.shape = new Path5(); this.append([this.shape, this.label, this.start, this.end]); } static is(value) { return AnnotationScene.isCheck( value, "callout" /* Callout */ ); } drag(datum, target, context, snapping) { if (datum.locked) return; if (this.activeHandle === "end") { this.dragHandle(datum, target, context, snapping); } else { this.dragAll(datum, target, context); } } getLabelCoords(datum, bbox, coords) { const padding = datum.getPadding(); const { bodyBounds = { x: 0, y: 0, width: 0, height: 0 } } = this.getDimensions(datum, bbox, coords) ?? {}; return { x: bodyBounds.x + padding.left, y: bodyBounds.y - padding.bottom }; } getHandleStyles(datum, handle22) { return handle22 === "start" ? { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke, strokeOpacity: datum.handle.strokeOpacity, strokeWidth: datum.handle.strokeWidth } : { fill: void 0, strokeWidth: 0 }; } updateAnchor(datum, coords, context, bbox) { const { bodyBounds } = this.getDimensions(datum, bbox, coords) ?? {}; const bounds = bodyBounds ?? bbox; this.anchor = { x: bounds.x + context.seriesRect.x, y: bounds.y + context.seriesRect.y - bounds.height, position: this.anchor.position }; } updateShape(datum, textBBox, coords) { const { shape } = this; shape.fill = datum.fill; shape.fillOpacity = datum.fillOpacity ?? 1; shape.stroke = datum.stroke; shape.strokeWidth = datum.strokeWidth ?? 1; shape.strokeOpacity = datum.strokeOpacity ?? 1; const { tailPoint, bodyBounds } = this.getDimensions(datum, textBBox, coords) ?? {}; if (!tailPoint || !bodyBounds) { return; } this.updatePath(tailPoint, bodyBounds); } updatePath(tailPoint, bodyBounds) { const { x: tailX, y: tailY } = tailPoint; const { x, y, width: width2, height: height2 } = bodyBounds; const top = y - height2; const right = x + width2; const placement = this.calculateCalloutPlacement({ x: tailX, y: tailY }, bodyBounds); const cornerRadius = 8; const pathParams = [ { coordinates: { x0: x, x1: x + cornerRadius, y0: top + cornerRadius, y1: top, cx: placement === `topLeft` ? tailX : x + cornerRadius, cy: placement === `topLeft` ? tailY : top + cornerRadius }, type: placement === `topLeft` ? "calloutCorner" : "corner" }, { coordinates: { x0: x + cornerRadius, x1: right - cornerRadius, y0: top, y1: top, cx: tailX, cy: tailY }, type: placement === `top` ? "calloutSide" : "side" }, { coordinates: { x0: right - cornerRadius, x1: right, y0: top, y1: top + cornerRadius, cx: placement === `topRight` ? tailX : right - cornerRadius, cy: placement === `topRight` ? tailY : top + cornerRadius }, type: placement === `topRight` ? "calloutCorner" : "corner" }, { coordinates: { x0: right, x1: right, y0: top + cornerRadius, y1: y - cornerRadius, cx: tailX, cy: tailY }, type: placement === `right` ? "calloutSide" : "side" }, { coordinates: { x0: right, x1: right - cornerRadius, y0: y - cornerRadius, y1: y, cx: placement === `bottomRight` ? tailX : right - cornerRadius, cy: placement === `bottomRight` ? tailY : y - cornerRadius }, type: placement === `bottomRight` ? "calloutCorner" : "corner" }, { coordinates: { x0: right - cornerRadius, x1: x + cornerRadius, y0: y, y1: y, cx: tailX, cy: tailY }, type: placement === `bottom` ? "calloutSide" : "side" }, { coordinates: { x0: x + cornerRadius, x1: x, y0: y, y1: y - cornerRadius, cx: placement === `bottomLeft` ? tailX : x + cornerRadius, cy: placement === `bottomLeft` ? tailY : y - cornerRadius }, type: placement === `bottomLeft` ? "calloutCorner" : "corner" }, { coordinates: { x0: x, x1: x, y0: y - cornerRadius, y1: top + cornerRadius, cx: tailX, cy: tailY }, type: placement === `left` ? "calloutSide" : "side" } ]; const { path } = this.shape; path.clear(); path.moveTo(x, top + cornerRadius); pathParams.forEach(({ coordinates, type }) => { this.drawPath(path, coordinates, cornerRadius, type); }); path.closePath(); } drawPath(path, { x0, y0, x1, y1, cx, cy }, cornerRadius, type) { const sideTailRadius = 6; switch (type) { case "calloutCorner": { path.lineTo(cx, cy); path.lineTo(x1, y1); break; } case "corner": { drawCorner2( path, { x0, x1, y0, y1, cx, cy }, cornerRadius, false ); break; } case "calloutSide": { if (x0 !== x1) { const direction = x0 > x1 ? -1 : 1; const midX = Math.min(x0, x1) + Math.abs(x1 - x0) / 2; path.lineTo(midX - sideTailRadius * direction, y0); path.lineTo(cx, cy); path.lineTo(midX + sideTailRadius * direction, y0); path.lineTo(x1, y1); } else { const direction = y0 > y1 ? -1 : 1; const midY = Math.min(y0, y1) + Math.abs(y0 - y1) / 2; path.lineTo(x0, midY - sideTailRadius * direction); path.lineTo(cx, cy); path.lineTo(x0, midY + sideTailRadius * direction); path.lineTo(x1, y1); } break; } case "side": default: { path.lineTo(x1, y1); break; } } } calculateCalloutPlacement(anchorPoint, bounds) { const right = bounds.x + bounds.width; const top = bounds.y - bounds.height; let xPlacement; let yPlacement; if (anchorPoint.x > right) { xPlacement = "right"; } else if (anchorPoint.x < bounds.x) { xPlacement = "left"; } if (anchorPoint.y > bounds.y) { yPlacement = "bottom"; } else if (anchorPoint.y < top) { yPlacement = "top"; } if (xPlacement && yPlacement) { return `${yPlacement}${xPlacement[0].toUpperCase()}${xPlacement.substring(1)}`; } else { return yPlacement ?? xPlacement; } } getDimensions(datum, textBBox, coords) { const { fontSize } = datum; const padding = datum.getPadding(); const horizontalPadding = padding.left + padding.right; const verticalPadding = padding.top + padding.bottom; const width2 = textBBox.width + horizontalPadding; const height2 = Math.max(textBBox.height + verticalPadding, fontSize + verticalPadding); return { tailPoint: { x: coords.x1, y: coords.y1 }, bodyBounds: { x: textBBox.x, y: textBBox.y, width: width2, height: height2 } }; } containsPoint(x, y) { const { start: start2, end: end2, shape } = this; this.activeHandle = void 0; if (start2.containsPoint(x, y)) { this.activeHandle = "start"; return true; } const bodyContainsPoint = end2.containsPoint(x, y) || shape.containsPoint(x, y); if (bodyContainsPoint) { this.activeHandle = "end"; } return bodyContainsPoint; } }; var import_ag_charts_community65 = (init_main4(), __toCommonJS(main_exports)); function guardCancelAndExit({ key }) { return key === "Escape"; } function guardSaveAndExit({ key, shiftKey }) { return !shiftKey && key === "Enter"; } var { StateMachine: StateMachine3, StateMachineProperty: StateMachineProperty3, Debug: Debug3 } = import_ag_charts_community65._ModuleSupport; var TextualStartEndStateMachine = class extends StateMachine3 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = this.createDatum(); datum.set({ start: point, end: point, visible: true }); ctx.create(datum); }; const actionFirstRender = () => { const { node } = this; node?.toggleActive(true); node?.toggleHandles({ start: true }); }; const onStartEditing = () => { ctx.showTextInput(); if (this.datum) this.datum.visible = false; }; const onStopEditing = () => { ctx.hideTextInput(); if (this.datum) this.datum.visible = true; ctx.deselect(); }; const actionUpdateTextInputBBox = (bbox) => { this.node?.setTextInputBBox(bbox); ctx.update(); }; const onEndHover = ({ point }) => { const { datum, node } = this; datum?.set({ end: point }); node?.toggleActive(true); node?.toggleHandles({ end: false }); ctx.update(); }; const onEndClick = () => { ctx.showAnnotationOptions(); this.node?.toggleHandles({ end: true }); }; const actionColor = ({ colorPickerType, colorOpacity, color, opacity, isMultiColor }) => { const { datum } = this; if (!datum) return; if (colorPickerType === "text-color") { ctx.updateTextInputColor(color); } setColor(datum, colorPickerType, colorOpacity, color, opacity, isMultiColor); ctx.update(); }; const actionFontSize = (fontSize) => { const { datum, node } = this; if (!datum || !node || !isTextType(datum)) return; datum.fontSize = fontSize; ctx.updateTextInputFontSize(fontSize); ctx.update(); }; const actionCancel = () => { ctx.delete(); }; const actionSave = ({ textInputValue, bbox }) => { const { datum } = this; if (bbox != null && textInputValue != null && textInputValue.length > 0) { if (!isTextType(datum)) { return; } const wrappedText = wrapText(datum, textInputValue, bbox.width); datum?.set({ text: wrappedText }); ctx.update(); ctx.recordAction(`Create ${datum?.type} annotation`); } else { ctx.delete(); } }; super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, dragStart: { target: "waiting-first-render", action: actionCreate }, cancel: StateMachine3.parent, reset: StateMachine3.parent }, "waiting-first-render": { render: { target: "end", action: actionFirstRender } }, end: { hover: onEndHover, drag: onEndHover, click: { target: "edit", action: onEndClick }, dragEnd: { target: "edit", action: onEndClick }, reset: { target: StateMachine3.parent, action: actionCancel }, cancel: { target: StateMachine3.parent, action: actionCancel } }, edit: { onEnter: onStartEditing, updateTextInputBBox: actionUpdateTextInputBBox, color: actionColor, fontSize: actionFontSize, textInput: [ { guard: guardCancelAndExit, target: StateMachine3.parent, action: actionCancel }, { guard: guardSaveAndExit, target: StateMachine3.parent, action: actionSave } ], click: { target: StateMachine3.parent, action: actionSave }, dragStart: { target: StateMachine3.parent, action: actionSave }, resize: { target: StateMachine3.parent, action: actionSave }, onExit: onStopEditing, cancel: { target: StateMachine3.parent, action: actionCancel } } }); this.debug = Debug3.create(true, "annotations"); } }; __decorateClass2([ StateMachineProperty3() ], TextualStartEndStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty3() ], TextualStartEndStateMachine.prototype, "node", 2); var CalloutStateMachine = class extends TextualStartEndStateMachine { createDatum() { return new CalloutProperties(); } }; var calloutConfig = { type: "callout", datum: CalloutProperties, scene: CalloutScene, isDatum: CalloutProperties.is, translate: (node, datum, transition, context) => { if (CalloutProperties.is(datum) && CalloutScene.is(node)) return node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (CalloutProperties.is(datum) && CalloutProperties.is(copiedDatum) && CalloutScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (CalloutProperties.is(datum) && CalloutScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new CalloutStateMachine({ ...ctx, create: createDatum( "callout" /* Callout */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community67 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community66 = (init_main4(), __toCommonJS(main_exports)); var TextualPointScene = class extends PointScene { constructor() { super(...arguments); this.label = new import_ag_charts_community66._ModuleSupport.Text({ zIndex: 1 }); this.anchor = { x: 0, y: 0, position: "above-left" }; } setTextInputBBox(bbox) { this.textInputBBox = bbox; this.markDirty(); } update(datum, context) { const coords = convertPoint(datum, context); const bbox = this.getTextBBox(datum, coords, context); this.updateLabel(datum, bbox); this.updateHandle(datum, coords, bbox); this.updateShape(datum, bbox); this.anchor = this.updateAnchor(datum, bbox, context); } copy(datum, copiedDatum, context) { const coords = convertPoint(datum, context); const bbox = this.getTextBBox(datum, coords, context); const padding = datum.getPadding(); const horizontalPadding = padding.left + padding.right; const verticalPadding = padding.top + padding.bottom; const xOffset = (bbox.width + horizontalPadding) / 2; const yOffset = bbox.height + verticalPadding; const point = invertCoords({ x: coords.x - xOffset, y: coords.y - yOffset }, context); copiedDatum.x = point.x; copiedDatum.y = point.y; return copiedDatum; } containsPoint(x, y) { const { label } = this; return super.containsPoint(x, y) || label.visible && label.containsPoint(x, y); } getNodeAtCoords(x, y) { if (this.label.visible && this.label.containsPoint(x, y)) return "text"; return super.getNodeAtCoords(x, y); } getTextBBox(datum, coords, _context) { const { text: text22 } = datum.getText(); return getBBox(datum, text22, { x: coords.x, y: coords.y }, this.textInputBBox); } updateLabel(datum, bbox) { const { text: text22, isPlaceholder } = datum.getText(); updateTextNode(this.label, text22, isPlaceholder, datum, this.getLabelCoords(datum, bbox)); } updateShape(_datum, _bbox) { } updateAnchor(_datum, bbox, context) { return { x: bbox.x + context.seriesRect.x, y: bbox.y + context.seriesRect.y - bbox.height, position: this.anchor.position }; } getLabelCoords(_datum, bbox) { return bbox; } getHandleCoords(_datum, _coords, bbox) { return bbox; } getHandleStyles(datum) { const styles = super.getHandleStyles(datum); styles.stroke = datum.handle.stroke ?? datum.color; return styles; } }; var { drawCorner: drawCorner22 } = import_ag_charts_community67._ModuleSupport; var CommentScene = class extends TextualPointScene { constructor() { super(); this.type = "comment"; this.shape = new import_ag_charts_community67._ModuleSupport.Path(); this.append([this.shape, this.label, this.handle]); } static is(value) { return AnnotationScene.isCheck( value, "comment" /* Comment */ ); } updateShape(datum, bbox) { const { shape } = this; shape.fill = datum.fill; shape.fillOpacity = datum.fillOpacity ?? 1; shape.stroke = datum.stroke ?? "transparent"; shape.strokeWidth = datum.strokeWidth ?? 1; shape.strokeOpacity = datum.strokeOpacity ?? 1; this.updatePath(datum, bbox); } getLabelCoords(datum, point) { const padding = datum.getPadding(); return { x: point.x + padding.left, y: point.y - padding.bottom }; } getHandleStyles(datum) { return { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke ?? datum.fill, strokeOpacity: datum.handle.strokeOpacity, strokeWidth: datum.handle.strokeWidth }; } updateAnchor(datum, bbox, context) { const anchor = super.updateAnchor(datum, bbox, context); const padding = datum.getPadding(); anchor.y -= padding.bottom + padding.top; return anchor; } updatePath(datum, bbox) { const padding = datum.getPadding(); const { x, y } = bbox; let { width: width2, height: height2 } = bbox; const { fontSize } = datum; const horizontalPadding = padding.left + padding.right; const verticalPadding = padding.top + padding.bottom; width2 = width2 + horizontalPadding; height2 = Math.max(height2 + verticalPadding, fontSize + verticalPadding); const top = y - height2; const right = x + width2; const cornerRadius = (fontSize * ANNOTATION_TEXT_LINE_HEIGHT + verticalPadding) / 2; const { path } = this.shape; path.clear(); path.moveTo(x, y); path.lineTo(x, top + cornerRadius); drawCorner22( path, { x0: x, x1: x + cornerRadius, y0: top + cornerRadius, y1: top, cx: x + cornerRadius, cy: top + cornerRadius }, cornerRadius, false ); path.lineTo(right - cornerRadius, top); drawCorner22( path, { x0: right - cornerRadius, x1: right, y0: top, y1: top + cornerRadius, cx: right - cornerRadius, cy: top + cornerRadius }, cornerRadius, false ); path.lineTo(right, y - cornerRadius); drawCorner22( path, { x0: right, x1: right - cornerRadius, y0: y - cornerRadius, y1: y, cx: right - cornerRadius, cy: y - cornerRadius }, cornerRadius, false ); path.closePath(); } containsPoint(x, y) { return super.containsPoint(x, y) || this.shape.containsPoint(x, y); } }; var import_ag_charts_community68 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine4, StateMachineProperty: StateMachineProperty4, Debug: Debug4 } = import_ag_charts_community68._ModuleSupport; var TextualPointStateMachine = class extends StateMachine4 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = this.createDatum(); datum.set({ x: point.x, y: point.y }); ctx.create(datum); }; const actionFirstRender = () => { this.node?.toggleActive(true); ctx.showAnnotationOptions(); ctx.update(); }; const onStartEditing = () => { ctx.showTextInput(); if (this.datum) { this.datum.visible = false; } }; const onStopEditing = () => { ctx.hideTextInput(); if (this.datum) this.datum.visible = true; ctx.deselect(); }; const actionUpdateTextInputBBox = (bbox) => { this.node?.setTextInputBBox(bbox); ctx.update(); }; const actionColor = ({ colorPickerType, colorOpacity, color, opacity, isMultiColor }) => { if (!this.datum) return; if (colorPickerType === "text-color") { ctx.updateTextInputColor(color); } setColor(this.datum, colorPickerType, colorOpacity, color, opacity, isMultiColor); ctx.update(); }; const actionFontSize = (fontSize) => { const { datum, node } = this; if (!datum || !node || !isTextType(datum)) return; datum.fontSize = fontSize; ctx.updateTextInputFontSize(fontSize); ctx.update(); }; const actionCancel = () => { ctx.delete(); }; const actionSave = ({ textInputValue, bbox }) => { if (bbox != null && textInputValue != null && textInputValue.length > 0) { const { datum } = this; if (!isTextType(datum)) { return; } const wrappedText = wrapText(datum, textInputValue, bbox.width); datum?.set({ text: wrappedText }); ctx.update(); ctx.recordAction(`Create ${datum?.type} annotation`); } else { ctx.delete(); } }; super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, dragStart: { target: "waiting-first-render", action: actionCreate }, cancel: StateMachine4.parent, reset: StateMachine4.parent }, "waiting-first-render": { render: { target: "edit", action: actionFirstRender } }, edit: { onEnter: onStartEditing, updateTextInputBBox: actionUpdateTextInputBBox, color: actionColor, fontSize: actionFontSize, textInput: [ { guard: guardCancelAndExit, target: StateMachine4.parent, action: actionCancel }, { guard: guardSaveAndExit, target: StateMachine4.parent, action: actionSave } ], click: { target: StateMachine4.parent, action: actionSave }, dragStart: { target: StateMachine4.parent, action: actionSave }, resize: { target: StateMachine4.parent, action: actionSave }, onExit: onStopEditing, cancel: { target: StateMachine4.parent, action: actionCancel } } }); this.debug = Debug4.create(true, "annotations"); } }; __decorateClass2([ StateMachineProperty4() ], TextualPointStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty4() ], TextualPointStateMachine.prototype, "node", 2); var CommentStateMachine = class extends TextualPointStateMachine { createDatum() { return new CommentProperties(); } }; var commentConfig = { type: "comment", datum: CommentProperties, scene: CommentScene, isDatum: CommentProperties.is, translate: (node, datum, translation, context) => { if (CommentProperties.is(datum) && CommentScene.is(node)) node.translate(datum, translation, context); }, copy: (node, datum, copiedDatum, context) => { if (CommentProperties.is(datum) && CommentProperties.is(copiedDatum) && CommentScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (CommentProperties.is(datum) && CommentScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new CommentStateMachine({ ...ctx, create: createDatum( "comment" /* Comment */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community73 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community69 = (init_main4(), __toCommonJS(main_exports)); var { calculateLabelTranslation: calculateLabelTranslation2, ChartAxisDirection: ChartAxisDirection7 } = import_ag_charts_community69._ModuleSupport; var AxisLabelScene = class extends import_ag_charts_community69._ModuleSupport.Group { constructor() { super({ name: "AnnotationAxisLabelGroup" }); this.label = new import_ag_charts_community69._ModuleSupport.Text({ zIndex: 1 }); this.rect = new import_ag_charts_community69._ModuleSupport.Rect(); const { label } = this; label.fontSize = 12; label.fontFamily = "Verdana, sans-serif"; label.fill = "black"; label.textBaseline = "middle"; label.textAlign = "center"; this.append([this.rect, this.label]); } update(opts) { this.updateLabel(opts); this.updateRect(opts); this.updatePosition(opts); } updateLabel({ value, styles, context }) { const { fontWeight, fontSize, fontStyle, fontFamily, textAlign, color = "white", formatter } = styles; const text22 = formatter ? formatter({ value }) : context.scaleValueFormatter()(value); this.label.setProperties({ fontWeight, fontSize, fontStyle, fontFamily, textAlign, fill: color, text: text22 }); } updateRect({ styles }) { const { rect } = this; const { cornerRadius, fill, fillOpacity, stroke: stroke22, strokeOpacity } = styles; rect.setProperties({ cornerRadius, fill, fillOpacity, stroke: stroke22, strokeOpacity }); } updatePosition({ x, y, context, styles: { padding } }) { const { label, rect } = this; const labelBBox = label.getBBox()?.clone(); const horizontalPadding = padding ?? 8; const verticalPadding = padding ?? 5; labelBBox.grow(horizontalPadding, "horizontal"); labelBBox.grow(verticalPadding, "vertical"); const shift = context.direction === ChartAxisDirection7.X ? Math.round(verticalPadding / 2) : horizontalPadding; const { xTranslation, yTranslation } = calculateLabelTranslation2({ yDirection: true, padding: context.labelPadding - shift, position: context.position ?? "left", bbox: labelBBox }); const translationX = x + xTranslation; const translationY = y + yTranslation; label.x = translationX; label.y = translationY; rect.y = translationY - Math.round(labelBBox.height / 2); rect.x = translationX - Math.round(labelBBox.width / 2); rect.height = labelBBox.height; rect.width = labelBBox.width; } }; AxisLabelScene.className = "AxisLabel"; var import_ag_charts_community70 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec27 } = import_ag_charts_community70._ModuleSupport; var CollidableLine = class extends import_ag_charts_community70._ModuleSupport.Line { constructor() { super(...arguments); this.growCollisionBox = 9; this.clipMask = /* @__PURE__ */ new Map(); } setProperties(styles, pickKeys) { super.setProperties(styles, pickKeys); this.updateCollisionBBox(); return this; } updateCollisionBBox() { const { growCollisionBox, strokeWidth, x1, y1, x2, y2 } = this; let height2 = strokeWidth + growCollisionBox; if (height2 % 2 === 0) height2 += 1; const topLeft = Vec27.from(x1, y1 - Math.floor(height2 / 2)); const bottomRight = Vec27.from(x2, y2); const width2 = Vec27.distance(topLeft, bottomRight); this.collisionBBox = new import_ag_charts_community70._ModuleSupport.BBox(topLeft.x, topLeft.y, width2, height2); } isPointInPath(pointX, pointY) { const { collisionBBox, x1, y1, x2, y2 } = this; if (!collisionBBox) return false; const v1 = Vec27.from(x1, y1); const v2 = Vec27.from(x2, y2); const point = Vec27.sub(Vec27.from(pointX, pointY), v1); const end2 = Vec27.sub(v2, v1); const rotated = Vec27.rotate(point, Vec27.angle(point, end2), v1); return collisionBBox.containsPoint(rotated.x, rotated.y) ?? false; } render(renderCtx) { this.applyClipMask(renderCtx.ctx); super.render(renderCtx); this.closeClipMask(renderCtx.ctx); } setClipMask(id, mask) { const cm = this.clipMask.get(id); if (import_ag_charts_community70._ModuleSupport.jsonDiff(cm, mask) != null) { this.markDirty(); } if (!mask) { this.clipMask.delete(id); } else { this.clipMask.set(id, mask); } } /** * Apply a clipping mask to the shape, this must be called before the shape calls `ctx.beginPath()`. */ applyClipMask(ctx) { const { clipMask } = this; if (clipMask.size === 0) { return; } this.clipMask.forEach((mask) => { const { x, y, radius } = mask; ctx.save(); ctx.beginPath(); ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.ellipse(x, y, radius, radius, 0, Math.PI * 2, 0, true); ctx.clip(); }); } closeClipMask(ctx) { if (this.clipMask.size === 0) { return; } ctx.restore(); } }; var import_ag_charts_community71 = (init_main4(), __toCommonJS(main_exports)); var CollidableText = class extends import_ag_charts_community71._ModuleSupport.TransformableText { constructor() { super(...arguments); this.growCollisionBox = { top: 4, right: 4, bottom: 4, left: 4 }; } isPointInPath(pointX, pointY) { const localPoint = this.fromParentPoint(pointX, pointY); const uBBox = this.computeBBoxWithoutTransforms(); if (!uBBox) return false; return uBBox.grow(this.growCollisionBox).containsPoint(localPoint.x, localPoint.y); } }; var import_ag_charts_community72 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec28 } = import_ag_charts_community72._ModuleSupport; function updateLineText(id, line, coords, textProperties, textNode, text22, lineWidth) { if (!text22 || !textNode || !textProperties) { line.setClipMask(id); return; } const { alignment, position } = textProperties; const numbers = getNumbers(coords, textProperties.fontSize, lineWidth); const { point, textBaseline } = positionAndAlignment(numbers, position, alignment); setProperties(textNode, text22, textProperties, point, numbers.angle, textBaseline); const { x, y, width: width2, height: height2 } = textNode.getBBox(); const diameter = Vec28.length(Vec28.from(width2, height2)); const clipMask = { x: x + width2 / 2, y: y + height2 / 2, radius: diameter / 2 + Vec28.length(numbers.offset) }; if (position === "center") { line.setClipMask(id, clipMask); } else { line.setClipMask(id); } return { clipMask, numbers }; } function updateChannelText(offsetInsideTextLabel, top, bottom, textProperties, lineWidth, textNode, text22) { if (!text22 || !textNode) return; const { alignment, position } = textProperties; const [actualTop, actualBottom] = top.y1 <= bottom.y1 ? [top, bottom] : [bottom, top]; let relativeLine = actualTop; if (position === "bottom") { relativeLine = actualBottom; } else if (position === "inside") { relativeLine = { x1: (actualTop.x1 + actualBottom.x1) / 2, y1: (actualTop.y1 + actualBottom.y1) / 2, x2: (actualTop.x2 + actualBottom.x2) / 2, y2: (actualTop.y2 + actualBottom.y2) / 2 }; } const numbers = getNumbers(relativeLine, textProperties.fontSize, lineWidth); const { point, textBaseline } = positionAndAlignment( numbers, position === "inside" ? "center" : position, alignment, offsetInsideTextLabel ); setProperties(textNode, text22, textProperties, point, numbers.angle, textBaseline); } function getNumbers(coords, fontSize, strokeWidth) { let [left, right] = Vec28.from(coords); if (left.x > right.x) [left, right] = [right, left]; const normal = Vec28.normalized(Vec28.sub(right, left)); const angle2 = Vec28.angle(normal); const inset = Vec28.multiply(normal, DivariantHandle.HANDLE_SIZE / 2 + (fontSize ?? 14) / 2); const offset4 = Vec28.multiply(normal, (strokeWidth ?? 2) / 2 + (fontSize ?? 14) / 3); return { left, right, normal, angle: angle2, inset, offset: offset4 }; } function positionAndAlignment({ left, right, normal, angle: angle2, inset, offset: offset4 }, position, alignment, offsetInsideTextLabel) { let point; if (alignment === "right") { point = Vec28.sub(right, inset); } else if (alignment === "center") { point = Vec28.add(left, Vec28.multiply(normal, Vec28.distance(left, right) / 2)); } else { point = Vec28.add(left, inset); } let textBaseline = "bottom"; if (position === "bottom") { point = Vec28.rotate(offset4, angle2 + Math.PI / 2, point); textBaseline = "top"; } else if (position === "center" && !offsetInsideTextLabel) { textBaseline = "middle"; } else { point = Vec28.rotate(offset4, angle2 - Math.PI / 2, point); } return { point, textBaseline }; } function setProperties(scene, text22, textProperties, point, angle2, textBaseline) { scene.setProperties({ text: text22, x: point.x, y: point.y, rotation: angle2, rotationCenterX: point.x, rotationCenterY: point.y, fill: textProperties.color, fontFamily: textProperties.fontFamily, fontSize: textProperties.fontSize, fontStyle: textProperties.fontStyle, fontWeight: textProperties.fontWeight, textAlign: textProperties.alignment, textBaseline }); } var { ChartAxisDirection: ChartAxisDirection8, Vec2: Vec29, Vec4: Vec44 } = import_ag_charts_community73._ModuleSupport; var CrossLineScene = class extends AnnotationScene { constructor() { super(); this.type = "cross-line"; this.line = new CollidableLine(); this.middle = new UnivariantHandle(); this.isHorizontal = false; this.append([this.line, this.middle]); } static is(value) { return AnnotationScene.isCheck(value, "cross-line"); } update(datum, context) { const { seriesRect } = context; this.seriesRect = seriesRect; this.isHorizontal = HorizontalLineProperties.is(datum); const axisContext = this.isHorizontal ? context.yAxis : context.xAxis; const coords = this.convertCrossLine(datum, axisContext); if (coords == null) { this.visible = false; return; } this.visible = datum.visible ?? true; if (!this.visible) return; this.updateLine(datum, coords); this.updateHandle(datum, coords); this.updateText(datum, coords); this.updateAxisLabel(datum, axisContext, coords); } updateLine(datum, coords) { const { line } = this; const { lineDashOffset, stroke: stroke22, strokeWidth, strokeOpacity } = datum; const { x1, y1, x2, y2 } = coords; line.setProperties({ x1, y1, x2, y2, lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke22, strokeWidth, strokeOpacity, fillOpacity: 0 }); } updateHandle(datum, coords) { const { middle } = this; const { locked, stroke: stroke22, strokeWidth, strokeOpacity } = datum; const handleStyles = { fill: datum.handle.fill, stroke: datum.handle.stroke ?? stroke22, strokeOpacity: datum.handle.strokeOpacity ?? strokeOpacity, strokeWidth: datum.handle.strokeWidth ?? strokeWidth }; const handlePosition = Vec29.sub( Vec44.center(coords), Vec29.from(middle.handle.width / 2, middle.handle.height / 2) ); middle.gradient = this.isHorizontal ? "horizontal" : "vertical"; middle.update({ ...handleStyles, ...handlePosition }); middle.toggleLocked(locked ?? false); } updateText(datum, coords) { this.text = this.updateNode(CollidableText, this.text, !!datum.text.label); updateLineText(this.line.id, this.line, coords, datum.text, this.text, datum.text.label, datum.strokeWidth); } createAxisLabel(context) { const axisLabel22 = new AxisLabelScene(); context.attachLabel(axisLabel22); return axisLabel22; } updateAxisLabel(datum, axisContext, coords) { if (!this.axisLabel) { this.axisLabel = this.createAxisLabel(axisContext); } const { axisLabel: axisLabel22, seriesRect } = this; const { direction, position } = axisContext; if (datum.axisLabel.enabled) { axisLabel22.visible = this.visible; const labelCorner = position === "left" || position === "top" ? Vec44.start(coords) : Vec44.end(coords); const labelPosition = direction === ChartAxisDirection8.X ? labelCorner.x : labelCorner.y; if (!axisContext.inRange(labelPosition)) { axisLabel22.visible = false; return; } const { value } = getGroupingValue(datum.value); axisLabel22.update({ ...Vec29.add(labelCorner, Vec29.required(seriesRect)), value, styles: datum.axisLabel, context: axisContext }); } else { axisLabel22.visible = false; } } setAxisLabelOpacity(opacity) { if (!this.axisLabel) return; this.axisLabel.opacity = opacity; } setAxisLabelVisible(visible) { if (!this.axisLabel) return; this.axisLabel.visible = visible; } toggleHandles(show) { this.middle.visible = show; this.middle.toggleHovered(this.activeHandle === "middle"); } destroy() { super.destroy(); this.axisLabel?.destroy(); } toggleActive(active) { this.toggleHandles(active); this.middle.toggleActive(active); } dragStart(datum, target, context) { const middle = HorizontalLineProperties.is(datum) ? { x: target.x, y: convert(datum.value, context.yAxis) } : { x: convert(datum.value, context.xAxis), y: target.y }; this.dragState = { offset: target, middle }; } drag(datum, target, context) { const { activeHandle, dragState } = this; if (datum.locked) return; let coords; if (activeHandle) { this[activeHandle].toggleDragging(true); coords = this[activeHandle].drag(target).point; } else if (dragState) { coords = Vec29.add(dragState.middle, Vec29.sub(target, dragState.offset)); } else { return; } const point = invertCoords(coords, context); const isHorizontal = HorizontalLineProperties.is(datum); datum.set({ value: isHorizontal ? point.y : point.x }); } translate(datum, { x, y }, context) { if (datum.locked) return; const { axisContext, translation } = HorizontalLineProperties.is(datum) ? { axisContext: context.yAxis, translation: y } : { axisContext: context.xAxis, translation: x }; const translated = convert(datum.value, axisContext) + translation; const value = invert(translated, axisContext); if (!isNaN(value)) datum.set({ value }); } stopDragging() { this.middle.toggleDragging(false); } copy(datum, copiedDatum, context) { const isHorizontal = HorizontalLineProperties.is(datum); const axisContext = this.isHorizontal ? context.yAxis : context.xAxis; const coords = this.convertCrossLine(datum, axisContext); if (!coords) { return; } const yOffset = isHorizontal ? -30 : 0; const xOffset = isHorizontal ? 0 : -30; const point = invertCoords({ x: coords.x1 + xOffset, y: coords.y1 + yOffset }, context); copiedDatum.set({ value: isHorizontal ? point.y : point.x }); return copiedDatum; } getCursor() { if (this.activeHandle == null) return "pointer"; return this[this.activeHandle].getCursor(); } containsPoint(x, y) { const { middle, line, text: text22 } = this; this.activeHandle = void 0; if (middle.containsPoint(x, y)) { this.activeHandle = "middle"; return true; } return line.isPointInPath(x, y) || Boolean(text22?.containsPoint(x, y)); } getNodeAtCoords(x, y) { if (this.text?.containsPoint(x, y)) return "text"; if (this.line.isPointInPath(x, y)) return "line"; if (this.middle.containsPoint(x, y)) return "handle"; } getAnchor() { const bbox = this.computeBBoxWithoutHandles(); if (this.isHorizontal) { return { x: bbox.x + bbox.width / 2, y: bbox.y }; } return { x: bbox.x + bbox.width, y: bbox.y + bbox.height / 2, position: "right" }; } convertCrossLine(datum, context) { if (datum.value == null) return; let x1 = 0; let y1 = 0; let x2, y2; const { bounds } = context; const scaledValue = convert(datum.value, context); if (HorizontalLineProperties.is(datum)) { x2 = bounds.width; y1 = scaledValue; y2 = scaledValue; } else { x1 = scaledValue; x2 = scaledValue; y2 = bounds.height; } return { x1, y1, x2, y2 }; } }; var import_ag_charts_community74 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine5, StateMachineProperty: StateMachineProperty5, Debug: Debug5 } = import_ag_charts_community74._ModuleSupport; var CrossLineStateMachine = class extends StateMachine5 { constructor(direction, ctx) { const onClick = ({ point }) => { const isHorizontal = direction === "horizontal"; const datum = isHorizontal ? new HorizontalLineProperties() : new VerticalLineProperties(); datum.set({ value: isHorizontal ? point.y : point.x }); ctx.create(datum); ctx.recordAction( `Create ${isHorizontal ? "horizontal-line" : "vertical-line"} annotation` ); }; const actionFirstRender = () => { this.node?.toggleActive(true); ctx.showAnnotationOptions(); ctx.update(); }; super("start", { start: { click: { target: "waiting-first-render", action: onClick }, drag: { target: "waiting-first-render", action: onClick }, reset: StateMachine5.parent, cancel: StateMachine5.parent }, "waiting-first-render": { render: { target: StateMachine5.parent, action: actionFirstRender } } }); this.debug = Debug5.create(true, "annotations"); } }; __decorateClass2([ StateMachineProperty5() ], CrossLineStateMachine.prototype, "node", 2); var horizontalLineConfig = { type: "horizontal-line", datum: HorizontalLineProperties, scene: CrossLineScene, isDatum: HorizontalLineProperties.is, translate: (node, datum, translation, context) => { if (HorizontalLineProperties.is(datum) && CrossLineScene.is(node)) node.translate(datum, translation, context); }, copy: (node, datum, copiedDatum, context) => { if (HorizontalLineProperties.is(datum) && HorizontalLineProperties.is(copiedDatum) && CrossLineScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (HorizontalLineProperties.is(datum) && CrossLineScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new CrossLineStateMachine("horizontal", { ...ctx, create: createDatum( "horizontal-line" /* HorizontalLine */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var verticalLineConfig = { type: "vertical-line", datum: VerticalLineProperties, scene: CrossLineScene, isDatum: VerticalLineProperties.is, translate: (node, datum, translation, context) => { if (VerticalLineProperties.is(datum) && CrossLineScene.is(node)) node.translate(datum, translation, context); }, copy: (node, datum, copiedDatum, context) => { if (VerticalLineProperties.is(datum) && VerticalLineProperties.is(copiedDatum) && CrossLineScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (VerticalLineProperties.is(datum) && CrossLineScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new CrossLineStateMachine("vertical", { ...ctx, create: createDatum( "vertical-line" /* VerticalLine */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community77 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community76 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community75 = (init_main4(), __toCommonJS(main_exports)); var { Vec4: Vec45 } = import_ag_charts_community75._ModuleSupport; var WithBackgroundScene = class { static updateBackground(datum, top, bottom, context) { const { background } = this; const { seriesRect } = context; background.path.clear(true); const bounds = Vec45.from(0, 0, seriesRect.width, seriesRect.height); const points = this.getBackgroundPoints(datum, top, bottom, bounds); for (let i = 0; i < points.length; i++) { const point = points[i]; if (i === 0) { background.path.moveTo(point.x, point.y); } else { background.path.lineTo(point.x, point.y); } } background.path.closePath(); background.checkPathDirty(); const backgroundStyles = this.getBackgroundStyles?.(datum) ?? datum.background; background.setProperties({ fill: backgroundStyles.fill, fillOpacity: backgroundStyles.fillOpacity }); } }; var ChannelScene = class extends LinearScene { constructor() { super(...arguments); this.handles = {}; this.topLine = new CollidableLine(); this.bottomLine = new CollidableLine(); this.background = new import_ag_charts_community76._ModuleSupport.Path({ zIndex: -1 }); this.anchor = { x: 0, y: 0 }; this.updateBackground = WithBackgroundScene.updateBackground.bind(this); } update(datum, context) { const { locked, visible } = datum; const top = convertLine(datum, context); const bottom = convertLine(datum.bottom, context); if (top == null || bottom == null) { this.visible = false; return; } else { this.visible = visible ?? true; } const topLine = this.extendLine(top, datum, context); const bottomLine = this.extendLine(bottom, datum, context); this.updateLines(datum, topLine, bottomLine, context, top, bottom); this.updateHandles(datum, top, bottom); this.updateText(datum, top, bottom); this.updateBackground(datum, topLine, bottomLine, context); this.updateAnchor(top, bottom); for (const handle22 of Object.values(this.handles)) { handle22.toggleLocked(locked ?? false); } } snapToAngle(target, context, handle22, originHandle, angle2, direction) { const { handles } = this; const fixed = handles[originHandle].handle; const active = handles[handle22].drag(target).point; return invertCoords(snapToAngle(active, fixed, angle2, direction), context); } toggleHandles(show) { const { handles } = this; if (typeof show === "boolean") { for (const [handle22, node] of Object.entries(handles)) { node.visible = show; node.toggleHovered(this.activeHandle === handle22); } return; } for (const [handle22, visible] of Object.entries(show)) { const node = handles[handle22]; node.visible = visible ?? true; node.toggleHovered(this.activeHandle === handle22); } } toggleActive(active) { this.toggleHandles(active); for (const node of Object.values(this.handles)) { node.toggleActive(active); } } stopDragging() { const { activeHandle, handles } = this; if (activeHandle == null) return; handles[activeHandle].toggleDragging(false); } getAnchor() { return this.anchor; } getCursor() { if (this.activeHandle == null) return "pointer"; return this.handles[this.activeHandle].getCursor(); } containsPoint(x, y) { const { handles, topLine, bottomLine, text: text22 } = this; this.activeHandle = void 0; for (const [handle22, child] of Object.entries(handles)) { if (child.containsPoint(x, y)) { this.activeHandle = handle22; return true; } } return topLine.containsPoint(x, y) || bottomLine.containsPoint(x, y) || Boolean(text22?.containsPoint(x, y)); } getNodeAtCoords(x, y) { if (this.text?.containsPoint(x, y)) return "text"; if (this.topLine.containsPoint(x, y) || this.bottomLine.containsPoint(x, y)) return "line"; for (const [_, child] of Object.entries(this.handles)) { if (child.containsPoint(x, y)) return "handle"; } } updateAnchor(top, bottom) { const { x, y } = import_ag_charts_community76._ModuleSupport.Transformable.toCanvasPoint( this.topLine, (top.x1 + top.x2) / 2, Math.min(top.y1, top.y2, bottom.y1, bottom.y2) ); this.anchor.x = x; this.anchor.y = y; } }; var { Vec2: Vec210, Vec4: Vec46 } = import_ag_charts_community77._ModuleSupport; var DisjointChannelScene = class extends ChannelScene { constructor() { super(); this.type = "disjoint-channel"; this.ignoreYBounds = true; this.handles = { topLeft: new DivariantHandle(), topRight: new DivariantHandle(), bottomLeft: new DivariantHandle(), bottomRight: new UnivariantHandle() }; this.append([this.background, this.topLine, this.bottomLine, ...Object.values(this.handles)]); } static is(value) { return AnnotationScene.isCheck(value, "disjoint-channel"); } dragHandle(datum, target, context, snapping) { const { activeHandle, handles } = this; if (activeHandle == null) return; const { offset: offset4 } = handles[activeHandle].drag(target); handles[activeHandle].toggleDragging(true); const invert2 = (coords) => invertCoords(coords, context); const prev = datum.toJson(); const angle2 = datum.snapToAngle; const { value: endY } = getGroupingValue(datum.end.y); const { value: startY } = getGroupingValue(datum.start.y); switch (activeHandle) { case "topLeft": case "bottomLeft": { const direction = activeHandle === "topLeft" ? 1 : -1; const start2 = snapping ? this.snapToAngle(target, context, "topLeft", "topRight", angle2, direction) : invert2({ x: handles.topLeft.handle.x + offset4.x, y: handles.topLeft.handle.y + offset4.y * direction }); const bottomStart = snapping ? this.snapToAngle(target, context, "bottomLeft", "bottomRight", angle2, -direction) : invert2({ x: handles.bottomLeft.handle.x + offset4.x, y: handles.bottomLeft.handle.y + offset4.y * -direction }); if (start2?.y == null || bottomStart?.y == null || startY == null || !isNumber2(startY)) return; const startHeight = datum.startHeight + (start2.y - startY) * 2; datum.start.x = start2.x; datum.start.y = start2.y; datum.startHeight = startHeight; break; } case "topRight": { const end2 = snapping ? this.snapToAngle(target, context, "topRight", "topLeft", angle2) : invert2({ x: handles.topRight.handle.x + offset4.x, y: handles.topRight.handle.y + offset4.y }); if (end2?.y == null || endY == null || !isNumber2(endY)) return; const endHeight = datum.endHeight + (end2.y - endY) * 2; datum.end.x = end2.x; datum.end.y = end2.y; datum.endHeight = endHeight; break; } case "bottomRight": { const bottomStart = invert2({ x: handles.bottomLeft.handle.x + offset4.x, y: handles.bottomLeft.handle.y + offset4.y }); const bottomEnd = invert2({ x: handles.bottomRight.handle.x + offset4.x, y: handles.bottomRight.handle.y + offset4.y }); if (!bottomStart || !bottomEnd || datum.start.y == null || endY == null || !isNumber2(endY)) return; const endHeight = endY - bottomEnd.y; const startHeight = datum.startHeight - (datum.endHeight - endHeight); datum.startHeight = startHeight; datum.endHeight = endHeight; } } if (!datum.isValidWithContext(context)) { datum.set(prev); } } updateLines(datum, top, bottom) { const { topLine, bottomLine } = this; const { lineDashOffset, stroke: stroke22, strokeOpacity, strokeWidth } = datum; const lineStyles = { lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke22, strokeOpacity, strokeWidth }; topLine.setProperties({ ...top, ...lineStyles }); bottomLine.setProperties({ ...bottom, ...lineStyles }); } updateHandles(datum, top, bottom) { const { handles: { topLeft, topRight, bottomLeft, bottomRight } } = this; const handleStyles = { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke, strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity, strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth }; topLeft.update({ ...handleStyles, ...Vec46.start(top) }); topRight.update({ ...handleStyles, ...Vec46.end(top) }); bottomLeft.update({ ...handleStyles, ...Vec46.start(bottom) }); bottomRight.update({ ...handleStyles, ...Vec210.sub(Vec46.end(bottom), Vec210.from(bottomRight.handle.width / 2, bottomRight.handle.height / 2)) }); } updateText(datum, top, bottom) { this.text = this.updateNode(CollidableText, this.text, !!datum.text.label); updateChannelText(false, top, bottom, datum.text, datum.strokeWidth, this.text, datum.text.label); } getBackgroundPoints(datum, top, bottom, bounds) { const isFlippedX = top.x1 > top.x2; const isFlippedY = top.y1 > top.y2; const topY = isFlippedY ? bounds.y2 : bounds.y1; const bottomY = isFlippedY ? bounds.y1 : bounds.y2; const points = Vec210.from(top); if (datum.extendEnd && top.y2 === bottomY) { points.push(Vec210.from(isFlippedX ? bounds.x1 : bounds.x2, isFlippedY ? bounds.y1 : bounds.y2)); } if (datum.extendEnd && bottom.y2 === topY) { points.push(Vec210.from(isFlippedX ? bounds.x1 : bounds.x2, isFlippedY ? bounds.y2 : bounds.y1)); } points.push(...Vec210.from(bottom).reverse()); if (datum.extendStart && bottom.y1 === bottomY) { points.push(Vec210.from(isFlippedX ? bounds.x2 : bounds.x1, isFlippedY ? bounds.y1 : bounds.y2)); } if (datum.extendStart && top.y1 === topY) { points.push(Vec210.from(isFlippedX ? bounds.x2 : bounds.x1, isFlippedY ? bounds.y2 : bounds.y1)); } return points; } }; var import_ag_charts_community78 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine6, StateMachineProperty: StateMachineProperty6, Debug: Debug6 } = import_ag_charts_community78._ModuleSupport; var DisjointChannelStateMachine = class extends StateMachine6 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = new DisjointChannelProperties(); datum.set({ start: point, end: point, startHeight: 0, endHeight: 0 }); ctx.create(datum); }; const actionFirstRender = () => { const { node } = this; node?.toggleActive(true); node?.toggleHandles({ topLeft: true, topRight: false, bottomLeft: false, bottomRight: false }); }; const actionEndUpdate = ({ offset: offset4, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset4, context, snapping, datum.start, datum.snapToAngle) }); ctx.update(); }; const actionEndFinish = () => { this.node?.toggleHandles({ topRight: true }); ctx.update(); }; const actionHeightUpdate = ({ point }) => { const { datum, node } = this; const { value: endY } = getGroupingValue(datum?.end.y); const { value: startY } = getGroupingValue(datum?.start.y); const { y: pointY } = point; if (datum == null || !isNumber2(startY) || !isNumber2(endY) || !isNumber2(pointY)) return; const endHeight = endY - (pointY ?? 0); const startHeight = (startY - endY) * 2 + endHeight; const bottomStart = { x: datum?.start.x, y: startY - startHeight }; const bottomEnd = { x: datum?.end.x, y: point.y }; node?.toggleHandles({ bottomLeft: true, bottomRight: true }); if (!ctx.validatePoint(bottomStart) || !ctx.validatePoint(bottomEnd)) { return; } datum.set({ startHeight, endHeight }); ctx.update(); }; const actionHeightFinish = ({ point }) => { const { datum, node } = this; const { value: endY } = getGroupingValue(datum?.end.y); const { value: startY } = getGroupingValue(datum?.start.y); const { y: pointY } = point; if (datum == null || !isNumber2(startY) || !isNumber2(endY) || !isNumber2(pointY)) return; const endHeight = endY - (pointY ?? 0); const startHeight = (startY - endY) * 2 + endHeight; const bottomStart = { x: datum.start.x, y: startY - endHeight }; const bottomEnd = { x: datum.end.x, y: point.y }; node?.toggleHandles(true); if (!ctx.validatePoint(bottomStart) || !ctx.validatePoint(bottomEnd)) { return; } datum.set({ startHeight, endHeight }); ctx.recordAction(`Create ${"disjoint-channel"} annotation`); ctx.showAnnotationOptions(); ctx.update(); }; const actionCancel = () => ctx.delete(); super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, drag: { target: "waiting-first-render", action: actionCreate }, reset: StateMachine6.parent }, "waiting-first-render": { render: { target: "end", action: actionFirstRender } }, end: { hover: actionEndUpdate, drag: actionEndUpdate, click: { target: "height", action: actionEndFinish }, dragEnd: { target: "height", action: actionEndFinish }, reset: { target: StateMachine6.parent, action: actionCancel }, cancel: { target: StateMachine6.parent, action: actionCancel } }, height: { hover: actionHeightUpdate, click: { target: StateMachine6.parent, action: actionHeightFinish }, drag: { target: StateMachine6.parent, action: actionHeightFinish }, reset: { target: StateMachine6.parent, action: actionCancel }, cancel: { target: StateMachine6.parent, action: actionCancel } } }); this.debug = Debug6.create(true, "annotations"); this.snapping = false; } }; __decorateClass2([ StateMachineProperty6() ], DisjointChannelStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty6() ], DisjointChannelStateMachine.prototype, "node", 2); __decorateClass2([ StateMachineProperty6() ], DisjointChannelStateMachine.prototype, "snapping", 2); var disjointChannelConfig = { type: "disjoint-channel", datum: DisjointChannelProperties, scene: DisjointChannelScene, isDatum: DisjointChannelProperties.is, translate: (node, datum, transition, context) => { if (DisjointChannelProperties.is(datum) && DisjointChannelScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (DisjointChannelProperties.is(datum) && DisjointChannelProperties.is(copiedDatum) && DisjointChannelScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (DisjointChannelProperties.is(datum) && DisjointChannelScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new DisjointChannelStateMachine({ ...ctx, create: createDatum( "disjoint-channel" /* DisjointChannel */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community80 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community79 = (init_main4(), __toCommonJS(main_exports)); var FIBONACCI_RETRACEMENT_RATIOS = [0, 23.6, 38.2, 50, 61.8, 78.6, 100]; var FIBONACCI_EXTENSION_RATIOS = [161.8, 261.8, 361.8, 423.6]; var FIBONACCI_RATIOS = [...FIBONACCI_RETRACEMENT_RATIOS, ...FIBONACCI_EXTENSION_RATIOS]; var FIBONACCI_RATIOS_MAP = { 10: FIBONACCI_RATIOS, 6: FIBONACCI_RETRACEMENT_RATIOS, 4: FIBONACCI_RETRACEMENT_RATIOS.filter((r) => r !== 78.6 && r !== 23.6) }; var FIBONACCI_RANGE_LABEL_PADDING = 10; function getFibonacciCoords(coords1, coords2) { const { x2, y1, y2 } = coords1; const trendLineVerticalDistance = y1 - y2; if (coords2 == null) { return { x1: x2, x2, y1: y2 - trendLineVerticalDistance, y2 }; } return { x1: coords2.x1, x2: coords2.x2, y1: coords2.y2 - trendLineVerticalDistance, y2: coords2.y2 }; } function createFibonacciRangesData({ x1, y1, x2, y2 }, context, reverse, yZero, bands = 10) { const verticalDistance = y1 - y2; const direction = reverse ? -1 : 1; let startY = yZero; const data = []; FIBONACCI_RATIOS_MAP[bands].forEach((ratio2, index) => { const endY = yZero + verticalDistance * (ratio2 / 100) * direction; const yDatumVal = context.yAxis.scaleInvert(endY); data.push({ id: index, x1, x2, y1: startY, y2: endY, tag: ratio2 == 100 ? 0 : 1, label: { x1: Math.min(x1, x2) - FIBONACCI_RANGE_LABEL_PADDING, x2, y1: endY, y2: endY, text: `${(ratio2 / 100).toFixed(3)} (${yDatumVal.toFixed(2)})` } }); startY = endY; }); return data; } var { Vec2: Vec211, Vec4: Vec47 } = import_ag_charts_community79._ModuleSupport; var FibonacciScene = class extends AnnotationScene { constructor() { super(); this.trendLine = new CollidableLine(); this.rangeFillsGroup = new import_ag_charts_community79._ModuleSupport.Group({ name: `${this.id}-range-fills` }); this.rangeFillsGroupSelection = import_ag_charts_community79._ModuleSupport.Selection.select(this.rangeFillsGroup, import_ag_charts_community79._ModuleSupport.Range); this.rangeStrokesGroup = new import_ag_charts_community79._ModuleSupport.Group({ name: `${this.id}-range-strokes` }); this.rangeStrokesGroupSelection = import_ag_charts_community79._ModuleSupport.Selection.select(this.rangeStrokesGroup, CollidableLine); this.labelsGroup = new import_ag_charts_community79._ModuleSupport.Group({ name: `${this.id}-ranges-labels` }); this.labelsGroupSelection = import_ag_charts_community79._ModuleSupport.Selection.select(this.labelsGroup, CollidableText); this.anchor = { x: 0, y: 0, position: "above" }; this.append([this.trendLine, this.rangeFillsGroup, this.rangeStrokesGroup, this.labelsGroup]); } update(datum, context) { let coords = convertLine(datum, context); if (coords == null) { this.visible = false; return; } coords = Vec47.round(coords); this.visible = datum.visible ?? true; if (!this.visible) return; this.updateLine(datum, coords, this.trendLine); this.updateHandles(datum, coords); this.updateAnchor(datum, coords, context); const { reverse } = datum; const extendedCoords = this.extendLine(coords, datum, context); const yZero = reverse ? extendedCoords.y1 : extendedCoords.y2; const yOne = reverse ? extendedCoords.y2 : extendedCoords.y1; const data = createFibonacciRangesData(extendedCoords, context, datum.reverse, yZero, datum.bands); this.updateRanges(datum, data, context); const oneLinePoints = { ...extendedCoords, y1: yOne, y2: yOne }; this.updateText(datum, oneLinePoints); } extendLine({ x1, y1, x2, y2 }, datum, context) { const linePoints = { x1, y1, x2, y2 }; if (!datum.extendStart && !datum.extendEnd) { return linePoints; } const { x, width: width2 } = context.xAxis.bounds; if (datum.extendEnd) { linePoints[x1 > x2 ? "x1" : "x2"] = x + width2; } if (datum.extendStart) { linePoints[x1 > x2 ? "x2" : "x1"] = x; } return linePoints; } updateLine(datum, coords, line) { if (!coords || !line) { return; } const { lineDashOffset, strokeWidth, strokeOpacity, stroke: stroke22 } = datum; line.setProperties({ ...coords, lineCap: datum.getLineCap(), lineDash: [3, 4], lineDashOffset, strokeWidth, strokeOpacity, fillOpacity: 0, stroke: stroke22 }); } updateRangeStrokes(datum) { const { lineDashOffset, strokeWidth, strokeOpacity, strokes, rangeStroke, isMultiColor } = datum; this.rangeStrokesGroupSelection.each((line, { x1, x2, y2, tag }, index) => { const y = y2; const color = isMultiColor ? strokes[index % strokes.length] : rangeStroke; line.setProperties({ x1, x2, y1: y, y2: y, stroke: color, strokeOpacity, strokeWidth, lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, tag }); }); } updateRanges(datum, data, context) { const getDatumId = (d) => d.id; this.rangeFillsGroupSelection.update(data, void 0, getDatumId); this.rangeStrokesGroupSelection.update(data, void 0, getDatumId); this.labelsGroupSelection.update(data, void 0, getDatumId); this.updateRangeFills(datum); this.updateRangeStrokes(datum); this.updateRangeLabels(datum, context); } updateRangeFills(datum) { const { lineDashOffset, strokeWidth, strokeOpacity, strokes: colors, rangeStroke, showFill, isMultiColor } = datum; this.rangeFillsGroupSelection.each((range22, { x1, x2, y1, y2 }, index) => { const color = isMultiColor ? colors[index % colors.length] : rangeStroke; if (!showFill) { range22.visible = false; return; } range22.setProperties({ x1, x2, y1, y2, startLine: false, endLine: false, isRange: true, stroke: color, strokeOpacity, fill: color, fillOpacity: (strokeOpacity ?? 1) * 0.15, strokeWidth, lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, visible: true }); }); } updateRangeLabels(trendLineProperties, { xAxis }) { const { rangeStrokesGroupSelection } = this; const { strokes: colors, strokeWidth, rangeStroke, isMultiColor, label: { fontFamily, fontSize, fontStyle, fontWeight, color } } = trendLineProperties; const labelProperties = { fontFamily, fontSize, fontStyle, fontWeight }; const withinBounds = this.checkWithinBounds(xAxis, labelProperties, this.labelsGroupSelection.at(0)); this.labelsGroupSelection.each((textNode, datum, index) => { const textColor = color ?? (isMultiColor ? colors[index % colors.length] : rangeStroke); const line = rangeStrokesGroupSelection.at(index); if (!line) { return; } const { text: text22, ...coords } = datum.label; if (withinBounds) { textNode.setProperties({ ...labelProperties, text: text22, x: coords.x1, y: coords.y1, textBaseline: "middle", textAlign: "end", fill: textColor }); updateLineText(textNode.id, line, coords); } else { const textProperties = { ...labelProperties, label: text22, position: "center", alignment: "left", color: textColor }; updateLineText(textNode.id, line, coords, textProperties, textNode, text22, strokeWidth); } }); } checkWithinBounds(xAxis, fontOptions, textNode) { if (!textNode) { return false; } const { text: text22, ...coords } = textNode.datum.label; textNode.setProperties({ ...fontOptions, text: text22, x: coords.x1, y: coords.y1, textBaseline: "middle", textAlign: "end" }); const { x } = textNode.getBBox(); return x >= xAxis.bounds.x && x <= xAxis.bounds.x + xAxis.bounds.width; } updateText(datum, coords) { const oneLine = this.rangeStrokesGroupSelection.selectByTag( 0 /* OneLine */ )[0]; if (!oneLine) { return; } const { text: textProperties, strokeWidth } = datum; this.text = this.updateNode(CollidableText, this.text, !!textProperties.label); updateLineText(oneLine.id, oneLine, coords, textProperties, this.text, textProperties.label, strokeWidth); } updateAnchor(_datum, coords, _context, _bbox) { const point = Vec47.topCenter(coords); Vec211.apply(this.anchor, import_ag_charts_community79._ModuleSupport.Transformable.toCanvasPoint(this.trendLine, point.x, point.y)); } containsPoint(x, y) { const { trendLine, rangeStrokesGroupSelection, text: text22 } = this; let isInStrokePath = false; rangeStrokesGroupSelection.each((line) => isInStrokePath || (isInStrokePath = line.isPointInPath(x, y))); return isInStrokePath || trendLine.isPointInPath(x, y) || Boolean(text22?.containsPoint(x, y)); } getNodeAtCoords(x, y) { if (this.text?.containsPoint(x, y)) return "text"; if (this.trendLine.isPointInPath(x, y)) return "line"; } getHandleStyles(datum) { return { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke, strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity, strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth }; } drag(datum, target, context, snapping) { if (datum.locked) return; if (this.activeHandle) { this.dragHandle(datum, target, context, snapping); } else { this.dragAll(datum, target, context); } } getAnchor() { return this.anchor; } getCursor() { return "pointer"; } }; var { Vec2: Vec212, Vec4: Vec48 } = import_ag_charts_community80._ModuleSupport; var FibonacciRetracementTrendBasedScene = class extends FibonacciScene { constructor() { super(); this.type = "fibonacci-retracement-trend-based"; this.endRetracementLine = new CollidableLine(); this.start = new DivariantHandle(); this.end = new DivariantHandle(); this.endRetracement = new DivariantHandle(); this.append([this.endRetracementLine, this.start, this.end, this.endRetracement]); } static is(value) { return AnnotationScene.isCheck(value, "fibonacci-retracement-trend-based"); } update(datum, context) { let { coords1, coords2 } = this.getCoords(datum, context); if (coords1 == null || coords2 == null) { this.visible = false; return; } coords1 = Vec48.round(coords1); coords2 = Vec48.round(coords2); this.visible = datum.visible ?? true; if (!this.visible) return; if (datum.endRetracement.x == void 0 || datum.endRetracement.y == void 0) { coords2 = void 0; } this.updateLine(datum, coords1, this.trendLine); this.updateLine(datum, coords2, this.endRetracementLine); this.updateHandles(datum, coords1, coords2); this.updateAnchor(datum, coords2 ?? coords1, context); const { reverse, bands } = datum; const coords = getFibonacciCoords(coords1, coords2); const extendedCoords = this.extendLine(coords, datum, context); const yZero = extendedCoords.y2; const yOne = extendedCoords.y1; const data = !coords2 ? [] : createFibonacciRangesData(extendedCoords, context, reverse, yZero, bands); this.updateRanges(datum, data, context); const oneLinePoints = { ...extendedCoords, y1: yOne, y2: yOne }; this.updateText(datum, oneLinePoints); } containsPoint(x, y) { const { start: start2, end: end2, endRetracement, endRetracementLine } = this; this.activeHandle = void 0; if (start2.containsPoint(x, y)) { this.activeHandle = "start"; return true; } if (end2.containsPoint(x, y)) { this.activeHandle = "end"; return true; } if (endRetracement.containsPoint(x, y)) { this.activeHandle = "endRetracement"; return true; } return endRetracementLine.isPointInPath(x, y) || super.containsPoint(x, y); } getNodeAtCoords(x, y) { if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y) || this.endRetracement.containsPoint(x, y)) return "handle"; if (this.endRetracementLine.isPointInPath(x, y)) return "line"; return super.getNodeAtCoords(x, y); } dragStart(datum, target, context) { this.dragState = { offset: target, ...getDragStartState({ start: datum.start, end: datum.end, endRetracement: datum.endRetracement }, context) }; } stopDragging() { this.start.toggleDragging(false); this.end.toggleDragging(false); this.endRetracement.toggleDragging(false); } dragAll(datum, target, context) { const { dragState } = this; if (!dragState) return; this.translatePoints({ datum, start: dragState.start, end: dragState.end, endRetracement: dragState.endRetracement, translation: Vec212.sub(target, dragState.offset), context }); } dragHandle(datum, target, context, snapping) { const { activeHandle, dragState } = this; if (!activeHandle || !dragState) return; this[activeHandle].toggleDragging(true); const point = snapping ? this.snapToAngle(datum, target, context) : invertCoords(this[activeHandle].drag(target).point, context); if (!point || !validateDatumPoint(context, point)) return; datum[activeHandle].x = point.x; datum[activeHandle].y = point.y; } snapToAngle(datum, coords, context) { const { activeHandle } = this; const handles = ["start", "end", "endRetracement"]; if (!activeHandle) return; const index = (handles.indexOf(activeHandle) + 1) % handles.length; const fixedHandle = handles[index]; this[activeHandle].toggleDragging(true); const fixed = convertPoint(datum[fixedHandle], context); return invertCoords(snapToAngle(coords, fixed, datum.snapToAngle), context); } translatePoints({ datum, start: start2, end: end2, endRetracement, translation, context }) { const { vectors, translateX, translateY } = translate( { start: start2, end: end2, endRetracement }, translation, context ); if (translateX) { datum.start.x = vectors.start?.x; datum.end.x = vectors.end?.x; datum.endRetracement.x = vectors.endRetracement?.x; } if (this.ignoreYBounds || translateY) { datum.start.y = vectors.start?.y; datum.end.y = vectors.end?.y; datum.endRetracement.y = vectors.endRetracement?.y; } } translate(datum, translation, context) { this.translatePoints({ datum, start: convertPoint(datum.start, context), end: convertPoint(datum.end, context), endRetracement: convertPoint(datum.endRetracement, context), translation, context }); } copy(datum, copiedDatum, context) { const { coords1, coords2 } = this.getCoords(datum, context); if (!coords1 || !coords2) { return; } const bbox = this.computeBBoxWithoutHandles(); this.translatePoints({ datum: copiedDatum, start: Vec48.start(coords1), end: Vec48.end(coords1), endRetracement: Vec48.end(coords2), translation: { x: -bbox.width / 2, y: -bbox.height / 2 }, context }); return copiedDatum; } getCoords(datum, context) { return { coords1: convertLine(datum, context), coords2: convertLine({ start: datum.end, end: datum.endRetracement }, context) }; } toggleHandles(show) { if (typeof show === "boolean") { this.start.visible = show; this.end.visible = show; this.endRetracement.visible = show; } else { for (const [handle22, visible] of Object.entries(show)) { this[handle22].visible = visible; } } this.start.toggleHovered(this.activeHandle === "start"); this.end.toggleHovered(this.activeHandle === "end"); this.endRetracement.toggleHovered(this.activeHandle === "endRetracement"); } toggleActive(active) { this.toggleHandles(active); this.start.toggleActive(active); this.end.toggleActive(active); this.endRetracement.toggleActive(active); } updateHandles(datum, coords1, coords2, bbox) { this.start.update({ ...this.getHandleStyles(datum), ...this.getHandleCoords(datum, coords1, "start") }); this.end.update({ ...this.getHandleStyles(datum), ...this.getHandleCoords(datum, coords1, "end", bbox) }); if (coords2) { this.endRetracement.update({ ...this.getHandleStyles(datum), ...this.getHandleCoords(datum, coords2, "endRetracement", bbox) }); } this.start.toggleLocked(datum.locked ?? false); this.end.toggleLocked(datum.locked ?? false); this.endRetracement.toggleLocked(datum.locked ?? false); } getHandleCoords(_datum, coords, handle22, _bbox) { return handle22 === "start" ? Vec48.start(coords) : Vec48.end(coords); } }; var import_ag_charts_community81 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine7, StateMachineProperty: StateMachineProperty7, Debug: Debug7 } = import_ag_charts_community81._ModuleSupport; var FibonacciRetracementTrendBasedStateMachine = class extends StateMachine7 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = this.createDatum(); datum.set({ start: point, end: point }); ctx.create(datum); }; const actionFirstRender = () => { const { node } = this; node?.toggleActive(true); node?.toggleHandles({ start: true, end: false, endRetracement: false }); }; const actionEndUpdate = ({ offset: offset4, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset4, context, snapping, datum.start, datum.snapToAngle) }); ctx.update(); }; const actionEndFinish = () => { const { datum } = this; if (!datum) return; datum.endRetracement.x = datum.end.x; datum.endRetracement.y = datum.end.y; this.node?.toggleHandles({ end: true }); ctx.update(); }; const actionEndRetracementUpdate = ({ offset: offset4, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ endRetracement: snapPoint(offset4, context, snapping, datum.end, datum.snapToAngle) }); ctx.update(); }; const actionEndRetracementFinish = () => { this.node?.toggleHandles({ endRetracement: true }); ctx.update(); }; const actionCancel = () => ctx.delete(); const onExitEnd = () => { ctx.showAnnotationOptions(); ctx.recordAction(`Create ${this.datum?.type} annotation`); }; super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, drag: { target: "waiting-first-render", action: actionCreate }, reset: StateMachine7.parent }, "waiting-first-render": { render: { target: "end", action: actionFirstRender } }, end: { hover: actionEndUpdate, click: { target: "endRetracement", action: actionEndFinish }, drag: actionEndUpdate, dragEnd: { target: "endRetracement", action: actionEndFinish }, reset: { target: StateMachine7.parent, action: actionCancel }, cancel: { target: StateMachine7.parent, action: actionCancel }, onExit: onExitEnd }, endRetracement: { hover: actionEndRetracementUpdate, click: { target: StateMachine7.parent, action: actionEndRetracementFinish }, drag: { target: StateMachine7.parent, action: actionEndRetracementFinish }, reset: { target: StateMachine7.parent, action: actionCancel }, cancel: { target: StateMachine7.parent, action: actionCancel } } }); this.debug = Debug7.create(true, "annotations"); this.snapping = false; } createDatum() { return new FibonacciRetracementTrendBasedProperties(); } }; __decorateClass2([ StateMachineProperty7() ], FibonacciRetracementTrendBasedStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty7() ], FibonacciRetracementTrendBasedStateMachine.prototype, "node", 2); __decorateClass2([ StateMachineProperty7() ], FibonacciRetracementTrendBasedStateMachine.prototype, "snapping", 2); var fibonacciRetracementTrendBasedConfig = { type: "fibonacci-retracement-trend-based", datum: FibonacciRetracementTrendBasedProperties, scene: FibonacciRetracementTrendBasedScene, isDatum: FibonacciRetracementTrendBasedProperties.is, translate: (node, datum, transition, context) => { if (FibonacciRetracementTrendBasedProperties.is(datum) && FibonacciRetracementTrendBasedScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (FibonacciRetracementTrendBasedProperties.is(datum) && FibonacciRetracementTrendBasedProperties.is(copiedDatum) && FibonacciRetracementTrendBasedScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (FibonacciRetracementTrendBasedProperties.is(datum) && FibonacciRetracementTrendBasedScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new FibonacciRetracementTrendBasedStateMachine({ ...ctx, create: createDatum( "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community82 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec213, Vec4: Vec49 } = import_ag_charts_community82._ModuleSupport; var FibonacciRetracementScene = class extends FibonacciScene { constructor() { super(); this.type = "fibonacci-retracement"; this.start = new DivariantHandle(); this.end = new DivariantHandle(); this.append([this.start, this.end]); } static is(value) { return AnnotationScene.isCheck(value, "fibonacci-retracement"); } containsPoint(x, y) { const { start: start2, end: end2 } = this; this.activeHandle = void 0; if (start2.containsPoint(x, y)) { this.activeHandle = "start"; return true; } if (end2.containsPoint(x, y)) { this.activeHandle = "end"; return true; } return super.containsPoint(x, y); } getNodeAtCoords(x, y) { if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y)) return "handle"; return super.getNodeAtCoords(x, y); } dragStart(datum, target, context) { this.dragState = { offset: target, ...getDragStartState({ start: datum.start, end: datum.end }, context) }; } stopDragging() { this.start.toggleDragging(false); this.end.toggleDragging(false); } dragAll(datum, target, context) { const { dragState } = this; if (!dragState) return; this.translatePoints({ datum, start: dragState.start, end: dragState.end, translation: Vec213.sub(target, dragState.offset), context }); } dragHandle(datum, target, context, snapping) { const { activeHandle, dragState } = this; if (!activeHandle || !dragState) return; this[activeHandle].toggleDragging(true); const point = snapping ? this.snapToAngle(datum, target, context) : invertCoords(this[activeHandle].drag(target).point, context); if (!point || !validateDatumPoint(context, point)) return; datum[activeHandle].x = point.x; datum[activeHandle].y = point.y; } snapToAngle(datum, coords, context) { const { activeHandle } = this; const handles = ["start", "end"]; const fixedHandle = handles.find((handle22) => handle22 !== activeHandle); if (!activeHandle || !fixedHandle) return; this[activeHandle].toggleDragging(true); const fixed = convertPoint(datum[fixedHandle], context); return invertCoords(snapToAngle(coords, fixed, datum.snapToAngle), context); } translatePoints({ datum, start: start2, end: end2, translation, context }) { const { vectors, translateX, translateY } = translate( { start: start2, end: end2 }, translation, context ); if (translateX) { datum.start.x = vectors.start?.x; datum.end.x = vectors.end?.x; } if (this.ignoreYBounds || translateY) { datum.start.y = vectors.start?.y; datum.end.y = vectors.end?.y; } } translate(datum, translation, context) { this.translatePoints({ datum, start: convertPoint(datum.start, context), end: convertPoint(datum.end, context), translation, context }); } copy(datum, copiedDatum, context) { const coords = convertLine(datum, context); if (!coords) { return; } const bbox = this.computeBBoxWithoutHandles(); this.translatePoints({ datum: copiedDatum, start: { x: coords.x1, y: coords.y1 }, end: { x: coords.x2, y: coords.y2 }, translation: { x: -bbox.width / 2, y: -bbox.height / 2 }, context }); return copiedDatum; } toggleHandles(show) { if (typeof show === "boolean") { this.start.visible = show; this.end.visible = show; } else { for (const [handle22, visible] of Object.entries(show)) { this[handle22].visible = visible; } } this.start.toggleHovered(this.activeHandle === "start"); this.end.toggleHovered(this.activeHandle === "end"); } toggleActive(active) { this.toggleHandles(active); this.start.toggleActive(active); this.end.toggleActive(active); } updateHandles(datum, coords, _coords2, bbox) { this.start.update({ ...this.getHandleStyles(datum), ...this.getHandleCoords(datum, coords, "start") }); this.end.update({ ...this.getHandleStyles(datum), ...this.getHandleCoords(datum, coords, "end", bbox) }); this.start.toggleLocked(datum.locked ?? false); this.end.toggleLocked(datum.locked ?? false); } getHandleCoords(_datum, coords, handle22, _bbox) { return handle22 === "start" ? Vec49.start(coords) : Vec49.end(coords); } }; var import_ag_charts_community83 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine8, StateMachineProperty: StateMachineProperty8, Debug: Debug8 } = import_ag_charts_community83._ModuleSupport; var LineTypeStateMachine = class extends StateMachine8 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = this.createDatum(); datum.set({ start: point, end: point }); ctx.create(datum); }; const actionFirstRender = () => { const { node } = this; node?.toggleActive(true); node?.toggleHandles({ start: true, end: false }); }; const actionEndUpdate = ({ offset: offset4, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset4, context, snapping, datum.start, datum.snapToAngle) }); ctx.update(); }; const actionEndFinish = () => { this.node?.toggleHandles({ end: true }); ctx.update(); }; const actionCancel = () => ctx.delete(); const onExitEnd = () => { ctx.showAnnotationOptions(); ctx.recordAction(`Create ${this.datum?.type} annotation`); }; super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, drag: { target: "waiting-first-render", action: actionCreate }, reset: StateMachine8.parent }, "waiting-first-render": { render: { target: "end", action: actionFirstRender } }, end: { hover: actionEndUpdate, click: { target: StateMachine8.parent, action: actionEndFinish }, drag: actionEndUpdate, dragEnd: { target: StateMachine8.parent, action: actionEndFinish }, reset: { target: StateMachine8.parent, action: actionCancel }, cancel: { target: StateMachine8.parent, action: actionCancel }, onExit: onExitEnd } }); this.debug = Debug8.create(true, "annotations"); this.snapping = false; } }; __decorateClass2([ StateMachineProperty8() ], LineTypeStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty8() ], LineTypeStateMachine.prototype, "node", 2); __decorateClass2([ StateMachineProperty8() ], LineTypeStateMachine.prototype, "snapping", 2); var ArrowStateMachine = class extends LineTypeStateMachine { createDatum() { return new ArrowProperties(); } }; var LineStateMachine = class extends LineTypeStateMachine { createDatum() { return new LineProperties(); } }; var FibonacciRetracementStateMachine = class extends LineTypeStateMachine { createDatum() { return new FibonacciRetracementProperties(); } }; var fibonacciRetracementConfig = { type: "fibonacci-retracement", datum: FibonacciRetracementProperties, scene: FibonacciRetracementScene, isDatum: FibonacciRetracementProperties.is, translate: (node, datum, transition, context) => { if (FibonacciRetracementProperties.is(datum) && FibonacciRetracementScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (FibonacciRetracementProperties.is(datum) && FibonacciRetracementProperties.is(copiedDatum) && FibonacciRetracementScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (FibonacciRetracementProperties.is(datum) && FibonacciRetracementScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new FibonacciRetracementStateMachine({ ...ctx, create: createDatum( "fibonacci-retracement" /* FibonacciRetracement */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community85 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community84 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec214 } = import_ag_charts_community84._ModuleSupport; var CapScene = class extends import_ag_charts_community84._ModuleSupport.Group { }; var ArrowCapScene = class extends CapScene { constructor() { super(); this.type = "arrow"; this.path = new import_ag_charts_community84._ModuleSupport.Path(); this.armLength = 6; this.append([this.path]); } update(options) { const { path } = this; const { x, y, angle: angle2, ...rest } = options; const origin3 = Vec214.from(x, y); const offsetAngle = 3 * Math.PI / 4; const armLength = this.armLength + (options.strokeWidth ?? 0) * 2; const leftEnd = Vec214.rotate(Vec214.from(0, armLength), angle2 + offsetAngle, origin3); const rightEnd = Vec214.rotate(Vec214.from(armLength, 0), angle2 - offsetAngle, origin3); path.setProperties(rest); path.fillOpacity = 0; path.path.clear(); path.path.moveTo(leftEnd.x, leftEnd.y); path.path.lineTo(origin3.x, origin3.y); path.path.lineTo(rightEnd.x, rightEnd.y); } }; var { Vec2: Vec215, Vec4: Vec410 } = import_ag_charts_community85._ModuleSupport; var LineScene = class extends StartEndScene { constructor() { super(); this.type = "line"; this.line = new CollidableLine(); this.append([this.line, this.start, this.end]); } static is(value) { return AnnotationScene.isCheck(value, "line"); } update(datum, context) { let coords = convertLine(datum, context); if (coords == null) { this.visible = false; return; } coords = Vec410.round(coords); this.visible = datum.visible ?? true; if (!this.visible) return; this.updateLine(datum, coords, context); this.updateHandles(datum, coords); this.updateText(datum, coords); this.updateCaps(datum, coords); this.updateAnchor(datum, coords, context); } updateLine(datum, coords, context) { const { line } = this; const { lineDashOffset, stroke: stroke22, strokeWidth, strokeOpacity } = datum; const linePoints = this.extendLine(coords, datum, context); line.setProperties({ ...linePoints, lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke22, strokeWidth, strokeOpacity, fillOpacity: 0 }); } updateText(datum, coords) { this.text = this.updateNode(CollidableText, this.text, !!datum.text.label); updateLineText(this.line.id, this.line, coords, datum.text, this.text, datum.text.label, datum.strokeWidth); } updateCaps(datum, coords) { if (!datum.startCap && this.startCap) { this.removeChild(this.startCap); this.startCap = void 0; } if (!datum.endCap && this.endCap) { this.removeChild(this.endCap); this.endCap = void 0; } if (!datum.startCap && !datum.endCap) return; const { stroke: stroke22, strokeWidth, strokeOpacity } = datum; const [start2, end2] = Vec215.from(coords); const angle2 = Vec215.angle(Vec215.sub(end2, start2)); if (datum.startCap) { if (this.startCap && this.startCap.type !== datum.startCap) { this.removeChild(this.startCap); this.startCap = void 0; } if (this.startCap == null) { this.startCap = new ArrowCapScene(); this.append([this.startCap]); } this.startCap.update({ x: start2.x, y: start2.y, angle: angle2 - Math.PI, stroke: stroke22, strokeWidth, strokeOpacity }); } if (datum.endCap) { if (this.endCap && this.endCap.type !== datum.endCap) { this.removeChild(this.endCap); this.endCap = void 0; } if (this.endCap == null) { this.endCap = new ArrowCapScene(); this.append([this.endCap]); } this.endCap.update({ x: end2.x, y: end2.y, angle: angle2, stroke: stroke22, strokeWidth, strokeOpacity }); } } updateAnchor(_datum, coords, _context, _bbox) { const point = Vec410.topCenter(coords); Vec215.apply(this.anchor, import_ag_charts_community85._ModuleSupport.Transformable.toCanvasPoint(this.line, point.x, point.y)); } containsPoint(x, y) { const { line, text: text22 } = this; return super.containsPoint(x, y) || line.isPointInPath(x, y) || Boolean(text22?.containsPoint(x, y)); } getNodeAtCoords(x, y) { if (this.text?.containsPoint(x, y)) return "text"; if (this.line.isPointInPath(x, y)) return "line"; return super.getNodeAtCoords(x, y); } getHandleCoords(_datum, coords, handle22, _bbox) { const { startCap, endCap } = this; let [startPoint, endPoint] = Vec215.from(coords); const angle2 = Vec215.angle(Vec215.sub(endPoint, startPoint)); if (startCap) { startPoint = Vec215.rotate(Vec215.from(0, -DivariantHandle.HANDLE_SIZE / 2), angle2, startPoint); } if (endCap) { endPoint = Vec215.rotate(Vec215.from(0, DivariantHandle.HANDLE_SIZE / 2), angle2, endPoint); } return handle22 === "start" ? startPoint : endPoint; } getHandleStyles(datum) { return { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke, strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity, strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth }; } }; var lineConfig = { type: "line", datum: LineProperties, scene: LineScene, isDatum: LineProperties.is, translate: (node, datum, transition, context) => { if (LineProperties.is(datum) && LineScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (LineProperties.is(datum) && LineProperties.is(copiedDatum) && LineScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (LineProperties.is(datum) && LineScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new LineStateMachine({ ...ctx, create: createDatum( "line" /* Line */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var arrowConfig = { type: "arrow", datum: ArrowProperties, scene: LineScene, isDatum: ArrowProperties.is, translate: (node, datum, transition, context) => { if (ArrowProperties.is(datum) && LineScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (ArrowProperties.is(datum) && ArrowProperties.is(copiedDatum) && LineScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (ArrowProperties.is(datum) && LineScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new ArrowStateMachine({ ...ctx, create: createDatum( "arrow" /* Arrow */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community88 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community87 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community86 = (init_main4(), __toCommonJS(main_exports)); function layoutScenesRow(scenes, startX = 0, gap = 0) { let x = startX; for (const scene of scenes) { if (Array.isArray(scene)) { for (const scene_ of scene) { layoutSetX(scene_, x); } x += import_ag_charts_community86._ModuleSupport.Group.computeChildrenBBox(scene).width + gap; } else { layoutSetX(scene, x); x += scene.getBBox().width + gap; } } } function layoutScenesColumn(scenes, startY = 0, gap = 0) { let y = startY; for (const scene of scenes) { if (Array.isArray(scene)) { for (const scene_ of scene) { layoutSetY(scene_, y); } y += import_ag_charts_community86._ModuleSupport.Group.computeChildrenBBox(scene).height + gap; } else { layoutSetY(scene, y); y += scene.getBBox().height + gap; } } } function layoutSetX(scene, x) { if ("x1" in scene) { scene.x2 = x + (scene.x2 - scene.x1); scene.x1 = x; } else { scene.x = x; } } function layoutSetY(scene, y) { if ("y1" in scene) { scene.y2 = y + (scene.y2 - scene.y1); scene.y1 = y; } else { scene.y = y; } } function layoutAddX(scene, x) { if ("x1" in scene) { scene.x1 += x; scene.x2 += x; } else { scene.x += x; } } function layoutAddY(scene, y) { if ("y1" in scene) { scene.y1 += y; scene.y2 += y; } else { scene.y += y; } } var { Vec4: Vec411 } = import_ag_charts_community87._ModuleSupport; var MeasurerStatisticsScene = class extends import_ag_charts_community87._ModuleSupport.Group { constructor() { super(); this.name = "MeasurerStatisticsScene"; this.background = new import_ag_charts_community87._ModuleSupport.Rect(); this.dateRangeBarsText = new import_ag_charts_community87._ModuleSupport.Text(); this.dateRangeDivider = new import_ag_charts_community87._ModuleSupport.Line(); this.dateRangeValueText = new import_ag_charts_community87._ModuleSupport.Text(); this.priceRangeValueText = new import_ag_charts_community87._ModuleSupport.Text(); this.priceRangeDivider = new import_ag_charts_community87._ModuleSupport.Line(); this.priceRangePercentageText = new import_ag_charts_community87._ModuleSupport.Text(); this.volumeText = new import_ag_charts_community87._ModuleSupport.Text(); this.volumeFormatter = new Intl.NumberFormat("en-US", { notation: "compact", minimumFractionDigits: 2, maximumFractionDigits: 2 }); this.append([ this.background, this.dateRangeBarsText, this.dateRangeDivider, this.dateRangeValueText, this.priceRangeValueText, this.priceRangeDivider, this.priceRangePercentageText, this.volumeText ]); } update(datum, stats, anchor, coords, context, verticalDirection, localeManager) { this.verticalDirection = verticalDirection; const scenes = this.updateStatistics(datum, stats, anchor, localeManager); const bbox = import_ag_charts_community87._ModuleSupport.Group.computeChildrenBBox(scenes.flat()); const padding = 10; bbox.grow(padding); this.updateBackground(datum, bbox, padding); this.reposition(scenes, padding, context); this.checkVisibility(datum, context, coords); } checkVisibility(datum, context, coords) { const bounds = Vec411.from(new import_ag_charts_community87._ModuleSupport.BBox(0, 0, context.seriesRect.width, context.seriesRect.height)); if (Vec411.collides(coords, bounds)) { this.visible = datum.visible ?? true; } else { this.visible = false; } } updateStatistics(datum, stats, anchor, localeManager) { const { dateRangeBarsText, dateRangeDivider, dateRangeValueText, priceRangeValueText, priceRangeDivider, priceRangePercentageText, volumeText } = this; const horizontalGap = 8; const verticalGap = 6; const dividerLineHeight = datum.statistics.fontSize + 3; const dividerLineOffset = -2; const textStyles = this.getTextStyles(datum); const dividerLineStyles = { ...this.getDividerStyles(datum), x1: 0, y1: 0, x2: 0, y2: dividerLineHeight }; const dateScenes = [dateRangeBarsText, dateRangeDivider, dateRangeValueText]; const priceScenes = [priceRangeValueText, priceRangeDivider, priceRangePercentageText]; const scenes = []; if (stats.priceRange) { priceRangeValueText.setProperties({ ...textStyles, text: this.formatPriceRangeValue(stats.priceRange.value, localeManager) }); priceRangeDivider.setProperties(dividerLineStyles); priceRangePercentageText.setProperties({ ...textStyles, text: this.formatPriceRangePercentage(stats.priceRange.percentage, localeManager) }); layoutScenesRow(priceScenes, anchor.x, horizontalGap); scenes.push(priceScenes); } if (stats.dateRange) { dateRangeBarsText.setProperties({ ...textStyles, text: this.formatDateRangeBars(stats.dateRange.bars, localeManager) }); dateRangeDivider.setProperties(dividerLineStyles); dateRangeValueText.setProperties({ ...textStyles, text: this.formatDateRangeValue(stats.dateRange.value) }); layoutScenesRow(dateScenes, anchor.x, horizontalGap); scenes.push(dateScenes); } if (stats.volume != null) { volumeText.setProperties({ ...textStyles, x: anchor.x, text: this.formatVolume(stats.volume, localeManager), visible: true }); scenes.push(volumeText); } else { volumeText.visible = false; } layoutScenesColumn(scenes, anchor.y, verticalGap); priceRangeDivider.y1 += dividerLineOffset; priceRangeDivider.y2 += dividerLineOffset; dateRangeDivider.y1 += dividerLineOffset; dateRangeDivider.y2 += dividerLineOffset; return scenes; } updateBackground(datum, bbox, padding) { const styles = this.getBackgroundStyles(datum); this.background.setProperties({ ...styles, ...bbox, x: bbox.x - bbox.width / 2 + padding, y: bbox.y }); } reposition(scenes, padding, context) { const { width: width2, height: height2 } = context.seriesRect; const background = Vec411.from(this.background.getBBox()); let offsetX = 0; if (background.x1 < 0) offsetX = -background.x1; if (background.x2 > width2) offsetX = width2 - background.x2; const offsetY = Math.min(padding, height2 - background.y2); for (const scene of scenes) { if (Array.isArray(scene)) { const rowWidth = import_ag_charts_community87._ModuleSupport.Group.computeChildrenBBox(scene).width; for (const scene_ of scene) { layoutAddX(scene_, offsetX - rowWidth / 2); layoutAddY(scene_, offsetY); } } else { layoutAddX(scene, offsetX - scene.getBBox().width / 2); layoutAddY(scene, offsetY); } } this.background.x += offsetX; this.background.y += offsetY; } getTextStyles(datum) { return { fill: datum.statistics.color, fontFamily: datum.statistics.fontFamily, fontSize: datum.statistics.fontSize, fontStyle: datum.statistics.fontStyle, fontWeight: datum.statistics.fontWeight, textBaseline: "top" }; } getDividerStyles(datum) { return { stroke: datum.statistics.divider.stroke, strokeOpacity: datum.statistics.divider.strokeOpacity, strokeWidth: datum.statistics.divider.strokeWidth }; } getBackgroundStyles(datum) { return { fill: datum.statistics.fill, stroke: datum.statistics.stroke, strokeOpacity: datum.statistics.strokeOpacity, strokeWidth: datum.statistics.strokeWidth, cornerRadius: 4 }; } formatDateRangeBars(bars, localeManager) { return localeManager?.t("measurerDateRangeBars", { value: bars }) ?? `${bars}`; } formatDateRangeValue(time2) { const range22 = []; const sign = time2 >= 0 ? "" : "-"; time2 = Math.abs(time2); const MINUTE = 1e3 * 60; const HOUR = MINUTE * 60; const DAY2 = HOUR * 24; const minutes = Math.floor(time2 / MINUTE); const hours = Math.floor(time2 / HOUR); const days = Math.floor(time2 / DAY2); const remainderHours = hours % (DAY2 / HOUR); const remainderMinutes = minutes % (HOUR / MINUTE); if (days >= 1) range22.push(`${days}d`); if (hours >= 1 && (time2 < DAY2 || remainderHours !== 0)) range22.push(`${remainderHours}h`); if (time2 < HOUR || remainderMinutes !== 0) range22.push(`${remainderMinutes}m`); range22[0] = `${sign}${range22[0]}`; return range22.join(" "); } formatPriceRangeValue(value, localeManager) { return localeManager?.t("measurerPriceRangeValue", { value: Number(value.toFixed(2)) }) ?? `${value}`; } formatPriceRangePercentage(percentage, localeManager) { return localeManager?.t("measurerPriceRangePercent", { value: percentage }) ?? `${percentage}`; } formatVolume(volume, localeManager) { const volumeString = isNaN(volume) ? "" : this.volumeFormatter.format(volume); return localeManager?.t("measurerVolume", { value: volumeString }) ?? volumeString; } }; var QuickMeasurerStatisticsScene = class extends MeasurerStatisticsScene { getDirectionStyles(datum) { return this.verticalDirection === "down" ? datum.down.statistics : datum.up.statistics; } getTextStyles(datum) { const styles = this.getDirectionStyles(datum); return { ...super.getTextStyles(datum), fill: styles.color, fontFamily: styles.fontFamily, fontSize: styles.fontSize, fontStyle: styles.fontStyle, fontWeight: styles.fontWeight }; } getDividerStyles(datum) { const styles = this.getDirectionStyles(datum); return { stroke: styles.divider.stroke, strokeOpacity: styles.divider.strokeOpacity, strokeWidth: styles.divider.strokeWidth }; } getBackgroundStyles(datum) { const styles = this.getDirectionStyles(datum); return { ...super.getBackgroundStyles(datum), fill: styles.fill, stroke: styles.stroke, strokeOpacity: styles.strokeOpacity, strokeWidth: styles.strokeWidth }; } }; var { Vec2: Vec216, Vec4: Vec412 } = import_ag_charts_community88._ModuleSupport; var MeasurerScene = class extends StartEndScene { constructor() { super(); this.type = "measurer"; this.horizontalLine = new CollidableLine(); this.verticalLine = new CollidableLine(); this.horizontalStartLine = new CollidableLine(); this.horizontalEndLine = new CollidableLine(); this.verticalStartLine = new CollidableLine(); this.verticalEndLine = new CollidableLine(); this.horizontalEndCap = new ArrowCapScene(); this.verticalEndCap = new ArrowCapScene(); this.background = new import_ag_charts_community88._ModuleSupport.Path({ zIndex: -1 }); this.updateBackground = WithBackgroundScene.updateBackground.bind(this); this.statistics = this.createStatisticsScene(); this.statistics.zIndex = 1; this.append([ this.background, this.verticalStartLine, this.verticalEndLine, this.horizontalStartLine, this.horizontalEndLine, this.horizontalLine, this.verticalLine, this.horizontalEndCap, this.verticalEndCap, this.start, this.end, this.statistics ]); } static is(value) { return AnnotationScene.isCheck(value, "measurer"); } createStatisticsScene() { return new MeasurerStatisticsScene(); } update(datum, context) { const coords = convertLine(datum, context); if (coords == null) { this.visible = false; return; } this.visible = datum.visible ?? true; if (!this.visible) return; const extended = this.extendPerpendicular(coords, datum, context); const verticalStart = { ...extended, y2: extended.y1 }; const verticalEnd = { ...extended, y1: extended.y2 }; this.verticalDirection = coords.y1 < coords.y2 ? "down" : "up"; this.updateVisibilities(datum); this.updateLines(datum, coords); this.updateHandles(datum, coords); this.updateText(datum, coords); this.updateCaps(datum, coords); this.updateBoundingLines(datum, extended); this.updateBackground(datum, verticalStart, verticalEnd, context); this.updateStatistics(datum, coords, context); this.updateAnchor(datum, coords, context); } extendPerpendicular(coords, datum, context) { const extended = { x1: Math.min(coords.x1, coords.x2), x2: Math.max(coords.x1, coords.x2), y1: Math.min(coords.y1, coords.y2), y2: Math.max(coords.y1, coords.y2) }; const [start2, end2] = Vec216.from(context.yAxis.bounds); if (DateRangeProperties.is(datum)) { if (datum.extendAbove) extended.y1 = start2.y; if (datum.extendBelow) extended.y2 = end2.y; } else if (PriceRangeProperties.is(datum)) { if (datum.extendLeft) extended.x1 = start2.x; if (datum.extendRight) extended.x2 = end2.x; } return extended; } updateVisibilities(datum) { const { horizontalStartLine, horizontalEndLine, horizontalEndCap, verticalStartLine, verticalEndLine, verticalEndCap } = this; const { direction } = datum; verticalStartLine.visible = direction !== "vertical"; verticalEndLine.visible = direction !== "vertical"; horizontalEndCap.visible = direction !== "vertical"; horizontalStartLine.visible = direction !== "horizontal"; horizontalEndLine.visible = direction !== "horizontal"; verticalEndCap.visible = direction !== "horizontal"; } updateLines(datum, coords) { const { horizontalLine, verticalLine } = this; const { direction } = datum; const { x1, y1, x2, y2 } = coords; const center2 = Vec216.round(Vec412.center(coords)); const lineStyles = this.getLineStyles(datum); if (direction !== "vertical") { horizontalLine.setProperties({ ...lineStyles, x1, x2, y1: center2.y, y2: center2.y }); } if (direction !== "horizontal") { verticalLine.setProperties({ ...lineStyles, x1: center2.x, x2: center2.x, y1, y2 }); } } updateText(datum, coords) { const { direction } = datum; const center2 = Vec216.round(Vec412.center(coords)); let line; const textCoords = { ...coords }; if (direction === "vertical") { line = this.verticalLine; textCoords.x1 = center2.x; textCoords.x2 = center2.x; } else { line = this.horizontalLine; textCoords.y1 = center2.y; textCoords.y2 = center2.y; } this.text = this.updateNode(CollidableText, this.text, !!datum.text.label); const { id } = line; const clip = updateLineText(id, line, textCoords, datum.text, this.text, datum.text.label, datum.strokeWidth); let verticalClipMask; if (direction === "both" && clip && this.text) { const textBBox = Vec412.from(this.text.getBBox()); const { offset: offset4 } = clip.numbers; const crossesVerticalLine = textBBox.x1 <= center2.x + offset4.x && textBBox.x2 >= center2.x - offset4.x; if (crossesVerticalLine) { verticalClipMask = { x: center2.x, y: clip.clipMask.y, radius: this.text.getBBox().height / 2 + Vec216.length(offset4) }; } } this.verticalLine.setClipMask(id, verticalClipMask); } updateCaps(datum, coords) { const { horizontalEndCap, verticalEndCap } = this; const { direction } = datum; const { x1, y1, x2, y2 } = coords; const center2 = Vec216.round(Vec412.center(coords)); const { stroke: stroke22, strokeWidth, strokeOpacity } = this.getLineStyles(datum); const capStyles = { stroke: stroke22, strokeWidth, strokeOpacity }; if (direction !== "vertical") { const angle2 = x1 <= x2 ? 0 : Math.PI; let x = x2; if (direction === "horizontal") { x += x1 <= x2 ? -2 : 2; } horizontalEndCap.update({ ...capStyles, x, y: center2.y, angle: angle2 }); } if (direction !== "horizontal") { const angle2 = y1 <= y2 ? Math.PI / 2 : Math.PI / -2; let y = y2; if (direction === "vertical") { y += y1 <= y2 ? -2 : 2; } verticalEndCap.update({ ...capStyles, x: center2.x, y, angle: angle2 }); } } updateBoundingLines(datum, extendedCoords) { const { verticalStartLine, verticalEndLine, horizontalStartLine, horizontalEndLine } = this; const { direction } = datum; const { x1, y1, x2, y2 } = extendedCoords; const lineStyles = this.getLineStyles(datum); if (direction === "horizontal") { verticalStartLine.setProperties({ ...lineStyles, x1, y1, x2: x1, y2 }); verticalEndLine.setProperties({ ...lineStyles, x1: x2, y1, x2, y2 }); } if (direction === "vertical") { horizontalStartLine.setProperties({ ...lineStyles, x1, y1, x2, y2: y1 }); horizontalEndLine.setProperties({ ...lineStyles, x1, y1: y2, x2, y2 }); } } updateStatistics(datum, coords, context) { const point = Vec216.add(Vec412.bottomCenter(coords), Vec216.from(0, 10)); const statistics = { volume: this.getVolume(datum) }; if (datum.hasPriceRange) { statistics.priceRange = { percentage: this.getPriceRangePercentage(datum), value: this.getPriceRangeValue(datum) }; } if (datum.hasDateRange) { statistics.dateRange = { bars: this.getDateRangeBars(coords, context), value: this.getDateRangeValue(datum) }; } this.statistics.update(datum, statistics, point, coords, context, this.verticalDirection, datum.localeManager); } updateAnchor(_datum, coords, _context, _bbox) { const point = Vec412.topCenter(coords); Vec216.apply(this.anchor, import_ag_charts_community88._ModuleSupport.Transformable.toCanvasPoint(this.horizontalLine, point.x, point.y)); } getBackgroundPoints(_datum, verticalStart, verticalEnd, _bounds) { const [startStart, startEnd] = Vec216.from(verticalStart); const [endStart, endEnd] = Vec216.from(verticalEnd); return [startStart, startEnd, endEnd, endStart]; } getLineStyles(datum) { const { lineDashOffset, stroke: stroke22, strokeWidth, strokeOpacity } = datum; return { lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke22, strokeWidth, strokeOpacity, fillOpacity: 0 }; } getBackgroundStyles(datum) { const { background } = datum; return { fill: background.fill, fillOpacity: background.fillOpacity }; } getHandleStyles(datum) { return { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke, strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity, strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth }; } containsPoint(x, y) { const { horizontalLine, text: text22, verticalLine, horizontalStartLine, horizontalEndLine, verticalStartLine, verticalEndLine } = this; return super.containsPoint(x, y) || horizontalLine.isPointInPath(x, y) || verticalLine.isPointInPath(x, y) || horizontalStartLine.visible && horizontalStartLine.isPointInPath(x, y) || horizontalEndLine.visible && horizontalEndLine.isPointInPath(x, y) || verticalStartLine.visible && verticalStartLine.isPointInPath(x, y) || verticalEndLine.visible && verticalEndLine.isPointInPath(x, y) || Boolean(text22?.containsPoint(x, y)); } getNodeAtCoords(x, y) { if (this.text?.containsPoint(x, y)) return "text"; if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y)) return "handle"; return "line"; } getDateRangeBars(coords, context) { const { step } = context.xAxis.scale; const sign = coords.x1 <= coords.x2 ? 1 : -1; return step ? Math.round(Vec412.width(coords) / step) * sign : 0; } getDateRangeValue(datum) { const { value: start2 } = getGroupingValue(datum.start.x); const { value: end2 } = getGroupingValue(datum.end.x); if (!isDate2(start2) || !isDate2(end2)) { throw new Error("Can not create a date range measurement of non-date x-axis."); } return end2.getTime() - start2.getTime(); } getPriceRangePercentage(datum) { if (datum.start.y == null || datum.end.y == null) { throw new Error("Can not create a price range measurement of a non-numeric y-axis"); } const { value: endY } = getGroupingValue(datum.end.y); const { value: startY } = getGroupingValue(datum.start.y); if (!isNumber2(endY) || !isNumber2(startY)) { throw new Error("Can not create a price range measurement of a non-numeric y-axis"); } return (endY - startY) / startY; } getPriceRangeValue(datum) { if (datum.start.y == null || datum.end.y == null) { throw new Error("Can not create a price range measurement of a non-numeric y-axis"); } const { value: endY } = getGroupingValue(datum.end.y); const { value: startY } = getGroupingValue(datum.start.y); if (!isNumber2(endY) || !isNumber2(startY)) { throw new Error("Can not create a price range measurement of a non-numeric y-axis"); } return endY - startY; } getVolume(datum) { return datum.getVolume(datum.start.x, datum.end.x); } }; var QuickMeasurerScene = class extends MeasurerScene { constructor() { super(...arguments); this.type = "quick-measurer"; } static is(value) { return AnnotationScene.isCheck(value, "quick-measurer"); } createStatisticsScene() { return new QuickMeasurerStatisticsScene(); } getDirectionStyles(datum) { return this.verticalDirection === "down" ? datum.down : datum.up; } getLineStyles(datum) { const styles = this.getDirectionStyles(datum); return { ...super.getLineStyles(datum), stroke: styles.stroke, strokeWidth: styles.strokeWidth, strokeOpacity: styles.strokeOpacity }; } getBackgroundStyles(datum) { const styles = this.getDirectionStyles(datum); return { fill: styles.fill, fillOpacity: styles.fillOpacity }; } getHandleStyles(datum) { const styles = this.getDirectionStyles(datum); return { fill: styles.handle.fill, stroke: styles.handle.stroke ?? styles.stroke, strokeOpacity: styles.handle.strokeOpacity ?? styles.strokeOpacity, strokeWidth: styles.handle.strokeWidth ?? styles.strokeWidth }; } }; var import_ag_charts_community89 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine9, StateMachineProperty: StateMachineProperty9, Debug: Debug9 } = import_ag_charts_community89._ModuleSupport; var MeasurerTypeStateMachine = class extends StateMachine9 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = this.createDatum(); datum.set({ start: point, end: point }); ctx.create(datum); }; const actionEndUpdate = ({ point }) => { const { datum, node } = this; datum?.set({ end: point }); node?.toggleActive(true); node?.toggleHandles({ end: false }); ctx.update(); }; const actionEndFinish = () => { this.node?.toggleHandles({ end: true }); }; const actionCancel = () => ctx.delete(); const onExitEnd = () => { ctx.showAnnotationOptions(); if (isEphemeralType(this.datum)) return; ctx.recordAction(`Create ${this.node?.type} annotation`); }; super("start", { start: { reset: StateMachine9.parent, click: { target: "end", action: actionCreate }, drag: { target: "end", action: actionCreate } }, end: { hover: actionEndUpdate, drag: actionEndUpdate, click: { target: StateMachine9.parent, action: actionEndFinish }, dragEnd: { target: StateMachine9.parent, action: actionEndFinish }, reset: { target: StateMachine9.parent, action: actionCancel }, cancel: { target: StateMachine9.parent, action: actionCancel }, onExit: onExitEnd } }); this.debug = Debug9.create(true, "annotations"); } }; __decorateClass2([ StateMachineProperty9() ], MeasurerTypeStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty9() ], MeasurerTypeStateMachine.prototype, "node", 2); var DateRangeStateMachine = class extends MeasurerTypeStateMachine { createDatum() { return new DateRangeProperties(); } }; var PriceRangeStateMachine = class extends MeasurerTypeStateMachine { createDatum() { return new PriceRangeProperties(); } }; var DatePriceRangeStateMachine = class extends MeasurerTypeStateMachine { createDatum() { return new DatePriceRangeProperties(); } }; var QuickDatePriceRangeStateMachine = class extends MeasurerTypeStateMachine { createDatum() { return new QuickDatePriceRangeProperties(); } }; var dateRangeConfig = { type: "date-range", datum: DateRangeProperties, scene: MeasurerScene, isDatum: DateRangeProperties.is, translate: (node, datum, translation, context) => { if (DateRangeProperties.is(datum) && MeasurerScene.is(node)) { node.translate(datum, translation, context); } }, copy: (node, datum, copiedDatum, context) => { if (DateRangeProperties.is(datum) && DateRangeProperties.is(copiedDatum) && MeasurerScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (DateRangeProperties.is(datum) && MeasurerScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new DateRangeStateMachine({ ...ctx, create: createDatum( "date-range" /* DateRange */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var priceRangeConfig = { type: "price-range", datum: PriceRangeProperties, scene: MeasurerScene, isDatum: PriceRangeProperties.is, translate: (node, datum, translation, context) => { if (PriceRangeProperties.is(datum) && MeasurerScene.is(node)) { node.translate(datum, translation, context); } }, copy: (node, datum, copiedDatum, context) => { if (PriceRangeProperties.is(datum) && PriceRangeProperties.is(copiedDatum) && MeasurerScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (PriceRangeProperties.is(datum) && MeasurerScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new PriceRangeStateMachine({ ...ctx, create: createDatum( "date-range" /* DateRange */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var datePriceRangeConfig = { type: "date-price-range", datum: DatePriceRangeProperties, scene: MeasurerScene, isDatum: DatePriceRangeProperties.is, translate: (node, datum, translation, context) => { if (DatePriceRangeProperties.is(datum) && MeasurerScene.is(node)) { node.translate(datum, translation, context); } }, copy: (node, datum, copiedDatum, context) => { if (DatePriceRangeProperties.is(datum) && DatePriceRangeProperties.is(copiedDatum) && MeasurerScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (DatePriceRangeProperties.is(datum) && MeasurerScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new DatePriceRangeStateMachine({ ...ctx, create: createDatum( "date-range" /* DateRange */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var quickDatePriceRangeConfig = { type: "quick-date-price-range", datum: QuickDatePriceRangeProperties, scene: QuickMeasurerScene, isDatum: QuickDatePriceRangeProperties.is, translate: (node, datum, translation, context) => { if (QuickDatePriceRangeProperties.is(datum) && QuickMeasurerScene.is(node)) { node.translate(datum, translation, context); } }, copy: (node, datum, copiedDatum, context) => { if (QuickDatePriceRangeProperties.is(datum) && QuickDatePriceRangeProperties.is(copiedDatum) && QuickMeasurerScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (QuickDatePriceRangeProperties.is(datum) && QuickMeasurerScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new QuickDatePriceRangeStateMachine({ ...ctx, create: createDatum( "quick-date-price-range" /* QuickDatePriceRange */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community90 = (init_main4(), __toCommonJS(main_exports)); var { ZIndexMap: ZIndexMap3, TextWrapper: TextWrapper3, clamp: clamp4 } = import_ag_charts_community90._ModuleSupport; var NoteScene = class extends TextualPointScene { constructor() { super(); this.type = "note"; this.shape = new import_ag_charts_community90._ModuleSupport.Rect(); this.iconBackground = new import_ag_charts_community90._ModuleSupport.SvgPath( "M22 1.83333C22 0.820811 21.1792 0 20.1667 0H1.83333C0.820811 0 0 0.82081 0 1.83333V13.9868C0 14.9994 0.820811 15.8202 1.83333 15.8202L5.88971 15.8202C6.44575 15.8202 6.97175 16.0725 7.31971 16.5062L9.57006 19.3112C10.304 20.2259 11.6962 20.2259 12.4301 19.3112L14.6804 16.5062C15.0284 16.0725 15.5544 15.8202 16.1104 15.8202L20.1667 15.8202C21.1792 15.8202 22 14.9994 22 13.9868V1.83333Z" ); this.iconLines = new import_ag_charts_community90._ModuleSupport.SvgPath( "M17.1114 5.75C17.1114 6.16421 16.7756 6.5 16.3614 6.5H5.63916C5.22495 6.5 4.88916 6.16421 4.88916 5.75V5.75C4.88916 5.33579 5.22495 5 5.63916 5H16.3614C16.7756 5 17.1114 5.33579 17.1114 5.75V5.75ZM17.1114 9.25C17.1114 9.66421 16.7756 10 16.3614 10H5.63916C5.22495 10 4.88916 9.66421 4.88916 9.25V9.25C4.88916 8.83579 5.22495 8.5 5.63916 8.5H16.3614C16.7756 8.5 17.1114 8.83579 17.1114 9.25V9.25Z" ); this.active = false; this.shape.visible = false; this.label.visible = false; this.iconBackground.fillShadow = new import_ag_charts_community90._ModuleSupport.DropShadow(); this.append([this.shape, this.label, this.iconBackground, this.iconLines, this.handle]); } static is(value) { return AnnotationScene.isCheck( value, "note" /* Note */ ); } update(datum, context) { this.updateIcon(datum, context); super.update(datum, context); } getTextBBox(datum, coords, context) { const bbox = super.getTextBBox(datum, coords, context); bbox.x -= datum.width / 2; bbox.x = clamp4(0, bbox.x, context.seriesRect.width - datum.width); const padding = datum.getPadding().top; const topY = bbox.y - LABEL_OFFSET - padding * 2; const bottomY = bbox.y + DivariantHandle.HANDLE_SIZE + padding * 2; if (topY - bbox.height - TOOLBAR_OFFSET < 0) { bbox.y = bottomY; datum.position = "top"; } else { bbox.y = topY + padding; datum.position = "bottom"; } return bbox; } updateLabel(datum, bbox) { const labelVisibility = datum.visible === false ? false : this.label.visible; super.updateLabel(datum, bbox); this.label.visible = labelVisibility; this.label.text = TextWrapper3.wrapText(datum.text, { font: { fontFamily: datum.fontFamily, fontSize: datum.fontSize, fontStyle: datum.fontStyle, fontWeight: datum.fontWeight }, avoidOrphans: false, textAlign: datum.textAlign, textBaseline: "hanging", textWrap: "always", maxWidth: 200 }); } updateShape(datum, bbox) { const { shape } = this; shape.fill = datum.background.fill; shape.fillOpacity = datum.background.fillOpacity ?? 1; shape.stroke = datum.background.stroke; shape.strokeOpacity = datum.background.strokeOpacity ?? 1; shape.strokeWidth = datum.background.strokeWidth ?? 1; shape.cornerRadius = 4; const padding = datum.getPadding().top; const isPositionTop = datum.position === "top"; shape.x = bbox.x - padding; shape.width = datum.width + padding * 2; shape.height = bbox.height + padding * 2; shape.y = bbox.y + (isPositionTop ? 0 : -bbox.height) - padding; } updateIcon(datum, context) { const { active, iconBackground, iconLines } = this; const { x, y } = convertPoint(datum, context); iconBackground.x = x - ICON_WIDTH / 2; iconBackground.y = y - ICON_HEIGHT; iconLines.x = iconBackground.x; iconLines.y = iconBackground.y; iconBackground.fill = datum.fill; iconBackground.fillOpacity = datum.fillOpacity ?? 1; iconBackground.stroke = datum.stroke; iconBackground.strokeOpacity = datum.strokeOpacity ?? 1; iconBackground.strokeWidth = datum.strokeWidth ?? 1; iconLines.fill = datum.stroke; if (active) { iconBackground.fillShadow.color = datum.fill ?? "rgba(0, 0, 0, 0.22)"; } else { iconBackground.fillShadow.color = "rgba(0, 0, 0, 0.22)"; } } updateAnchor(datum, bbox, context) { const padding = datum.getPadding().top; const isPositionTop = datum.position === "top"; const direction = isPositionTop ? 1 : -1; return { x: bbox.x + context.seriesRect.x + datum.width / 2, y: bbox.y + context.seriesRect.y + direction * (bbox.height + padding), position: isPositionTop ? "below" : "above" }; } getLabelCoords(datum, bbox) { const isPositionTop = datum.position === "top"; const padding = datum.getPadding().top; return { x: bbox.x, y: bbox.y + (isPositionTop ? padding / 2 : 0) }; } getHandleCoords(_datum, coords, _bbox) { return { x: coords.x, y: coords.y + DivariantHandle.HANDLE_SIZE / 2 + 4 }; } getHandleStyles(datum) { return { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.fill, strokeOpacity: datum.handle.strokeOpacity, strokeWidth: datum.handle.strokeWidth }; } toggleHovered(hovered) { super.toggleHovered(hovered); this.label.visible = hovered; this.shape.visible = hovered; this.zIndex = hovered ? ZIndexMap3.CHART_ANNOTATION_FOCUSED : ZIndexMap3.CHART_ANNOTATION; } toggleActive(active) { super.toggleActive(active); this.label.visible = active; this.shape.visible = active; this.active = active; } containsPoint(x, y) { if (this.shape.visible && this.shape.containsPoint(x, y)) return true; if (this.iconBackground.containsPoint(x, y)) return true; return super.containsPoint(x, y); } }; var NoteStateMachine = class extends TextualPointStateMachine { createDatum() { return new NoteProperties(); } }; var noteConfig = { type: "note", datum: NoteProperties, scene: NoteScene, isDatum: NoteProperties.is, translate: (node, datum, transition, context) => { if (NoteProperties.is(datum) && NoteScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (NoteProperties.is(datum) && NoteProperties.is(copiedDatum) && NoteScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (NoteProperties.is(datum) && NoteScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new NoteStateMachine({ ...ctx, create: createDatum( "note" /* Note */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var import_ag_charts_community91 = (init_main4(), __toCommonJS(main_exports)); var { Vec2: Vec217, Vec4: Vec413 } = import_ag_charts_community91._ModuleSupport; var ParallelChannelScene = class extends ChannelScene { constructor() { super(); this.type = "parallel-channel"; this.ignoreYBounds = true; this.handles = { topLeft: new DivariantHandle(), topMiddle: new UnivariantHandle(), topRight: new DivariantHandle(), bottomLeft: new DivariantHandle(), bottomMiddle: new UnivariantHandle(), bottomRight: new DivariantHandle() }; this.middleLine = new CollidableLine(); this.append([this.background, this.topLine, this.middleLine, this.bottomLine, ...Object.values(this.handles)]); } static is(value) { return AnnotationScene.isCheck(value, "parallel-channel"); } dragHandle(datum, target, context, snapping) { const { activeHandle, handles } = this; if (activeHandle == null) return; const { offset: offset4 } = handles[activeHandle].drag(target); handles[activeHandle].toggleDragging(true); const prev = datum.toJson(); let moves = []; let origins = []; switch (activeHandle) { case "topLeft": case "bottomLeft": moves = ["topLeft", "bottomLeft"]; origins = ["topRight", "bottomRight"]; break; case "topMiddle": moves = ["topLeft", "topRight"]; offset4.y -= UnivariantHandle.HANDLE_SIZE / 2; break; case "topRight": case "bottomRight": moves = ["topRight", "bottomRight"]; origins = ["topLeft", "bottomLeft"]; break; case "bottomMiddle": moves = ["bottomLeft", "bottomRight"]; offset4.y -= UnivariantHandle.HANDLE_SIZE / 2; break; } const angle2 = datum.snapToAngle; const invertedMoves = moves.map( (handle22, index) => snapping && origins[index] ? this.snapToAngle(target, context, handle22, origins[index], angle2) : invertCoords(Vec217.add(handles[handle22].handle, offset4), context) ).filter(isPoint); if (invertedMoves.some((invertedMove) => !validateDatumPoint(context, invertedMove, { y: false }))) { return; } const { value: startY } = getGroupingValue(datum.start.y); if ((activeHandle === "topMiddle" || activeHandle === "bottomMiddle") && startY != null && isNumber2(startY)) { const topLeft = invertCoords(Vec217.add(handles.topLeft.handle, offset4), context); if (activeHandle === "topMiddle") { datum.height += topLeft.y - startY; } else { datum.height -= topLeft.y - startY; } } for (const [index, invertedMove] of invertedMoves.entries()) { switch (moves[index]) { case "topLeft": datum.start.x = invertedMove.x; datum.start.y = invertedMove.y; break; case "topRight": datum.end.x = invertedMove.x; datum.end.y = invertedMove.y; break; } } if (!datum.isValidWithContext(context)) { datum.set(prev); } } containsPoint(x, y) { return super.containsPoint(x, y) || this.middleLine.visible && this.middleLine.strokeWidth > 0 && this.middleLine.containsPoint(x, y); } getNodeAtCoords(x, y) { if (this.middleLine.visible && this.middleLine.strokeWidth > 0 && this.middleLine.containsPoint(x, y)) return "line"; return super.getNodeAtCoords(x, y); } updateLines(datum, top, bottom, context, naturalTop, naturalBottom) { const { topLine, middleLine, bottomLine } = this; const { lineDashOffset, stroke: stroke22, strokeOpacity, strokeWidth } = datum; const lineDash = datum.getLineDash(); const lineStyles = { lineCap: datum.getLineCap(), lineDash, lineDashOffset, stroke: stroke22, strokeOpacity, strokeWidth }; topLine.setProperties({ ...top, ...lineStyles }); bottomLine.setProperties({ ...bottom, ...lineStyles }); const middlePoints = this.extendLine( { x1: naturalTop.x1, y1: naturalBottom.y1 + (naturalTop.y1 - naturalBottom.y1) / 2, x2: naturalTop.x2, y2: naturalBottom.y2 + (naturalTop.y2 - naturalBottom.y2) / 2 }, datum, context ); middleLine.setProperties({ ...middlePoints, lineDash: datum.middle.lineDash ?? lineDash, lineDashOffset: datum.middle.lineDashOffset ?? lineDashOffset, stroke: datum.middle.stroke ?? stroke22, strokeOpacity: datum.middle.strokeOpacity ?? strokeOpacity, strokeWidth: datum.middle.strokeWidth ?? strokeWidth, visible: datum.middle.visible ?? true }); } updateHandles(datum, top, bottom) { const { handles: { topLeft, topMiddle, topRight, bottomLeft, bottomMiddle, bottomRight } } = this; const handleStyles = { fill: datum.handle.fill, stroke: datum.handle.stroke ?? datum.stroke, strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity, strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth }; topLeft.update({ ...handleStyles, ...Vec413.start(top) }); topRight.update({ ...handleStyles, ...Vec413.end(top) }); bottomLeft.update({ ...handleStyles, ...Vec413.start(bottom) }); bottomRight.update({ ...handleStyles, ...Vec413.end(bottom) }); topMiddle.update({ ...handleStyles, ...Vec217.sub(Vec413.center(top), Vec217.from(topMiddle.handle.width / 2, topMiddle.handle.height / 2)) }); bottomMiddle.update({ ...handleStyles, ...Vec217.sub(Vec413.center(bottom), Vec217.from(bottomMiddle.handle.width / 2, bottomMiddle.handle.height / 2)) }); } updateText(datum, top, bottom) { this.text = this.updateNode(CollidableText, this.text, !!datum.text.label); updateChannelText(true, top, bottom, datum.text, datum.strokeWidth, this.text, datum.text.label); } getBackgroundPoints(datum, top, bottom, bounds) { const isFlippedX = top.x1 > top.x2; const isFlippedY = top.y1 > top.y2; const outOfBoundsStart = top.x1 !== bottom.x1 && top.y1 !== bottom.y1; const outOfBoundsEnd = top.x2 !== bottom.x2 && top.y2 !== bottom.y2; const points = Vec217.from(top); if (datum.extendEnd && outOfBoundsEnd) { points.push(Vec217.from(isFlippedX ? bounds.x1 : bounds.x2, isFlippedY ? bounds.y1 : bounds.y2)); } points.push(...Vec217.from(bottom).reverse()); if (datum.extendStart && outOfBoundsStart) { points.push(Vec217.from(isFlippedX ? bounds.x2 : bounds.x1, isFlippedY ? bounds.y2 : bounds.y1)); } return points; } }; var import_ag_charts_community92 = (init_main4(), __toCommonJS(main_exports)); var { StateMachine: StateMachine10, StateMachineProperty: StateMachineProperty10, Debug: Debug10 } = import_ag_charts_community92._ModuleSupport; var ParallelChannelStateMachine = class extends StateMachine10 { constructor(ctx) { const actionCreate = ({ point }) => { const datum = new ParallelChannelProperties(); datum.set({ start: point, end: point, height: 0 }); ctx.create(datum); }; const actionFirstRender = () => { const { node } = this; node?.toggleActive(true); node?.toggleHandles({ topLeft: true, topMiddle: false, topRight: false, bottomLeft: false, bottomMiddle: false, bottomRight: false }); }; const actionEndUpdate = ({ offset: offset4, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset4, context, snapping, datum.start, datum.snapToAngle) }); ctx.update(); }; const actionEndFinish = () => { this.node?.toggleHandles({ topRight: true }); ctx.update(); }; const actionHeightUpdate = ({ point }) => { const { datum, node } = this; const { value: endY } = getGroupingValue(datum?.end.y); const { value: startY } = getGroupingValue(datum?.start.y); const { y: pointY } = point; if (datum == null || !isNumber2(startY) || !isNumber2(endY) || !isNumber2(pointY)) return; const height2 = endY - (pointY ?? 0); const bottomStartY = startY - height2; node?.toggleHandles({ bottomLeft: true, bottomRight: true }); if (!ctx.validatePoint({ x: datum.start.x, y: bottomStartY }) || !ctx.validatePoint({ x: datum.end.x, y: point.y })) { return; } datum.set({ height: height2 }); ctx.update(); }; const actionHeightFinish = ({ point }) => { const { datum, node } = this; const { value: endY } = getGroupingValue(datum?.end.y); const { value: startY } = getGroupingValue(datum?.start.y); const { y: pointY } = point; if (datum == null || !isNumber2(startY) || !isNumber2(endY) || !isNumber2(pointY)) return; const height2 = endY - (pointY ?? 0); const bottomStartY = startY - height2; node?.toggleHandles(true); if (!ctx.validatePoint({ x: datum.start.x, y: bottomStartY }) || !ctx.validatePoint({ x: datum.end.x, y: point.y })) { return; } datum.set({ height: height2 }); ctx.recordAction(`Create ${"parallel-channel"} annotation`); ctx.showAnnotationOptions(); ctx.update(); }; const actionCancel = () => ctx.delete(); super("start", { start: { click: { target: "waiting-first-render", action: actionCreate }, drag: { target: "waiting-first-render", action: actionCreate }, reset: StateMachine10.parent }, "waiting-first-render": { render: { target: "end", action: actionFirstRender } }, end: { hover: actionEndUpdate, drag: actionEndUpdate, click: { target: "height", action: actionEndFinish }, dragEnd: { target: "height", action: actionEndFinish }, reset: { target: StateMachine10.parent, action: actionCancel }, cancel: { target: StateMachine10.parent, action: actionCancel } }, height: { hover: actionHeightUpdate, click: { target: StateMachine10.parent, action: actionHeightFinish }, drag: { target: StateMachine10.parent, action: actionHeightFinish }, reset: { target: StateMachine10.parent, action: actionCancel }, cancel: { target: StateMachine10.parent, action: actionCancel } } }); this.debug = Debug10.create(true, "annotations"); this.snapping = false; } }; __decorateClass2([ StateMachineProperty10() ], ParallelChannelStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty10() ], ParallelChannelStateMachine.prototype, "node", 2); __decorateClass2([ StateMachineProperty10() ], ParallelChannelStateMachine.prototype, "snapping", 2); var parallelChannelConfig = { type: "parallel-channel", datum: ParallelChannelProperties, scene: ParallelChannelScene, isDatum: ParallelChannelProperties.is, translate: (node, datum, transition, context) => { if (ParallelChannelProperties.is(datum) && ParallelChannelScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (ParallelChannelProperties.is(datum) && ParallelChannelProperties.is(copiedDatum) && ParallelChannelScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (ParallelChannelProperties.is(datum) && ParallelChannelScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new ParallelChannelStateMachine({ ...ctx, create: createDatum( "parallel-channel" /* ParallelChannel */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var TextScene = class extends TextualPointScene { constructor() { super(); this.type = "text"; this.append([this.label, this.handle]); } static is(value) { return AnnotationScene.isCheck( value, "text" /* Text */ ); } getHandleCoords(_datum, point) { const halfSize = DivariantHandle.HANDLE_SIZE / 2; return { x: point.x + halfSize, y: point.y + 2 + halfSize }; } }; var TextStateMachine = class extends TextualPointStateMachine { createDatum() { return new TextProperties(); } }; var textConfig = { type: "text", datum: TextProperties, scene: TextScene, isDatum: TextProperties.is, translate: (node, datum, transition, context) => { if (TextProperties.is(datum) && TextScene.is(node)) node.translate(datum, transition, context); }, copy: (node, datum, copiedDatum, context) => { if (TextProperties.is(datum) && TextProperties.is(copiedDatum) && TextScene.is(node)) { return node.copy(datum, copiedDatum, context); } }, update: (node, datum, context) => { if (TextProperties.is(datum) && TextScene.is(node)) { node.update(datum, context); } }, createState: (ctx, { createDatum }) => new TextStateMachine({ ...ctx, create: createDatum( "text" /* Text */ ) }), dragState: (ctx) => new DragStateMachine(ctx) }; var annotationConfigs = { // Lines [lineConfig.type]: lineConfig, [horizontalLineConfig.type]: horizontalLineConfig, [verticalLineConfig.type]: verticalLineConfig, // Channels [parallelChannelConfig.type]: parallelChannelConfig, [disjointChannelConfig.type]: disjointChannelConfig, // Fibonaccis [fibonacciRetracementConfig.type]: fibonacciRetracementConfig, [fibonacciRetracementTrendBasedConfig.type]: fibonacciRetracementTrendBasedConfig, // Texts [calloutConfig.type]: calloutConfig, [commentConfig.type]: commentConfig, [noteConfig.type]: noteConfig, [textConfig.type]: textConfig, // Shapes [arrowConfig.type]: arrowConfig, [arrowUpConfig.type]: arrowUpConfig, [arrowDownConfig.type]: arrowDownConfig, // Measurers [dateRangeConfig.type]: dateRangeConfig, [priceRangeConfig.type]: priceRangeConfig, [datePriceRangeConfig.type]: datePriceRangeConfig, [quickDatePriceRangeConfig.type]: quickDatePriceRangeConfig }; function getTypedDatum(datum) { for (const { isDatum } of Object.values(annotationConfigs)) { if (isDatum(datum)) { return datum; } } } var import_ag_charts_community93 = (init_main4(), __toCommonJS(main_exports)); var { ActionOnSet: ActionOnSet2, ParallelStateMachine: ParallelStateMachine2, StateMachine: StateMachine11, StateMachineProperty: StateMachineProperty11, Debug: Debug11 } = import_ag_charts_community93._ModuleSupport; var AnnotationsStateMachine = class extends ParallelStateMachine2 { constructor(ctx) { super( new SnappingStateMachine((snapping) => { this.snapping = snapping; }), new UpdateMachine(() => { this.node = this.active == null ? void 0 : ctx.node(this.active); }), new AnnotationsMainStateMachine(ctx, (index) => { this.active = index; this.datum = this.active == null ? void 0 : ctx.datum(this.active); this.node = this.active == null ? void 0 : ctx.node(this.active); }) ); this.snapping = false; } // TODO: remove this leak getActive() { return this.active; } // TODO: remove this leak isActive(index) { return index === this.active; } }; __decorateClass2([ StateMachineProperty11() ], AnnotationsStateMachine.prototype, "snapping", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsStateMachine.prototype, "node", 2); var SnappingStateMachine = class extends StateMachine11 { constructor(setSnapping) { super("idle", { [ "idle" /* Idle */ ]: { hover: ({ shiftKey }) => setSnapping(shiftKey), keyDown: ({ shiftKey }) => setSnapping(shiftKey), keyUp: ({ shiftKey }) => setSnapping(shiftKey), click: ({ shiftKey }) => setSnapping(shiftKey), drag: ({ shiftKey }) => setSnapping(shiftKey) }, [ "dragging" /* Dragging */ ]: {}, [ "text-input" /* TextInput */ ]: {} }); } }; var UpdateMachine = class extends StateMachine11 { constructor(update) { super("idle", { [ "idle" /* Idle */ ]: { onEnter: update, render: update }, [ "dragging" /* Dragging */ ]: { onEnter: update, render: update }, [ "text-input" /* TextInput */ ]: { render: update } }); } }; var AnnotationsMainStateMachine = class extends StateMachine11 { constructor(ctx, setActive) { const createDatum = (type) => (datum) => { ctx.create(type, datum); this.active = ctx.selectLast(); }; const deleteDatum = () => { if (this.active != null) ctx.delete(this.active); this.active = void 0; ctx.select(); }; const stateMachineHelpers = { createDatum }; const createStateMachineContext = { ...ctx, delete: deleteDatum, showTextInput: () => { if (this.active != null) ctx.showTextInput(this.active); }, deselect: () => { const prevActive = this.active; this.active = void 0; this.hovered = void 0; ctx.select(this.active, prevActive); }, showAnnotationOptions: () => { if (this.active != null) ctx.showAnnotationOptions(this.active); } }; const createStateMachines = Object.fromEntries( Object.entries(annotationConfigs).map(([type, config]) => [ type, config.createState(createStateMachineContext, stateMachineHelpers) ]) ); const dragStateMachines = Object.fromEntries( Object.entries(annotationConfigs).map(([type, config]) => [ type, config.dragState(ctx, stateMachineHelpers) ]) ); const actionColor = ({ colorPickerType, colorOpacity, color, opacity, isMultiColor }) => { if (!this.datum) return; if (colorPickerType === "text-color") { ctx.updateTextInputColor(color); } setColor(this.datum, colorPickerType, colorOpacity, color, opacity, isMultiColor); ctx.update(); }; const actionFontSize = (fontSize) => { const { datum, node } = this; if (!datum || !node) return; if (isTextType(datum)) { datum.fontSize = fontSize; ctx.updateTextInputFontSize(fontSize); } else if (hasLineText(datum)) { datum.text.fontSize = fontSize; } ctx.update(); }; const actionLineStyle = (lineStyle) => { const { datum, node } = this; if (!datum || !node || !hasLineStyle(datum)) return; setLineStyle(datum, lineStyle); ctx.update(); }; const actionUpdateTextInputBBox = (bbox) => { const { node } = this; if (!node || !("setTextInputBBox" in node)) return; node.setTextInputBBox(bbox); ctx.update(); }; const actionSaveText = ({ textInputValue, bbox }) => { const { datum } = this; if (bbox != null && textInputValue != null && textInputValue.length > 0) { if (!isTextType(datum)) { return; } const wrappedText = wrapText(datum, textInputValue, bbox.width); datum.set({ text: wrappedText }); ctx.update(); ctx.recordAction(`Change ${datum.type} annotation text`); } else { ctx.delete(this.active); ctx.recordAction(`Delete ${datum?.type} annotation`); } }; const actionCancel = () => { ctx.updateTextInputBBox(void 0); }; const guardActive = () => this.active != null; const guardCopied = () => this.copied != null; const guardActiveHasLineText = () => { const { active, datum } = this; if (active == null) return false; if (!datum) return false; return hasLineText(datum) && !datum.locked; }; const guardActiveNotEphemeral = () => this.active != null && !isEphemeralType(this.datum); const guardHovered = () => this.hovered != null; super("idle", { [ "idle" /* Idle */ ]: { onEnter: () => { ctx.select(this.active, this.active); if (this.hoverCoords) { this.hovered = ctx.hoverAtCoords(this.hoverCoords, this.active, this.hovered); } }, hover: ({ offset: offset4 }) => { this.hovered = ctx.hoverAtCoords(offset4, this.active, this.hovered); this.hoverCoords = offset4; }, translate: { guard: guardActive, action: ({ translation }) => { ctx.startInteracting(); ctx.translate(this.active, translation); ctx.update(); } }, translateEnd: { guard: guardActive, action: () => { ctx.stopInteracting(); } }, copy: { guard: guardActiveNotEphemeral, action: () => { this.copied = ctx.copy(this.active); } }, cut: { guard: guardActiveNotEphemeral, action: () => { this.copied = ctx.copy(this.active); deleteDatum(); } }, paste: { guard: guardCopied, action: () => { ctx.paste(this.copied); } }, selectLast: () => { const previousActive = this.active; this.active = ctx.selectLast(); ctx.select(this.active, previousActive); }, click: [ { guard: () => { const { active, hovered, datum } = this; if (active == null || hovered !== active) return false; if (!datum) return false; return isTextType(datum) && !datum.locked; }, target: "text-input" /* TextInput */ }, { action: () => { const prevActive = this.active; this.active = this.hovered; ctx.select(this.active, prevActive); } } ], dblclick: { guard: guardActiveHasLineText, action: ({ offset: offset4 }) => { const nodeAtCoords = ctx.getNodeAtCoords(offset4, this.active) === "text" ? "text" : "line"; ctx.showAnnotationSettings(this.active, void 0, nodeAtCoords); } }, dragStart: [ { guard: guardHovered, target: "dragging", action: () => { const prevActive = this.active; this.active = this.hovered; ctx.select(this.active, prevActive); ctx.startInteracting(); } }, { action: () => { const prevActive = this.active; this.active = this.hovered; ctx.select(this.active, prevActive); } } ], color: { guard: guardActive, action: actionColor }, fontSize: { guard: guardActive, action: actionFontSize }, lineProps: { guard: guardActive, action: (props) => { const datum = getTypedDatum(this.datum); datum?.set(props); ctx.update(); ctx.recordAction( `Change ${datum?.type} ${Object.entries(props).map(([key, value]) => `${key} to ${value}`).join(", ")}` ); } }, lineStyle: { guard: guardActive, action: actionLineStyle }, lineText: { guard: guardActive, action: (props) => { const datum = getTypedDatum(this.datum); if (!hasLineText(datum)) return; if (isChannelType(datum) && props.position === "center") { props.position = "inside"; } datum.text.set(props); ctx.update(); } }, updateTextInputBBox: { guard: guardActive, action: actionUpdateTextInputBBox }, toolbarPressSettings: { guard: guardActiveHasLineText, action: (sourceEvent) => { ctx.showAnnotationSettings(this.active, sourceEvent); } }, reset: () => { if (this.active != null) { this.node?.toggleActive(false); } this.hovered = void 0; this.active = void 0; ctx.select(this.active, this.active); ctx.resetToIdle(); }, delete: () => { if (this.active == null) return; ctx.delete(this.active); if (isEphemeralType(this.datum)) return; ctx.recordAction(`Delete ${this.datum?.type} annotation`); }, deleteAll: () => { ctx.deleteAll(); }, ...createStateMachines }, [ "dragging" /* Dragging */ ]: { onEnter: (_, data) => { if (this.active == null) return; const type = ctx.getAnnotationType(this.active); if (!type) return; this.transitionRoot(type); this.transitionRoot("dragStart", data); }, ...dragStateMachines }, [ "text-input" /* TextInput */ ]: { onEnter: () => { if (this.active == null) return; const datum = getTypedDatum(this.datum); if (!datum || !("getTextInputCoords" in datum)) return; ctx.startInteracting(); ctx.showTextInput(this.active); datum.visible = false; ctx.update(); }, updateTextInputBBox: { guard: guardActive, action: actionUpdateTextInputBBox }, resize: { target: "idle", action: actionSaveText }, click: { target: "idle", action: actionSaveText }, drag: { target: "idle", action: actionSaveText }, textInput: [ { guard: guardCancelAndExit, target: "idle", action: actionCancel }, { guard: guardSaveAndExit, target: "idle", action: actionSaveText } ], color: { guard: guardActive, action: actionColor }, fontSize: { guard: guardActive, action: actionFontSize }, cancel: { target: "idle", action: actionCancel }, onExit: () => { ctx.stopInteracting(); ctx.hideTextInput(); const wasActive = this.active; this.active = this.hovered = void 0; ctx.select(this.active, wasActive); if (wasActive == null) return; const datum = ctx.datum(wasActive); const node = ctx.node(wasActive); if (!datum || !node) return; datum.visible = true; } } }); this.setActive = setActive; this.debug = Debug11.create(true, "annotations"); this.snapping = false; } }; __decorateClass2([ ActionOnSet2({ changeValue(newValue) { this.setActive(newValue); } }), StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "active", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "hovered", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "hoverCoords", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "copied", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "snapping", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "datum", 2); __decorateClass2([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "node", 2); var import_ag_charts_community94 = (init_main4(), __toCommonJS(main_exports)); var { ARRAY: ARRAY3, BOOLEAN: BOOLEAN9, UNION: UNION6, POSITIVE_NUMBER: POSITIVE_NUMBER5, ActionOnSet: ActionOnSet22, LayoutElement: LayoutElement2, Menu: Menu22, PropertiesArray: PropertiesArray22, ToolbarButtonProperties: ToolbarButtonProperties22, Validate: Validate30, ChartAxisDirection: ChartAxisDirection9 } = import_ag_charts_community94._ModuleSupport; var AnnotationsToolbarButtonProperties = class extends ToolbarButtonProperties22 { }; __decorateClass2([ Validate30(UNION6(["line-menu", "fibonacci-menu", "text-menu", "shape-menu", "measurer-menu", "clear"])) ], AnnotationsToolbarButtonProperties.prototype, "value", 2); var AnnotationsToolbar = class extends import_ag_charts_community94._ModuleSupport.BaseProperties { constructor(ctx) { super(); this.ctx = ctx; this.enabled = true; this.padding = 20; this.buttons = new PropertiesArray22(AnnotationsToolbarButtonProperties); this.events = new import_ag_charts_community94._ModuleSupport.Listeners(); this.annotationMenu = new Menu22(this.ctx, "annotations"); this.destroyFns = []; this.toolbar = ctx.sharedToolbar.getSharedToolbar("annotations"); const onKeyDown = this.onKeyDown.bind(this); this.toolbar.addListener("keydown", onKeyDown); this.destroyFns.push( this.toolbar.addToolbarListener("button-pressed", this.onToolbarButtonPress.bind(this)), ctx.layoutManager.registerElement(LayoutElement2.ToolbarLeft, this.onLayoutStart.bind(this)), () => { this.toolbar.removeListener("keydown", onKeyDown); this.toolbar.destroy(); } ); } destroy() { for (const destroyFn of this.destroyFns) { destroyFn(); } } addListener(eventType, handler) { return this.events.addListener(eventType, handler); } toggleVisibility(visible) { this.toolbar.setHidden(!visible); } toggleClearButtonEnabled(enabled) { const index = this.buttons.findIndex((button) => button.value === "clear"); this.toolbar.toggleButtonEnabledByIndex(index, enabled); } resetButtonIcons() { for (const [index, button] of this.buttons.entries()) { switch (button.value) { case "line-menu": this.updateButtonByIndex(index, { icon: "trend-line-drawing", value: "line-menu" }); break; case "fibonacci-menu": this.updateButtonByIndex(index, { icon: "fibonacci-retracement-drawing", value: "fibonacci-menu" }); break; case "text-menu": this.updateButtonByIndex(index, { icon: "text-annotation", value: "text-menu" }); break; case "shape-menu": this.updateButtonByIndex(index, { icon: "arrow-drawing", value: "shape-menu" }); break; case "measurer-menu": this.updateButtonByIndex(index, { icon: "measurer-drawing", value: "measurer-menu" }); break; } } } hideOverlays() { this.annotationMenu.hide(); } clearActiveButton() { this.toolbar.clearActiveButton(); } dispatch(eventType, event) { this.events.dispatch(eventType, event); } onLayoutStart(event) { if (!this.enabled) return; this.toolbar.updateButtons(this.buttons); this.toolbar.layout(event.layoutBox, this.padding); } refreshButtonsEnabled(enabled) { for (const [index, button] of this.buttons.entries()) { if (!button) continue; this.toolbar.toggleButtonEnabledByIndex(index, enabled); } } onToolbarButtonPress({ event, button, buttonBounds }) { const axisScale = this.ctx.axisManager.getAxisContext(ChartAxisDirection9.Y)[0].scale; switch (button.value) { case "clear": this.dispatch("pressed-clear"); break; case "line-menu": this.onToolbarButtonPressShowMenu( event, buttonBounds, button.value, "toolbarAnnotationsLineAnnotations", LINE_ANNOTATION_ITEMS.filter((item) => item.visible ? item.visible(axisScale) : true) ); break; case "fibonacci-menu": this.onToolbarButtonPressShowMenu( event, buttonBounds, button.value, "toolbarAnnotationsFibonacciAnnotations", FIBONACCI_ANNOTATION_ITEMS ); break; case "text-menu": this.onToolbarButtonPressShowMenu( event, buttonBounds, button.value, "toolbarAnnotationsTextAnnotations", TEXT_ANNOTATION_ITEMS ); break; case "shape-menu": this.onToolbarButtonPressShowMenu( event, buttonBounds, button.value, "toolbarAnnotationsShapeAnnotations", SHAPE_ANNOTATION_ITEMS ); break; case "measurer-menu": this.onToolbarButtonPressShowMenu( event, buttonBounds, button.value, "toolbarAnnotationsMeasurerAnnotations", MEASURER_ANNOTATION_ITEMS ); break; } } onToolbarButtonPressShowMenu(event, buttonBounds, menu, ariaLabel, items) { this.dispatch("pressed-show-menu"); const index = this.buttons.findIndex((button) => button.value === menu); this.toolbar.toggleActiveButtonByIndex(index); this.annotationMenu.setAnchor({ x: buttonBounds.x + buttonBounds.width + 6, y: buttonBounds.y }); this.annotationMenu.show({ items, ariaLabel: this.ctx.localeManager.t(ariaLabel), class: "ag-charts-annotations__toolbar-menu", sourceEvent: event.sourceEvent, onPress: this.onButtonPressMenuCreateAnnotation.bind(this, menu) }); } onButtonPressMenuCreateAnnotation(menu, item) { const index = this.buttons.findIndex((button) => button.value === menu); this.updateButtonByIndex(index, { icon: item.icon }); this.dispatch("pressed-create-annotation", { annotation: item.value }); this.annotationMenu.hide(); } onKeyDown({ sourceEvent }) { if (sourceEvent.key === "Escape") { this.dispatch("cancel-create-annotation"); } } updateButtonByIndex(index, change) { const button = this.buttons.at(index); if (!button) return; button.set({ ...button.toJson(), ...change, value: change.value ?? button.value }); this.toolbar.updateButtonByIndex(index, { ...button.toJson() }); } }; __decorateClass2([ Validate30(BOOLEAN9), ActionOnSet22({ changeValue(enabled) { this.toolbar?.setHidden(!enabled); } }) ], AnnotationsToolbar.prototype, "enabled", 2); __decorateClass2([ Validate30(POSITIVE_NUMBER5) ], AnnotationsToolbar.prototype, "padding", 2); __decorateClass2([ Validate30(ARRAY3) ], AnnotationsToolbar.prototype, "buttons", 2); var import_ag_charts_community95 = (init_main4(), __toCommonJS(main_exports)); var { BaseModuleInstance: BaseModuleInstance2, InteractionState: InteractionState2, Validate: Validate31, BOOLEAN: BOOLEAN10, ChartAxisDirection: ChartAxisDirection10, getIconClassNames: getIconClassNames2 } = import_ag_charts_community95._ModuleSupport; var DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS = `ag-charts-annotations__axis-button`; var AxisButton = class extends BaseModuleInstance2 { constructor(ctx, axisCtx, onButtonClick, seriesRect) { super(); this.ctx = ctx; this.axisCtx = axisCtx; this.onButtonClick = onButtonClick; this.seriesRect = seriesRect; this.enabled = true; this.snap = false; this.padding = 0; this.button = this.setup(); this.toggleVisibility(false); this.updateButtonElement(); this.snap = Boolean(axisCtx.scale.bandwidth); ctx.domManager.addEventListener("focusin", ({ target }) => { const htmlTarget = target instanceof HTMLElement ? target : void 0; const isSeriesAreaChild = htmlTarget && ctx.domManager.contains(htmlTarget, "series-area"); if (!isSeriesAreaChild && htmlTarget !== this.button.getElement()) this.hide(); }); this.destroyFns.push( ctx.widgets.seriesWidget.addListener("drag-move", (e) => this.onMouseDrag(e)), ctx.widgets.seriesWidget.addListener("mousemove", (e) => this.onMouseMove(e)), ctx.widgets.seriesWidget.addListener("mouseleave", () => this.onMouseLeave()), ctx.widgets.seriesDragInterpreter.addListener("click", (e) => this.onClick(e)), ctx.chartEventManager.addListener("series-focus-change", () => this.onKeyPress()), ctx.zoomManager.addListener("zoom-pan-start", () => this.hide()), ctx.zoomManager.addListener("zoom-change", () => this.hide()), () => this.destroyElements(), () => this.button.destroy() ); } update(seriesRect, padding) { this.seriesRect = seriesRect; this.padding = padding; } setup() { const button = new import_ag_charts_community95._Widget.ButtonWidget(); button.addClass(DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS); button.setTabIndex(-1); button.setAriaLabel(this.ctx.localeManager.t("ariaLabelAddHorizontalLine")); this.ctx.widgets.seriesWidget.getElement().appendChild(button.getElement()); return button; } destroyElements() { this.ctx.domManager.removeChild("canvas-overlay", DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS); } onMouseMove(e) { if (this.ctx.interactionManager.isState(InteractionState2.Clickable)) this.show(e); } onMouseDrag(e) { if (this.ctx.interactionManager.isState(InteractionState2.AnnotationsMoveable)) this.show(e); } onMouseLeave() { if (this.ctx.interactionManager.isState(InteractionState2.Clickable)) this.hide(); } onClick(e) { if (this.ctx.interactionManager.isState(InteractionState2.Clickable) && e.device === "touch") this.show(e); } show(event) { const { sourceEvent, currentX: x, currentY: y } = event; if (!(this.enabled && this.ctx.widgets.seriesWidget.getElement().contains(sourceEvent.target))) { this.hide(); return; } this.toggleVisibility(true); const buttonCoords = this.getButtonCoordinates({ x, y }); this.coords = { x: buttonCoords.x + this.button.clientWidth / 2, y: buttonCoords.y + this.button.clientHeight / 2 }; this.updatePosition(buttonCoords); } hide() { this.toggleVisibility(false); } onKeyPress() { if (this.snap && this.ctx.interactionManager.isState(InteractionState2.Default)) return; this.hide(); } getButtonCoordinates({ x, y }) { const { axisCtx: { direction, position }, seriesRect, snap, axisCtx, padding } = this; const { clientWidth: buttonWidth, clientHeight: buttonHeight } = this.button; const [minY, maxY] = [0, seriesRect.height]; const [minX, maxX] = [0, seriesRect.width]; if (snap) { x = convert(invert(x - seriesRect.x, axisCtx), axisCtx) + seriesRect.x; y = convert(invert(y - seriesRect.y, axisCtx), axisCtx) + seriesRect.y; } if (direction === ChartAxisDirection10.X) { const crosshairLabelPadding = 5; const offset4 = buttonHeight - Math.max(0, padding - crosshairLabelPadding); x = x - buttonWidth / 2; y = position === "top" ? minY - buttonHeight + offset4 : maxY - offset4; } else { const crosshairLabelPadding = 9; const offset4 = buttonWidth - Math.max(0, padding - crosshairLabelPadding); x = position === "left" ? minX - buttonWidth + offset4 : maxX - offset4; y = y - buttonHeight / 2; } return { x, y }; } toggleVisibility(visible) { const { button } = this; if (button == null) return; const isVisible = this.enabled && visible; this.toggleClass("-hidden", !isVisible); } toggleClass(name, include) { this.button.toggleClass(`${DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS}-${name}`, include); } updatePosition({ x, y }) { this.button.getElement().style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`; } updateButtonElement() { const { button } = this; button.addListener("click", () => this.onButtonClick(this.coords)); button.addListener("touchend", () => this.onButtonClick(this.coords)); button.addListener("drag-start", () => { }); button.setInnerHTML( `` ); } }; __decorateClass2([ Validate31(BOOLEAN10) ], AxisButton.prototype, "enabled", 2); var import_ag_charts_community97 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community96 = (init_main4(), __toCommonJS(main_exports)); var { Color: Color5, DraggablePopover: DraggablePopover2, NativeWidget: NativeWidget2, Vec2: Vec218, createButton: createButton2, createCheckbox: createCheckbox2, createElementId: createElementId2, createSelect: createSelect2, createTextArea: createTextArea2, initRovingTabIndex: initRovingTabIndex2, getIconClassNames: getIconClassNames22, mapValues: mapValues2, setAttribute: setAttribute2, setAttributes: setAttributes2, createElement: createElement22, getWindow: getWindow2 } = import_ag_charts_community96._ModuleSupport; var _Dialog = class _Dialog2 extends DraggablePopover2 { constructor(ctx, id) { super(ctx, id); this.dragHandleDraggingClass = "ag-charts-dialog__drag-handle--dragging"; this.colorPicker = new ColorPicker(this.ctx, { detached: true }); this.destroyFns.push(ctx.layoutManager.addListener("layout:complete", this.onLayoutComplete.bind(this))); } showWithChildren(children, options) { const popover = super.showWithChildren(children, options); popover.classList.add("ag-charts-dialog"); popover.setAttribute("role", "dialog"); popover.addEventListener("mousedown", (event) => { if (event.target.classList?.contains("ag-charts-dialog__color-picker-button")) return; this.colorPicker.hide(); }); popover.addEventListener("keydown", this.onKeyDown.bind(this)); getWindow2().requestAnimationFrame(() => this.reposition()); this.colorPicker.attachTo(this); return popover; } updatePosition(position) { super.updatePosition(position); const { anchor, fallbackAnchor } = this.getColorPickerAnchors() ?? {}; if (!anchor) return; this.colorPicker.setAnchor(anchor, fallbackAnchor); } /************** * Containers * **************/ createTabs(tablistLabel, initial, tabs) { const element2 = createElement22("div", "ag-charts-dialog__tabs"); const tabButtonIds = mapValues2(tabs, () => createElementId2("ag-charts-dialog__tab")); const tabPanelIds = mapValues2(tabs, () => createElementId2("ag-charts-dialog__tab-panel")); for (const [key, tab] of Object.entries(tabs)) { setAttributes2(tab.panel, { id: tabPanelIds[key], role: "tabpanel", "aria-labelledby": tabButtonIds[key] }); } const onPressTab = (active) => { for (const [key, tab] of Object.entries(tabs)) { tab.panel.classList.toggle("ag-charts-dialog__tab-panel--active", key === active); tabButtons[key].classList.toggle("ag-charts-dialog__tab-button--active", key === active); setAttribute2(tabButtons[key], "aria-selected", key === active); if (key === active) tab.onShow?.(); } }; const header = new NativeWidget2(createElement22("div", "ag-charts-dialog__header")); header.addListener("drag-start", (event) => { const { sourceEvent } = event; if (sourceEvent.target instanceof Element && sourceEvent.target.classList.contains("ag-charts-dialog__header")) { this.onDragStart(event); } }); header.addListener("drag-move", (event) => this.onDragMove(event)); header.addListener("drag-end", () => this.onDragEnd()); const dragHandle = new DragHandleWidget2(); this.setDragHandle(dragHandle); const tabButtons = mapValues2( tabs, (tab, key) => createButton2( { label: this.ctx.localeManager.t(tab.label), onPress: () => onPressTab(key) }, { id: tabButtonIds[key], class: "ag-charts-dialog__tab-button", role: "tab", "aria-controls": tabPanelIds[key] } ) ); const tabList = createElement22("div", "ag-charts-dialog__tab-list"); setAttributes2(tabList, { role: "tablist", "aria-label": this.ctx.localeManager.t(tablistLabel) }); tabList.append(...Object.values(tabButtons)); const closeButton = this.createHeaderCloseButton(); header.getElement().append(dragHandle.getElement(), tabList, closeButton); element2.append(header.getElement(), ...Object.values(tabs).map((t) => t.panel)); onPressTab(initial); initRovingTabIndex2({ orientation: "horizontal", buttons: Object.values(tabButtons) }); return { tabs: element2, initialFocus: tabButtons[initial] }; } createTabPanel() { return createElement22("div", "ag-charts-dialog__tab-panel"); } /********** * Inputs * **********/ createInputGroupLine() { return createElement22("div", "ag-charts-dialog__input-group-line"); } createRadioGroup({ label, options, value, onChange }) { const group = this.createInputGroup(label); setAttributes2(group, { role: "radiogroup", tabindex: -1, "aria-label": this.ctx.localeManager.t(label) }); const activeClass = "ag-charts-dialog__button--active"; const buttons2 = []; for (const button of options) { const { icon, altText: altTextKey } = button; const altText = this.ctx.localeManager.t(altTextKey); const buttonEl = createButton2( { icon, altText, onPress: () => { for (const b of Array.from(group.children)) { b.classList.remove(activeClass); b.ariaChecked = "false"; } buttonEl.classList.add(activeClass); buttonEl.ariaChecked = "true"; onChange(button.value); } }, { "aria-checked": button.value === value, class: "ag-charts-dialog__button", role: "radio", title: altText } ); if (button.value === value) { buttonEl.classList.add(activeClass); } group.appendChild(buttonEl); buttons2.push(buttonEl); } initRovingTabIndex2({ orientation: "horizontal", buttons: buttons2 }); return group; } createSelect({ altText, label, options, value, onChange }) { const group = this.createInputGroup(label); const altTextT = this.ctx.localeManager.t(altText); const select = createSelect2( { value, options, onChange }, { class: "ag-charts-dialog__select", "aria-label": altTextT, title: altTextT } ); group.append(select); return group; } createTextArea({ placeholder, value, onChange }) { const placeholderT = placeholder ? this.ctx.localeManager.t(placeholder) : void 0; return createTextArea2({ value, onChange }, { placeholder: placeholderT }); } createCheckbox({ label, checked, onChange }) { const id = `ag-charts__${label}`; const group = this.createInputGroup(label, { for: id }); const checkbox = createCheckbox2( { checked, onChange }, { class: "ag-charts-dialog__checkbox", role: "switch", id } ); group.append(checkbox); return group; } createColorPicker({ color, opacity, label, altText, onChange, onChangeHide, isMultiColor, hasMultiColorOption }) { const group = this.createInputGroup(label); const altTextT = this.ctx.localeManager.t(altText); const colorEl = createButton2( { label: altTextT, onPress: (event) => { const { anchor, fallbackAnchor } = this.getColorPickerAnchors(colorEl) ?? {}; this.colorPicker.show({ anchor, fallbackAnchor, color, opacity, isMultiColor, hasMultiColorOption, sourceEvent: event, onChange: (newColorOpacity, newColor, newOpacity, newIsMultiColor) => { colorEl.style.setProperty("--color", newColorOpacity); colorEl.classList.toggle( "ag-charts-dialog__color-picker-button--multi-color", newIsMultiColor ); onChange(newColorOpacity, newColor, newOpacity, newIsMultiColor); }, onChangeHide }); } }, { "aria-label": altTextT, tabindex: 0, class: "ag-charts-dialog__color-picker-button", title: altTextT } ); if (isMultiColor) { colorEl.classList.toggle("ag-charts-dialog__color-picker-button--multi-color"); } else if (color) { const hex = Color5.fromString(color); const hexWithOpacity = new Color5(hex.r, hex.g, hex.b, opacity); colorEl.style.setProperty("--color", hexWithOpacity.toHexString()); } group.append(colorEl); this.hideFns.push(() => { this.colorPicker.hide(); }); return group; } /*********** * Private * ***********/ createHeaderCloseButton() { return createButton2( { icon: "close", altText: this.ctx.localeManager.t("iconAltTextClose"), onPress: () => this.hide() }, { class: "ag-charts-dialog__close-button" } ); } createInputGroup(label, options) { const group = createElement22("div", "ag-charts-dialog__input-group"); const labelEl = createElement22("label", "ag-charts-dialog__input-group-label"); labelEl.innerText = this.ctx.localeManager.t(label); if (options?.for) labelEl.setAttribute("for", options.for); group.appendChild(labelEl); return group; } onLayoutComplete(event) { this.seriesRect = event.series.paddedRect; this.reposition(); } onKeyDown(event) { if (event.altKey || event.ctrlKey || event.metaKey || event.isComposing || event.key !== "Escape") return; this.hide(); } reposition() { const { seriesRect, ctx } = this; const clientRect = ctx.domManager.getBoundingClientRect(); const popover = this.getPopoverElement(); if (!seriesRect || !popover) return; const outerOffset = Vec218.from(0, seriesRect.y); const outerSize = Vec218.from(clientRect.width, seriesRect.height); const popoverSize = Vec218.from(popover); const halfWidth = Vec218.from(0.5, 1); let position; if (seriesRect.width > 1e3) { const bottomCenter2 = Vec218.sub( Vec218.add(outerOffset, Vec218.multiply(outerSize, halfWidth)), Vec218.multiply(popoverSize, halfWidth) ); position = Vec218.sub(bottomCenter2, Vec218.from(0, _Dialog2.offset)); } else { const bottomRight = Vec218.sub(Vec218.add(outerOffset, outerSize), popoverSize); position = Vec218.sub(bottomRight, _Dialog2.offset); } this.updatePosition(position); } getColorPickerAnchors(element2) { if (element2) this.colorPickerAnchorElement = element2; if (!this.colorPickerAnchorElement) return; const rect = this.colorPickerAnchorElement.getBoundingClientRect(); const canvasRect = this.ctx.domManager.getBoundingClientRect(); const topLeft = Vec218.sub(Vec218.from(rect.x, rect.y), Vec218.from(canvasRect.left, canvasRect.top)); const anchor = Vec218.add(topLeft, Vec218.from(0, rect.height + 5)); const fallbackAnchor = Vec218.sub(topLeft, Vec218.from(0, 5)); return { anchor, fallbackAnchor }; } }; _Dialog.offset = 60; var Dialog = _Dialog; var DragHandleWidget2 = class extends NativeWidget2 { constructor() { super(createElement22("div", "ag-charts-dialog__drag-handle")); const icon = new NativeWidget2(createElement22("span", getIconClassNames22("drag-handle"))); icon.setAriaHidden(true); this.addChild(icon); } }; var { Listeners: Listeners22, focusCursorAtEnd: focusCursorAtEnd22 } = import_ag_charts_community97._ModuleSupport; var AnnotationSettingsDialog = class extends Dialog { constructor(ctx) { super(ctx, "settings"); this.events = new Listeners22(); this.hideFns.push(() => this.events.dispatch("hidden")); } addListener(eventType, handler) { return this.events.addListener(eventType, handler); } show(datum, options) { const lineTab = this.createLinearLineTab(datum, options); const textTab = this.createLinearTextTab(datum, options); let lineLabel = "dialogHeaderLine"; if (isChannelType(datum)) { lineLabel = "dialogHeaderChannel"; } else if (isFibonacciType(datum)) { lineLabel = "dialogHeaderFibonacciRange"; } else if (datum.type === "date-range") { lineLabel = "dialogHeaderDateRange"; } else if (datum.type === "price-range") { lineLabel = "dialogHeaderPriceRange"; } else if (datum.type === "date-price-range") { lineLabel = "dialogHeaderDatePriceRange"; } const { tabs, initialFocus } = this.createTabs("ariaLabelSettingsTabBar", options.initialSelectedTab, { line: { label: lineLabel, panel: lineTab }, text: { label: "dialogHeaderText", panel: textTab.panel, onShow: textTab.onShow } }); options.initialFocus = initialFocus; const popover = this.showWithChildren([tabs], options); popover.classList.add("ag-charts-dialog--annotation-settings"); } createLinearLineTab(datum, options) { const panel = this.createTabPanel(); const groupOne = this.createInputGroupLine(); const groupTwo = this.createInputGroupLine(); const hasMultiColorOption = "isMultiColor" in datum; const lineColorPicker = this.createColorPickerInput( "line-color", datum.getDefaultColor("line-color"), datum.getDefaultOpacity("line-color"), hasMultiColorOption ? datum.isMultiColor : false, hasMultiColorOption, options.onChangeLineColor, options.onChangeHideLineColor ); const strokeWidth = this.createStrokeWidthSelect(datum.strokeWidth ?? 2, options.onChangeLineStyleWidth); const lineStyle = this.createLineStyleRadioGroup(datum.lineStyle ?? "solid", options.onChangeLineStyleType); groupOne.append(lineColorPicker); if ("background" in datum) { const fillColorPicker = this.createColorPickerInput( "fill-color", datum.getDefaultColor("fill-color"), datum.getDefaultOpacity("fill-color"), false, false, options.onChangeFillColor, options.onChangeHideFillColor ); groupOne.append(fillColorPicker); groupTwo.append(strokeWidth); } else if ("showFill" in datum) { groupOne.append( this.createCheckbox({ label: "dialogInputShowFill", checked: datum.showFill ?? true, onChange: (showFill) => options.onChangeLine({ showFill }) }) ); groupTwo.append(strokeWidth); } else { groupOne.append(strokeWidth); } groupTwo.append(lineStyle); panel.append(groupOne, groupTwo); if ("bands" in datum) { panel.append( this.createFibonacciRatioSelect(datum.bands ?? 10, (bands) => options.onChangeLine({ bands })) ); } if ("extendStart" in datum && "extendEnd" in datum) { panel.append( this.createCheckbox({ label: isChannelType(datum) ? "dialogInputExtendChannelStart" : "dialogInputExtendLineStart", checked: datum.extendStart ?? false, onChange: (extendStart) => options.onChangeLine({ extendStart }) }), this.createCheckbox({ label: isChannelType(datum) ? "dialogInputExtendChannelEnd" : "dialogInputExtendLineEnd", checked: datum.extendEnd ?? false, onChange: (extendEnd) => options.onChangeLine({ extendEnd }) }) ); } if ("extendAbove" in datum && "extendBelow" in datum) { panel.append( this.createCheckbox({ label: "dialogInputExtendAbove", checked: datum.extendAbove ?? false, onChange: (extendAbove) => options.onChangeLine({ extendAbove }) }), this.createCheckbox({ label: "dialogInputExtendBelow", checked: datum.extendBelow ?? false, onChange: (extendBelow) => options.onChangeLine({ extendBelow }) }) ); } if ("extendLeft" in datum && "extendRight" in datum) { panel.append( this.createCheckbox({ label: "dialogInputExtendLeft", checked: datum.extendLeft ?? false, onChange: (extendLeft) => options.onChangeLine({ extendLeft }) }), this.createCheckbox({ label: "dialogInputExtendRight", checked: datum.extendRight ?? false, onChange: (extendRight) => options.onChangeLine({ extendRight }) }) ); } if ("reverse" in datum && "showFill" in datum) { panel.append( this.createCheckbox({ label: "dialogInputReverse", checked: datum.reverse ?? false, onChange: (reverse) => options.onChangeLine({ reverse }) }) ); } return panel; } createLinearTextTab(datum, options) { const panel = this.createTabPanel(); const textArea = this.createTextArea({ placeholder: "inputTextareaPlaceholder", value: datum.text.label, onChange: (value) => options.onChangeText({ label: value }) }); const fontSize = this.createFontSizeSelect(datum.text.fontSize, options.onChangeTextFontSize); const colorPicker = this.createColorPickerInput( "text-color", datum.text.color, 1, false, false, options.onChangeTextColor, options.onChangeHideTextColor ); const textPosition = datum.text.position === "inside" ? "center" : datum.text.position; const position = this.createPositionRadioGroup( textPosition ?? "top", (value) => options.onChangeText({ position: value }) ); const alignment = this.createAlignmentRadioGroup( datum.text.alignment ?? "center", (value) => options.onChangeText({ alignment: value }) ); const inputGroupLine = this.createInputGroupLine(); inputGroupLine.append(fontSize, colorPicker, position, alignment); panel.append(textArea, inputGroupLine); return { panel, onShow: () => focusCursorAtEnd22(textArea) }; } createColorPickerInput(colorType, color, opacity, isMultiColor, hasMultiColorOption, onChange, onChangeHide) { const label = colorType === "fill-color" ? "dialogInputFillColorPicker" : "dialogInputColorPicker"; const altText = colorType === "fill-color" ? "dialogInputFillColorPickerAltText" : "dialogInputColorPickerAltText"; return this.createColorPicker({ label, altText, color, opacity, isMultiColor, hasMultiColorOption, onChange, onChangeHide }); } createStrokeWidthSelect(strokeWidth, onChange) { return this.createSelect({ label: "dialogInputStrokeWidth", altText: "dialogInputStrokeWidthAltText", options: LINE_STROKE_WIDTH_ITEMS.map(({ label, value }) => ({ label, value: `${value}` })), value: String(strokeWidth), onChange: (value) => onChange(Number(value)) }); } createFibonacciRatioSelect(bands, onChange) { return this.createSelect({ label: "dialogInputFibonacciBands", altText: "dialogInputFibonacciBandsAltText", options: FIBONACCI_RATIO_ITEMS.map(({ label, value }) => ({ label, value: `${value}` })), value: String(bands), onChange: (value) => onChange(Number(value)) }); } createLineStyleRadioGroup(lineStyle, onChange) { return this.createRadioGroup({ label: "dialogInputLineStyle", options: [ { icon: "line-style-solid", altText: "iconAltTextLineStyleSolid", value: "solid" }, { icon: "line-style-dashed", altText: "iconAltTextLineStyleDashed", value: "dashed" }, { icon: "line-style-dotted", altText: "iconAltTextLineStyleDotted", value: "dotted" } ], value: lineStyle, onChange }); } createFontSizeSelect(fontSize, onChange) { return this.createSelect({ label: "dialogInputFontSize", altText: "dialogInputFontSizeAltText", options: TEXT_SIZE_ITEMS.map(({ label, value }) => ({ label, value: String(value) })), value: String(fontSize), onChange: (value) => onChange(Number(value)) }); } createPositionRadioGroup(position, onChange) { return this.createRadioGroup({ label: "dialogInputPosition", options: [ { icon: "position-top", altText: "iconAltTextPositionTop", value: "top" }, { icon: "position-center", altText: "iconAltTextPositionCenter", value: "center" }, { icon: "position-bottom", altText: "iconAltTextPositionBottom", value: "bottom" } ], value: position, onChange }); } createAlignmentRadioGroup(alignment, onChange) { return this.createRadioGroup({ label: "dialogInputAlign", options: [ { icon: "align-left", altText: "iconAltTextAlignLeft", value: "left" }, { icon: "align-center", altText: "iconAltTextAlignCenter", value: "center" }, { icon: "align-right", altText: "iconAltTextAlignRight", value: "right" } ], value: alignment, onChange }); } }; function calculateAxisLabelPadding(axisLayout) { return axisLayout.gridPadding + axisLayout.seriesAreaPadding + axisLayout.tickSize + axisLayout.label.spacing; } function updateAnnotation(node, datum, context) { for (const { update } of Object.values(annotationConfigs)) { update(node, datum, context); } } var { BOOLEAN: BOOLEAN11, OBJECT: OBJECT14, ChartUpdateType: ChartUpdateType2, InteractionState: InteractionState22, ObserveChanges: ObserveChanges22, PropertiesArray: PropertiesArray3, Validate: Validate32, ChartAxisDirection: ChartAxisDirection11, Vec2: Vec219, keyProperty: keyProperty2, valueProperty: valueProperty2, Selection: Selection22, BBox: BBox3 } = import_ag_charts_community98._ModuleSupport; var _Annotations = class _Annotations2 extends import_ag_charts_community98._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = true; this.toolbar = new AnnotationsToolbar(this.ctx); this.optionsToolbar = new AnnotationOptionsToolbar(this.ctx, () => { const active = this.state.getActive(); if (active == null) return; return getTypedDatum(this.annotationData.at(active)); }); this.axesButtons = new AxesButtons(); this.snap = false; this.data = void 0; this.xKey = void 0; this.volumeKey = void 0; this.annotationData = new PropertiesArray3( _Annotations2.createAnnotationDatum ); this.defaults = new AnnotationDefaults(); this.container = new import_ag_charts_community98._ModuleSupport.Group({ name: "static-annotations" }); this.annotations = new Selection22( this.container, this.createAnnotationScene.bind(this) ); this.settingsDialog = new AnnotationSettingsDialog(this.ctx); this.textInput = new TextInput(this.ctx); this.restoreAnnotations = true; this.postUpdateFns = []; this.state = this.setupStateMachine(); this.setupListeners(); this.setupDOM(); this.ctx.historyManager.addMementoOriginator(ctx.annotationManager); this.ctx.historyManager.addMementoOriginator(this.defaults); this.textInput.setKeyDownHandler(this.onTextInput.bind(this)); } setupStateMachine() { const { ctx } = this; return new AnnotationsStateMachine({ resetToIdle: () => { ctx.domManager.updateCursor("annotations"); this.popAnnotationState(InteractionState22.Annotations); this.hideOverlays(); this.optionsToolbar.hide(); this.deleteEphemeralAnnotations(); this.update(); }, hoverAtCoords: (coords, active, previousHovered) => { let hovered; this.annotations.each((annotation, _, index) => { const contains = annotation.containsPoint(coords.x, coords.y); if (contains) hovered ?? (hovered = index); annotation.toggleHovered(contains || active === index); }); if (hovered != null) { ctx.tooltipManager.suppressTooltip("annotations"); } else if (!this.isAnnotationState()) { ctx.tooltipManager.unsuppressTooltip("annotations"); } this.ctx.domManager.updateCursor( "annotations", hovered == null ? void 0 : this.annotations.at(hovered)?.getCursor() ); if (hovered !== previousHovered) { this.update(); } return hovered; }, getNodeAtCoords: (coords, active) => { const node = this.annotations.at(active); if (!node) { return; } return node.getNodeAtCoords(coords.x, coords.y); }, translate: (index, translation) => { const node = this.annotations.at(index); const datum = getTypedDatum(this.annotationData.at(index)); if (!node || !datum) { return; } return this.translateNode(node, datum, translation); }, copy: (index) => { const node = this.annotations.at(index); const datum = getTypedDatum(this.annotationData.at(index)); if (!node || !datum) { return; } return this.createAnnotationDatumCopy(node, datum); }, paste: (datum) => { this.createAnnotation(datum.type, datum, false); this.postUpdateFns.push(() => { this.state.transitionAsync("selectLast"); this.state.transitionAsync("copy"); }); }, select: (index, previous) => { const { annotations, optionsToolbar: optionsToolbar2, toolbar: toolbar2 } = this; this.hideOverlays(); toolbar2.clearActiveButton(); toolbar2.resetButtonIcons(); const selectedNode = index != null ? annotations.at(index) : null; const previousNode = previous != null ? annotations.at(previous) : null; if (previousNode === selectedNode && selectedNode != null) { return; } previousNode?.toggleActive(false); optionsToolbar2.hide(); if (selectedNode) { this.pushAnnotationState(InteractionState22.AnnotationsSelected); selectedNode.toggleActive(true); optionsToolbar2.updateButtons(this.annotationData.at(index)); this.postUpdateFns.push(() => { optionsToolbar2.show(); optionsToolbar2.setAnchorScene(selectedNode); }); } else { this.popAnnotationState(InteractionState22.AnnotationsSelected); this.popAnnotationState(InteractionState22.Annotations); } this.deleteEphemeralAnnotations(); this.update(); }, selectLast: () => { this.pushAnnotationState(InteractionState22.AnnotationsSelected); return this.annotationData.length - 1; }, startInteracting: () => { this.pushAnnotationState(InteractionState22.Annotations); }, stopInteracting: () => { this.popAnnotationState(InteractionState22.Annotations); }, create: (type, datum) => { this.createAnnotation(type, datum); }, delete: (index) => { this.annotationData.splice(index, 1); }, deleteAll: () => { this.annotationData.splice(0, this.annotationData.length); }, validatePoint: (point) => { const context = this.getAnnotationContext(); return context ? validateDatumPoint(context, point) : true; }, getAnnotationType: (index) => { return stringToAnnotationType(this.annotationData[index].type); }, datum: (index) => { return this.annotationData.at(index); }, node: (index) => { return this.annotations.at(index); }, recordAction: (label) => { this.recordActionAfterNextUpdate(label); }, update: () => { this.postUpdateFns.push(() => { const active = this.state.getActive(); const node = active != null ? this.annotations.at(active) : null; if (node == null) return; this.optionsToolbar.setAnchorScene(node); }); this.update(); }, showTextInput: (active) => { const datum = getTypedDatum(this.annotationData.at(active)); const node = this.annotations.at(active); if (!node || !datum || !("getTextInputCoords" in datum) || !("getTextPosition" in datum)) return; const styles = { color: datum.color, fontFamily: datum.fontFamily, fontSize: datum.fontSize, fontStyle: datum.fontStyle, fontWeight: datum.fontWeight, placeholderColor: datum.getPlaceholderColor() }; const context = this.getAnnotationContext(); const getTextInputCoords = (height2) => Vec219.add(datum.getTextInputCoords(context, height2), Vec219.required(this.seriesRect)); const getTextPosition = () => datum.getTextPosition(); this.textInput.show({ styles, layout: { getTextInputCoords, getTextPosition, alignment: datum.alignment, textAlign: datum.textAlign, width: datum.width }, text: datum.text, placeholderText: datum.placeholderText, onChange: (_text, bbox) => { this.state.transition("updateTextInputBBox", bbox); } }); this.ctx.domManager.updateCursor("annotations"); }, hideTextInput: () => { this.textInput.hide(); }, updateTextInputColor: (color) => { this.textInput.updateColor(color); }, updateTextInputFontSize: (fontSize) => { const bbox = this.textInput.updateFontSize(fontSize); this.state.transition("updateTextInputBBox", bbox); }, updateTextInputBBox: (bbox) => { this.state.transition("updateTextInputBBox", bbox); }, showAnnotationOptions: (active) => { const node = this.annotations.at(active); if (!node || isEphemeralType(this.annotationData.at(active))) return; this.optionsToolbar.updateButtons(this.annotationData.at(active)); this.optionsToolbar.show(); this.optionsToolbar.setAnchorScene(node); }, showAnnotationSettings: (active, sourceEvent, initialTab = "line") => { const datum = this.annotationData.at(active); if (!isLineType(datum) && !isChannelType(datum) && !isMeasurerType(datum)) return; if (isEphemeralType(datum)) return; const onChangeColor = (colorType) => (colorOpacity, color, opacity, isMultiColor) => { this.setColorAndDefault(datum.type, colorType, colorOpacity, color, opacity, isMultiColor); this.optionsToolbar.updateColorPickerColor(colorType, color, opacity, isMultiColor); }; const onChangeHideColor = (colorType) => () => { this.recordActionAfterNextUpdate( `Change ${datum.type} ${colorType} to ${datum.getDefaultColor(colorType)}`, ["annotations", "defaults"] ); this.update(); }; const options = { initialSelectedTab: initialTab, ariaLabel: this.ctx.localeManager.t("ariaLabelAnnotationSettingsDialog"), sourceEvent, onChangeLine: (props) => { this.state.transition("lineProps", props); if (props.bands != null) this.defaults.setDefaultFibonacciOptions(datum.type, "bands", props.bands); if (props.reverse != null) this.defaults.setDefaultFibonacciOptions(datum.type, "reverse", props.reverse); if (props.showFill != null) this.defaults.setDefaultFibonacciOptions(datum.type, "showFill", props.showFill); }, onChangeText: (props) => { this.state.transition("lineText", props); if (props.alignment) this.defaults.setDefaultLineTextAlignment(datum.type, props.alignment); if (props.position) this.defaults.setDefaultLineTextPosition(datum.type, props.position); this.recordActionAfterNextUpdate( `Change ${datum.type} text ${Object.entries(props).map(([key, value]) => `${key} to ${value}`).join(", ")}` ); }, onChangeFillColor: onChangeColor("fill-color"), onChangeHideFillColor: onChangeHideColor("fill-color"), onChangeLineColor: onChangeColor("line-color"), onChangeHideLineColor: onChangeHideColor("line-color"), onChangeLineStyleType: (lineStyleType) => { this.setLineStyleTypeAndDefault(datum.type, lineStyleType); this.optionsToolbar.updateLineStyleType( LINE_STYLE_TYPE_ITEMS.find((item) => item.value === lineStyleType) ?? LINE_STYLE_TYPE_ITEMS[0] ); }, onChangeLineStyleWidth: (strokeWidth) => { this.setLineStyleWidthAndDefault(datum.type, strokeWidth); this.optionsToolbar.updateStrokeWidth({ strokeWidth, value: strokeWidth, label: String(strokeWidth) }); }, onChangeTextColor: onChangeColor("text-color"), onChangeHideTextColor: onChangeHideColor("text-color"), onChangeTextFontSize: (fontSize) => { this.setFontSizeAndDefault(datum.type, fontSize); } }; this.settingsDialog.show(datum, options); } }); } setupListeners() { const { ctx, optionsToolbar: optionsToolbar2, settingsDialog, toolbar: toolbar2 } = this; const { seriesWidget, seriesDragInterpreter, chartWidget } = ctx.widgets; this.destroyFns.push( // Interactions seriesDragInterpreter.addListener("click", this.hoverTouchPreHandler.bind(this)), seriesDragInterpreter.addListener("drag-start", this.hoverTouchPreHandler.bind(this)), seriesDragInterpreter.addListener("drag-move", this.dragMoveTouchPreHandler.bind(this)), seriesDragInterpreter.addListener("mousemove", this.onHover.bind(this)), seriesDragInterpreter.addListener("click", this.onClick.bind(this)), seriesDragInterpreter.addListener("dblclick", this.onDoubleClick.bind(this)), seriesDragInterpreter.addListener("drag-start", this.onDragStart.bind(this)), seriesDragInterpreter.addListener("drag-move", this.onDrag.bind(this)), seriesDragInterpreter.addListener("drag-end", this.onDragEnd.bind(this)), seriesWidget.addListener("keydown", this.onKeyDown.bind(this)), seriesWidget.addListener("keyup", this.onKeyUp.bind(this)), chartWidget.addListener("click", this.onCancel.bind(this)), // Services ctx.annotationManager.addListener("restore-annotations", this.onRestoreAnnotations.bind(this)), ctx.layoutManager.addListener("layout:complete", this.onLayoutComplete.bind(this)), ctx.updateService.addListener("pre-scene-render", this.onPreRender.bind(this)), ctx.zoomManager.addListener("zoom-change", () => this.onResize()), ctx.domManager.addListener("resize", () => this.onResize()), // Toolbar toolbar2.addListener("cancel-create-annotation", () => { this.cancel(); this.reset(); this.update(); }), toolbar2.addListener("pressed-create-annotation", ({ annotation }) => { this.cancel(); this.pushAnnotationState(InteractionState22.Annotations); this.state.transition(annotation); this.update(); }), toolbar2.addListener("pressed-clear", () => { this.clear(); this.recordActionAfterNextUpdate("Clear all"); }), toolbar2.addListener("pressed-show-menu", () => { this.cancel(); this.reset(); }), toolbar2.addListener("pressed-unrelated", () => { this.reset(); }), // Annotation Options Toolbar optionsToolbar2.addListener("pressed-delete", () => { this.cancel(); this.delete(); this.reset(); }), optionsToolbar2.addListener("pressed-settings", ({ sourceEvent }) => { this.state.transition("toolbarPressSettings", sourceEvent); }), optionsToolbar2.addListener("pressed-lock", () => { this.update(); }), optionsToolbar2.addListener("hid-overlays", () => { this.settingsDialog.hide(); }), optionsToolbar2.addListener("saved-color", ({ type, colorPickerType, color }) => { this.recordActionAfterNextUpdate(`Change ${type} ${colorPickerType} to ${color}`, [ "annotations", "defaults" ]); }), optionsToolbar2.addListener( "updated-color", ({ type, colorPickerType, colorOpacity, color, opacity, isMultiColor }) => { this.setColorAndDefault(type, colorPickerType, colorOpacity, color, opacity, isMultiColor); } ), optionsToolbar2.addListener("updated-font-size", ({ type, fontSize }) => { this.setFontSizeAndDefault(type, fontSize); }), optionsToolbar2.addListener("updated-line-style", ({ type, lineStyleType }) => { this.setLineStyleTypeAndDefault(type, lineStyleType); }), optionsToolbar2.addListener("updated-line-width", ({ type, strokeWidth }) => { this.setLineStyleWidthAndDefault(type, strokeWidth); }), // Settings Dialog settingsDialog.addListener("hidden", () => { this.optionsToolbar.clearActiveButton(); }) ); } setupDOM() { const { ctx, toolbar: toolbar2 } = this; this.destroyFns.push( // DOM ctx.annotationManager.attachNode(this.container), () => ctx.domManager.removeStyles(DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS), () => toolbar2.destroy() ); } async processData(dataController) { if (!this.enabled || this.data == null || this.xKey == null || this.volumeKey == null) return; const props = [ keyProperty2(this.xKey, void 0, { id: "date" }), valueProperty2(this.volumeKey, "number", { id: "volume" }) ]; const { dataModel, processedData } = await dataController.request("annotations", this.data, { props }); this.dataModel = dataModel; this.processedData = processedData; } /** * Create an annotation scene within the `this.annotations` scene selection. This method is automatically called by * the selection when a new scene is required. */ createAnnotationScene(datum) { if (datum.type in annotationConfigs) { return new annotationConfigs[datum.type].scene(); } throw new Error( `AG Charts - Cannot create annotation scene of type [${datum.type}], expected one of [${Object.keys(annotationConfigs)}], ignoring.` ); } /** * Create an annotation datum within the `this.annotationData` properties array. It is created as an instance * of `AnnotationProperties` from the given config for its type. This method is only called when annotations * are added from the initial state. */ static createAnnotationDatum(params) { if (params.type in annotationConfigs) { return new annotationConfigs[params.type].datum().set(params); } throw new Error( `AG Charts - Cannot create annotation datum of unknown type [${params.type}], expected one of [${Object.keys(annotationConfigs)}], ignoring.` ); } /** * Append an annotation datum to `this.annotationData`, applying default styles. This method is called when a user * interacts with the chart to draw their own annotations. */ createAnnotation(type, datum, applyDefaults = true) { this.annotationData.push(datum); if (applyDefaults) { const styles = this.ctx.annotationManager.getAnnotationTypeStyles(type); if (styles) datum.set(styles); this.defaults.applyDefaults(datum); } this.injectDatumDependencies(datum); this.update(); } injectDatumDependencies(datum) { if ("setLocaleManager" in datum) { datum.setLocaleManager(this.ctx.localeManager); } if ("getVolume" in datum) { datum.getVolume = this.getDatumRangeVolume.bind(this); } } getDatumRangeVolume(fromPoint, toPoint) { const { dataModel, processedData } = this; let from3 = getGroupingValue(fromPoint).value; let to = getGroupingValue(toPoint).value; if (!isValidDate2(from3) || !isValidDate2(to) || !dataModel || !processedData || this.volumeKey == null) return; if (from3 > to) { [from3, to] = [to, from3]; } const dateValues = dataModel.resolveKeysById({ id: "annotations" }, "date", processedData); const volumeValues = dataModel.resolveColumnById({ id: "annotations" }, "volume", processedData); let sum2 = 0; for (let datumIndex = 0; datumIndex < processedData.input.count; datumIndex++) { const key = dateValues[datumIndex]; if (isValidDate2(key) && key >= from3 && key <= to) { sum2 += volumeValues[datumIndex]; } } return sum2; } translateNode(node, datum, translation) { const config = this.getAnnotationConfig(datum); const context = this.getAnnotationContext(); if (!context) { return; } config.translate(node, datum, translation, context); } createAnnotationDatumCopy(node, datum) { const config = this.getAnnotationConfig(datum); const newDatum = new config.datum(); newDatum.set(datum.toJson()); const context = this.getAnnotationContext(); if (!context) { return; } return config.copy(node, datum, newDatum, context); } getAnnotationConfig(datum) { if (datum.type in annotationConfigs) { return annotationConfigs[datum.type]; } throw new Error( `AG Charts - Cannot get annotation config of unknown type [${datum.type}], expected one of [${Object.keys(annotationConfigs)}], ignoring.` ); } onRestoreAnnotations(event) { if (!this.enabled) return; this.clear(); this.annotationData.set(event.annotations); this.restoreAnnotations = true; this.update(); } onLayoutComplete(event) { const seriesRect = event.series.paddedRect; this.seriesRect = seriesRect; this.container.setClipRect(seriesRect); for (const axisLayout of event.axes ?? []) { if (axisLayout.direction === import_ag_charts_community98._ModuleSupport.ChartAxisDirection.X) { this.xAxis = this.getAxis(axisLayout, seriesRect, this.xAxis?.button); } else { this.yAxis = this.getAxis(axisLayout, seriesRect, this.yAxis?.button); } } if (this.showAnnotations()) { this.animateAnnotations({ from: 0, to: 1, phase: "trailing" }); } else { this.animateAnnotations({ from: 1, to: 0, phase: "remove" }); } } showAnnotations() { if (!this.yAxis || !this.xAxis) { return false; } const hasData = this.ctx.chartService.series.some((s) => s.hasData); const seriesIds = this.yAxis.context.seriesIds(); const anyBoundSeriesVisible = seriesIds.some((id) => { const series = this.ctx.chartService.series.find((s) => s.id === id); return series?.visible; }); return hasData && anyBoundSeriesVisible; } animateAnnotations({ from: from3, to, phase }) { const { annotations } = this; this.ctx.animationManager?.animate({ from: from3, to, id: "chart-annotations", phase, groupId: "opacity", onUpdate(value) { annotations.each((node) => { node.opacity = value; if ("setAxisLabelOpacity" in node) { node.setAxisLabelOpacity(value); } }); }, onStop() { annotations.each((node) => { node.opacity = to; if ("setAxisLabelOpacity" in node) { node.setAxisLabelOpacity(to); } }); } }); } onPreRender() { this.updateAnnotations(); this.state.transition("render"); } getAxis(axisLayout, seriesRect, button) { const axisCtx = this.ctx.axisManager.getAxisContext(axisLayout.direction)[0]; const { position: axisPosition = "bottom", direction } = axisCtx; const padding = axisLayout.gridPadding + axisLayout.seriesAreaPadding; const bounds = new BBox3(0, 0, seriesRect.width, seriesRect.height).grow(padding, axisPosition); const lineDirection = axisCtx.direction === ChartAxisDirection11.X ? "vertical" : "horizontal"; const { axesButtons, snap } = this; const buttonEnabled = this.enabled && axesButtons.enabled && (axesButtons.axes === "xy" || axesButtons.axes === direction); if (buttonEnabled) { button ?? (button = new AxisButton( this.ctx, { ...axisCtx, snapToGroup: snap }, (coords) => this.onAxisButtonClick(coords, lineDirection), seriesRect )); const axisLabelPadding = calculateAxisLabelPadding(axisLayout); button.update(seriesRect, axisLabelPadding); } else { button?.destroy(); button = void 0; } return { layout: axisLayout, context: axisCtx, bounds, button }; } recordActionAfterNextUpdate(label, types = ["annotations"]) { const { defaults, ctx: { annotationManager, historyManager } } = this; const originators = types.map((type) => type === "defaults" ? defaults : annotationManager); this.postUpdateFns.push(() => { historyManager.record(label, ...originators); }); } setColorAndDefault(datumType, colorPickerType, colorOpacity, color, opacity, isMultiColor) { this.state.transition("color", { colorPickerType, colorOpacity, color, opacity, isMultiColor }); this.defaults.setDefaultColor(datumType, colorPickerType, colorOpacity, color, opacity, isMultiColor); } setFontSizeAndDefault(datumType, fontSize) { this.state.transition("fontSize", fontSize); this.defaults.setDefaultFontSize(datumType, fontSize); this.recordActionAfterNextUpdate(`Change ${datumType} font size to ${fontSize}`, ["annotations", "defaults"]); } setLineStyleTypeAndDefault(datumType, styleType) { this.state.transition("lineStyle", { type: styleType }); this.defaults.setDefaultLineStyleType(datumType, styleType); this.recordActionAfterNextUpdate(`Change ${datumType} line style to ${styleType}`, ["annotations", "defaults"]); } setLineStyleWidthAndDefault(datumType, strokeWidth) { this.state.transition("lineStyle", { strokeWidth }); this.defaults.setDefaultLineStyleWidth(datumType, strokeWidth); this.recordActionAfterNextUpdate(`Change ${datumType} stroke width to ${strokeWidth}`, [ "annotations", "defaults" ]); } updateAnnotations() { const { annotationData, annotations, seriesRect, ctx: { annotationManager } } = this; const context = this.getAnnotationContext(); if (!seriesRect || !context) return; annotationManager.updateData(annotationData.toJson().filter((datum) => !isEphemeralType(datum))); const showAnnotations = this.showAnnotations(); this.toolbar.refreshButtonsEnabled(showAnnotations); this.toolbar.toggleClearButtonEnabled(annotationData.length > 0 && showAnnotations); const shouldWarn = this.restoreAnnotations; annotations.update(annotationData ?? [], void 0, (datum) => datum.id).each((node, datum) => { if (!showAnnotations || !this.validateDatum(datum, shouldWarn)) { node.visible = false; if ("setAxisLabelVisible" in node) { node.setAxisLabelVisible(false); } return; } if ("setAxisLabelVisible" in node) { node.setAxisLabelVisible(true); } this.injectDatumDependencies(datum); updateAnnotation(node, datum, context); }); this.postUpdateFns.forEach((fn) => fn()); this.postUpdateFns = []; this.restoreAnnotations = false; } // Validation of the options beyond the scope of the @Validate decorator validateDatum(datum, shouldWarn) { const context = this.getAnnotationContext(); const warningPrefix = shouldWarn ? `Annotation [${datum.type}] ` : void 0; return context ? datum.isValidWithContext(context, warningPrefix) : true; } getAnnotationContext() { const { seriesRect, xAxis, yAxis, snap } = this; if (!(seriesRect && xAxis && yAxis)) { return; } return { seriesRect, xAxis: { ...xAxis.context, bounds: xAxis.bounds, labelPadding: calculateAxisLabelPadding(xAxis.layout), snapToGroup: snap }, yAxis: { ...yAxis.context, bounds: yAxis.bounds, labelPadding: calculateAxisLabelPadding(xAxis.layout), snapToGroup: snap } }; } onHover(event) { const { state } = this; const context = this.getAnnotationContext(); if (!context) return; const shiftKey = event.sourceEvent.shiftKey; const offset4 = Vec219.from(event); const point = invertCoords(offset4, context); state.transition("hover", { offset: offset4, point, shiftKey, context }); } onClick(event) { const { state } = this; const context = this.getAnnotationContext(); if (!context) return; const shiftKey = event.sourceEvent.shiftKey; const point = invertCoords(Vec219.from(event), context); const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); state.transition("click", { point, shiftKey, textInputValue, bbox }); } onDoubleClick(event) { const { state } = this; const context = this.getAnnotationContext(); if (!context) return; const offset4 = Vec219.from(event); state.transition("dblclick", { offset: offset4 }); } onAxisButtonClick(coords, direction) { this.cancel(); this.reset(); const context = this.getAnnotationContext(); if (!this.annotationData || !context) return; const { state } = this; this.pushAnnotationState(InteractionState22.Annotations); const isHorizontal = direction === "horizontal"; state.transition( isHorizontal ? "horizontal-line" : "vertical-line" /* VerticalLine */ ); this.optionsToolbar.hide(); if (!coords) { return; } const point = invertCoords(coords, context); if (!validateDatumPoint(context, point)) { return; } state.transition("click", { point, shiftKey: false }); this.update(); } onResize() { const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); this.state.transition("resize", { textInputValue, bbox }); } hoverTouchPreHandler(event) { if (event.device === "touch") { this.onHover(event); } } dragMoveTouchPreHandler(event) { if (event.device === "touch" && this.ctx.interactionManager.isState(InteractionState22.AnnotationsSelected)) { event.sourceEvent.preventDefault(); } } onDragStart(event) { if (!this.ctx.interactionManager.isState(InteractionState22.AnnotationsDraggable)) return; const context = this.getAnnotationContext(); if (!context) return; const offset4 = Vec219.from(event); const point = invertCoords(offset4, context); const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); this.state.transition("dragStart", { context, offset: offset4, point, textInputValue, bbox }); } onDrag(event) { if (!this.ctx.interactionManager.isState(InteractionState22.AnnotationsDraggable)) return; const context = this.getAnnotationContext(); if (!context) return; const offset4 = Vec219.from(event); const point = invertCoords(offset4, context); const shiftKey = event.sourceEvent.shiftKey; const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); this.state.transition("drag", { context, offset: offset4, point, shiftKey, textInputValue, bbox }); } onDragEnd() { this.state.transition("dragEnd"); } onCancel(widgetEvent) { const { sourceEvent } = widgetEvent ?? {}; if (sourceEvent?.currentTarget !== sourceEvent?.target) return; this.cancel(); this.reset(); } onDelete() { if (this.textInput.isVisible()) return; this.cancel(); this.delete(); this.reset(); this.update(); } onTextInput(event) { const { state } = this; const context = this.getAnnotationContext(); if (!context) return; const { key, shiftKey } = event; const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); state.transition("textInput", { key, shiftKey, textInputValue, bbox, context }); } onKeyDown(event) { const { state } = this; const context = this.getAnnotationContext(); if (!context) { return; } const { sourceEvent } = event; const { shiftKey, ctrlKey, metaKey } = sourceEvent; const ctrlMeta = ctrlKey || metaKey; const ctrlShift = ctrlKey || shiftKey; this.state.transition("keyDown", { shiftKey, context }); const translation = { x: 0, y: 0 }; const xStep = Math.max(context?.xAxis.scale.bandwidth ?? 0, ctrlShift ? 10 : 1); const yStep = Math.max(context?.yAxis.scale.bandwidth ?? 0, ctrlShift ? 10 : 1); switch (sourceEvent.key) { case "ArrowDown": translation.y = yStep; break; case "ArrowUp": translation.y = -yStep; break; case "ArrowLeft": translation.x = -xStep; break; case "ArrowRight": translation.x = xStep; break; case "Escape": this.onCancel(); return; case "Backspace": case "Delete": this.onDelete(); return; } if (translation.x || translation.y) { state.transition("translate", { translation }); sourceEvent.stopPropagation(); sourceEvent.preventDefault(); } if (!ctrlMeta) { return; } switch (sourceEvent.key) { case "c": state.transition("copy"); return; case "x": state.transition("cut"); this.recordActionAfterNextUpdate("Cut annotation"); return; case "v": state.transition("paste"); this.recordActionAfterNextUpdate("Paste annotation"); return; } } onKeyUp(event) { const { shiftKey } = event.sourceEvent; const context = this.getAnnotationContext(); if (!context) { return; } this.state.transition("keyUp", { shiftKey, context }); this.state.transition("translateEnd"); } clear() { this.cancel(); this.deleteAll(); this.reset(); } reset() { this.state.transition("reset"); } cancel() { this.state.transition("cancel"); } delete() { this.state.transition("delete"); } deleteAll() { this.state.transition("deleteAll"); } deleteEphemeralAnnotations() { for (const [index, datum] of this.annotationData.entries()) { if (isEphemeralType(datum)) { this.annotationData.splice(index, 1); } } } hideOverlays() { this.settingsDialog.hide(); this.toolbar.hideOverlays(); this.optionsToolbar.hideOverlays(); } pushAnnotationState(state) { this.ctx.interactionManager.pushState(state); this.ctx.tooltipManager.suppressTooltip("annotations"); } popAnnotationState(state) { this.ctx.interactionManager.popState(state); this.ctx.tooltipManager.unsuppressTooltip("annotations"); } isAnnotationState() { return this.ctx.interactionManager.isState(InteractionState22.Annotations) || this.ctx.interactionManager.isState(InteractionState22.AnnotationsSelected); } update(status = ChartUpdateType2.PRE_SCENE_RENDER) { this.ctx.updateService.update(status); } }; __decorateClass2([ ObserveChanges22((target, newValue, oldValue) => { const { ctx: { annotationManager, stateManager } } = target; if (newValue === oldValue) return; target.toolbar?.toggleVisibility(Boolean(newValue)); if (oldValue === false && newValue === true) { stateManager.restoreState(annotationManager); } else if (newValue === false) { target.clear(); } }), Validate32(BOOLEAN11) ], _Annotations.prototype, "enabled", 2); __decorateClass2([ Validate32(OBJECT14) ], _Annotations.prototype, "toolbar", 2); __decorateClass2([ Validate32(OBJECT14) ], _Annotations.prototype, "optionsToolbar", 2); __decorateClass2([ Validate32(OBJECT14) ], _Annotations.prototype, "axesButtons", 2); __decorateClass2([ Validate32(BOOLEAN11) ], _Annotations.prototype, "snap", 2); var Annotations = _Annotations; var import_ag_charts_community99 = (init_main4(), __toCommonJS(main_exports)); var { FONT_SIZE_RATIO: FONT_SIZE_RATIO2, ThemeSymbols } = import_ag_charts_community99._ModuleSupport; var stroke2 = { stroke: { $ref: "foregroundColor" }, strokeOpacity: 1, strokeWidth: 2 }; var handle2 = { fill: ThemeSymbols.DEFAULT_ANNOTATION_HANDLE_FILL, strokeOpacity: 1, strokeWidth: 2 }; var font2 = { color: { $ref: "backgroundColor" }, fontSize: { $rem: [FONT_SIZE_RATIO2.LARGE] }, fontFamily: { $ref: "fontFamily" } }; var axisLabel2 = { ...font2, enabled: true, fill: { $ref: "foregroundColor" }, fontSize: { $ref: "fontSize" } }; var text2 = { ...font2, textAlign: "left" }; var lineText2 = { ...font2, position: "top", alignment: "center", color: { $ref: "textColor" } }; var channelText = { ...font2, position: "top", alignment: "center", color: { $ref: "textColor" } }; var measurerStatistics2 = { ...font2, fontSize: { $ref: "fontSize" }, color: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_COLOR, fill: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_FILL, stroke: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_STROKE, strokeWidth: 1, divider: { stroke: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, strokeWidth: 1, strokeOpacity: 0.5 } }; var measurer2 = { ...stroke2, background: { fill: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, handle: { ...handle2 }, text: { ...lineText2 }, statistics: { ...measurerStatistics2 } }; var toolbar = { buttons: [ { icon: "text-annotation", tooltip: "toolbarAnnotationsTextAnnotations", value: "text-menu" }, { icon: "trend-line-drawing", tooltip: "toolbarAnnotationsLineAnnotations", value: "line-menu" }, { icon: "arrow-drawing", tooltip: "toolbarAnnotationsShapeAnnotations", value: "shape-menu" }, { icon: "delete", tooltip: "toolbarAnnotationsClearAll", value: "clear" } ], // @ts-expect-error undocumented option padding: { $ref: "padding" } }; var optionsToolbar = { buttons: [ { icon: "text-annotation", tooltip: "toolbarAnnotationsTextColor", value: "text-color" }, { icon: "line-color", tooltip: "toolbarAnnotationsLineColor", value: "line-color" }, { icon: "fill-color", tooltip: "toolbarAnnotationsFillColor", value: "fill-color" }, { tooltip: "toolbarAnnotationsTextSize", value: "text-size" }, { tooltip: "toolbarAnnotationsLineStrokeWidth", value: "line-stroke-width" }, { icon: "line-style-solid", tooltip: "toolbarAnnotationsLineStyle", value: "line-style-type" }, { icon: "settings", tooltip: "toolbarAnnotationsSettings", value: "settings" }, { icon: "unlocked", tooltip: "toolbarAnnotationsLock", ariaLabel: "toolbarAnnotationsLock", checkedOverrides: { icon: "locked", tooltip: "toolbarAnnotationsUnlock" }, value: "lock" }, { icon: "delete", tooltip: "toolbarAnnotationsDelete", value: "delete" } ] }; var annotationsTheme2 = { enabled: false, // Lines line: { ...stroke2, handle: { ...handle2 }, text: { ...lineText2 } }, "horizontal-line": { ...stroke2, handle: { ...handle2 }, axisLabel: { ...axisLabel2 }, text: { ...lineText2 } }, "vertical-line": { ...stroke2, handle: { ...handle2 }, axisLabel: { ...axisLabel2 }, text: { ...lineText2 } }, // Channels "disjoint-channel": { ...stroke2, background: { fill: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, handle: { ...handle2 }, text: { ...channelText } }, "parallel-channel": { ...stroke2, middle: { lineDash: [6, 5], strokeWidth: 1 }, background: { fill: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, handle: { ...handle2 }, text: { ...channelText } }, // Fibonnaccis "fibonacci-retracement": { ...stroke2, strokes: ThemeSymbols.DEFAULT_FIBONACCI_STROKES, rangeStroke: { $ref: "foregroundColor" }, handle: { ...handle2 }, text: { ...lineText2, position: "center" }, label: { ...font2, color: void 0, fontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 10 / 12] }] } } }, "fibonacci-retracement-trend-based": { ...stroke2, strokes: ThemeSymbols.DEFAULT_FIBONACCI_STROKES, rangeStroke: { $ref: "foregroundColor" }, handle: { ...handle2 }, text: { ...lineText2, position: "center" }, label: { ...font2, color: void 0, fontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 10 / 12] }] } } }, // Texts callout: { ...stroke2, ...text2, color: { $ref: "textColor" }, handle: { ...handle2 }, fill: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, comment: { ...text2, fontWeight: 700, handle: { ...handle2 }, fill: { $ref: "foregroundColor" } }, note: { ...text2, color: ThemeSymbols.DEFAULT_TEXTBOX_COLOR, fill: ThemeSymbols.DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, stroke: { $ref: "backgroundColor" }, strokeWidth: 1, strokeOpacity: 1, handle: { ...handle2 }, background: { fill: ThemeSymbols.DEFAULT_TEXTBOX_FILL, stroke: ThemeSymbols.DEFAULT_TEXTBOX_STROKE, strokeWidth: 1 } }, text: { ...text2, color: { $ref: "textColor" }, handle: { ...handle2 } }, // Shapes arrow: { ...stroke2, handle: { ...handle2 }, text: { ...lineText2 } }, "arrow-up": { fill: ThemeSymbols.PALETTE_UP_FILL, handle: { ...handle2, stroke: { $ref: "foregroundColor" } } }, "arrow-down": { fill: ThemeSymbols.PALETTE_DOWN_FILL, handle: { ...handle2, stroke: { $ref: "foregroundColor" } } }, // Measurers "date-range": { ...measurer2 }, "price-range": { ...measurer2 }, "date-price-range": { ...measurer2 }, "quick-date-price-range": { up: { ...stroke2, fill: ThemeSymbols.DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2, handle: { ...handle2 }, statistics: { ...measurerStatistics2, color: "#fff", fill: ThemeSymbols.DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, strokeWidth: 0, divider: { stroke: "#fff", strokeWidth: 1, strokeOpacity: 0.5 } } }, down: { ...stroke2, stroke: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, fill: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, fillOpacity: 0.2, handle: { ...handle2, stroke: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE }, statistics: { ...measurerStatistics2, color: "#fff", fill: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, strokeWidth: 0, divider: { stroke: "#fff", strokeWidth: 1, strokeOpacity: 0.5 } } } }, axesButtons: {}, // Toolbars toolbar, optionsToolbar }; var AnnotationsModule = { type: "root", optionsKey: "annotations", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new Annotations(ctx), themeTemplate: { annotations: annotationsTheme2 } }; var import_ag_charts_community101 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community100 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties12, ObserveChanges: ObserveChanges3, ProxyProperty: ProxyProperty2, Validate: Validate33, NUMBER: NUMBER9, POSITIVE_NUMBER: POSITIVE_NUMBER6, RATIO: RATIO5, calculatePlacement: calculatePlacement2, createElement: createElement3 } = import_ag_charts_community100._ModuleSupport; var Image2 = class extends BaseProperties12 { constructor() { super(); this.opacity = 1; this.loadedSynchronously = true; this.containerWidth = 0; this.containerHeight = 0; this.onLoad = void 0; this.onImageLoad = () => { if (this.loadedSynchronously) { return; } this.node.visible = false; this.performLayout(this.containerWidth, this.containerHeight); this.onLoad?.(); }; this.imageElement = createElement3("img"); this.imageElement.onload = this.onImageLoad; this.node = new import_ag_charts_community100._ModuleSupport.Image(this.imageElement); } get complete() { return this.imageElement.width > 0 && this.imageElement.height > 0; } performLayout(containerWidth, containerHeight) { this.containerWidth = containerWidth; this.containerHeight = containerHeight; const container = { width: containerWidth, height: containerHeight }; const placement = calculatePlacement2(this.imageElement.width, this.imageElement.height, container, this); this.node.setProperties( this.complete ? { visible: true, opacity: this.opacity, ...placement } : { visible: false } ); return placement; } }; __decorateClass2([ Validate33(NUMBER9, { optional: true }) ], Image2.prototype, "top", 2); __decorateClass2([ Validate33(NUMBER9, { optional: true }) ], Image2.prototype, "right", 2); __decorateClass2([ Validate33(NUMBER9, { optional: true }) ], Image2.prototype, "bottom", 2); __decorateClass2([ Validate33(NUMBER9, { optional: true }) ], Image2.prototype, "left", 2); __decorateClass2([ Validate33(POSITIVE_NUMBER6, { optional: true }) ], Image2.prototype, "width", 2); __decorateClass2([ Validate33(POSITIVE_NUMBER6, { optional: true }) ], Image2.prototype, "height", 2); __decorateClass2([ Validate33(RATIO5) ], Image2.prototype, "opacity", 2); __decorateClass2([ ProxyProperty2("imageElement.src"), ObserveChanges3((target) => target.loadedSynchronously = target.complete) ], Image2.prototype, "url", 2); var { ActionOnSet: ActionOnSet3, OBJECT: OBJECT15, Validate: Validate34 } = import_ag_charts_community101._ModuleSupport; var Background22 = class extends import_ag_charts_community101._ModuleSupport.Background { constructor() { super(...arguments); this.image = new Image2(); } onLayoutComplete(event) { super.onLayoutComplete(event); if (this.image) { const { width: width2, height: height2 } = event.chart; this.image.performLayout(width2, height2); } } onImageLoad() { this.ctx.updateService.update(import_ag_charts_community101._ModuleSupport.ChartUpdateType.SCENE_RENDER); } }; __decorateClass2([ Validate34(OBJECT15, { optional: true }), ActionOnSet3({ newValue(image) { this.node.appendChild(image.node); image.onLoad = () => this.onImageLoad(); }, oldValue(image) { this.node.removeChild(image.node); image.onLoad = void 0; } }) ], Background22.prototype, "image", 2); var BackgroundModule2 = { type: "root", optionsKey: "background", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Background22(ctx) }; var import_ag_charts_community103 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community102 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN12, ActionOnSet: ActionOnSet4, LayoutElement: LayoutElement22, Menu: Menu3, Validate: Validate35 } = import_ag_charts_community102._ModuleSupport; var menuItems = [ { label: "toolbarSeriesTypeOHLC", icon: "ohlc-series", value: "ohlc" }, { label: "toolbarSeriesTypeCandles", icon: "candlestick-series", value: "candlestick" }, { label: "toolbarSeriesTypeHollowCandles", icon: "hollow-candlestick-series", value: "hollow-candlestick" }, { label: "toolbarSeriesTypeLine", icon: "line-series", value: "line" }, { label: "toolbarSeriesTypeStepLine", icon: "step-line-series", value: "step-line" }, { label: "toolbarSeriesTypeHLC", icon: "hlc-series", value: "hlc" }, { label: "toolbarSeriesTypeHighLow", icon: "high-low-series", value: "high-low" } ]; var ChartToolbar = class extends import_ag_charts_community102._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = false; this.menu = new Menu3(this.ctx, "chart-toolbar"); this.toolbar = ctx.sharedToolbar.getSharedToolbar("chartToolbar"); this.destroyFns.push( this.toolbar.addToolbarListener("button-pressed", this.onButtonPressed.bind(this)), ctx.layoutManager.registerElement(LayoutElement22.ToolbarLeft, this.onLayoutStart.bind(this)), () => this.toolbar.destroy() ); } onLayoutStart(event) { if (!this.enabled) return; this.updateButton(); this.toolbar.layout(event.layoutBox); } onButtonPressed({ event, buttonBounds }) { this.menu.setAnchor({ x: buttonBounds.x + buttonBounds.width + 6, y: buttonBounds.y }); this.menu.show({ items: menuItems, menuItemRole: "menuitemradio", ariaLabel: this.ctx.localeManager.t("toolbarSeriesTypeDropdown"), class: "ag-charts-chart-toolbar__menu", value: this.getChartType(), sourceEvent: event.sourceEvent, onPress: (item) => { this.setChartType(item.value); this.hidePopover(); }, onHide: () => { this.toolbar.clearActiveButton(); } }); this.toolbar.toggleActiveButtonByIndex(0); } updateButton() { const chartType = this.getChartType(); const icon = menuItems.find((item) => item.value === chartType)?.icon; if (icon != null) { this.toolbar.updateButtons([{ icon, tooltip: "toolbarSeriesTypeDropdown" }]); } } hidePopover() { this.toolbar.clearActiveButton(); this.menu.hide(); } setChartType(chartType) { const options = { chartType }; this.ctx.chartService.publicApi?.updateDelta(options).catch((e) => logger_exports2.error(e)); } getChartType() { const chartType = this.ctx.chartService.publicApi?.getOptions()?.chartType; if (chartType == null || !menuItems.some((item) => item.value === chartType)) { return "candlestick"; } return chartType; } }; __decorateClass2([ Validate35(BOOLEAN12), ActionOnSet4({ changeValue(enabled) { this.toolbar?.setHidden(!enabled); } }) ], ChartToolbar.prototype, "enabled", 2); var ChartToolbarModule = { type: "root", optionsKey: "chartToolbar", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new ChartToolbar(ctx) }; var import_ag_charts_community105 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community104 = (init_main4(), __toCommonJS(main_exports)); var DEFAULT_CONTEXT_MENU_CLASS = "ag-charts-context-menu"; var DEFAULT_CONTEXT_MENU_DARK_CLASS = "ag-charts-dark-context-menu"; var { BOOLEAN: BOOLEAN13, Validate: Validate36, initMenuKeyNav: initMenuKeyNav2, makeAccessibleClickListener: makeAccessibleClickListener2, ContextMenuRegistry: ContextMenuRegistry2, createElement: createElement4 } = import_ag_charts_community104._ModuleSupport; var moduleId2 = "context-menu"; function getChildrenOfType(parent, ctor) { const { children } = parent ?? {}; if (!children) return []; const result = []; for (const child of Array.from(children)) { if (child instanceof ctor) { result.push(child); } } return result; } var ContextMenu = class extends import_ag_charts_community104._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = true; this.darkTheme = false; this.extraActions = []; this.extraNodeActions = []; this.extraSeriesAreaActions = []; this.extraLegendItemActions = []; this.pickedNode = void 0; this.showEvent = void 0; this.x = 0; this.y = 0; this.interactionManager = ctx.interactionManager; this.registry = ctx.contextMenuRegistry; this.groups = { default: [], extra: [], extraSeriesArea: [], extraNode: [], extraLegendItem: [] }; this.element = ctx.domManager.addChild("canvas-overlay", moduleId2); this.element.classList.add(DEFAULT_CONTEXT_MENU_CLASS); this.element.addEventListener("contextmenu", (event) => event.preventDefault()); this.destroyFns.push(() => this.element.parentNode?.removeChild(this.element)); this.doClose(); this.destroyFns.push(ctx.domManager.addListener("hidden", () => this.hide())); if (typeof MutationObserver !== "undefined") { const observer = new MutationObserver(() => { if (this.menuElement && this.element.contains(this.menuElement)) { this.reposition(); } }); observer.observe(this.element, { childList: true }); this.mutationObserver = observer; this.destroyFns.push(() => observer.disconnect()); } this.destroyFns.push( this.registry.registerDefaultAction({ id: "download", type: "all", label: "contextMenuDownload", action: () => { const title = ctx.chartService.title; let fileName = "image"; if (title?.enabled && title?.text !== void 0) { fileName = title.text.replace(/\.+/, ""); } this.ctx.chartService.publicApi?.download({ fileName }).catch((e) => { logger_exports2.error("Unable to download chart", e); }); } }) ); this.destroyFns.push(this.registry.addListener((e) => this.onContext(e))); } onContext(event) { if (!this.enabled) return; event.sourceEvent.preventDefault(); this.showEvent = event.sourceEvent; this.x = event.x; this.y = event.y; this.groups.default = this.registry.filterActions(event.type); for (const action of this.groups.default) { if (action.id == null || action.toggleEnabledOnShow == null) continue; if (action.toggleEnabledOnShow(event)) { this.registry.enableAction(action.id); } else { this.registry.disableAction(action.id); } } this.pickedNode = void 0; this.pickedLegendItem = void 0; this.groups.extra = this.extraActions.map(({ label, action }) => { return { type: "all", label, action }; }); this.groups.extraSeriesArea = []; this.groups.extraNode = []; if (ContextMenuRegistry2.check("series-area", event)) { this.pickedNode = event.context.pickedNode; this.groups.extraSeriesArea = this.extraSeriesAreaActions.map(({ label, action }) => { return { type: "series-area", label, action }; }); if (this.pickedNode) { this.groups.extraNode = this.extraNodeActions.map(({ label, action }) => { return { type: "node", label, action }; }); } } this.groups.extraLegendItem = []; if (ContextMenuRegistry2.check("legend", event)) { this.pickedLegendItem = event.context.legendItem; if (this.pickedLegendItem) { this.groups.extraLegendItem = this.extraLegendItemActions.map(({ label, action }) => { return { type: "legend", label, action }; }); } } const { default: def, extra, extraSeriesArea, extraNode, extraLegendItem } = this.groups; const groupCount2 = [def, extra, extraSeriesArea, extraNode, extraLegendItem].reduce((count, e) => { return e.length + count; }, 0); if (groupCount2 === 0) return; this.show(event.sourceEvent); } show(sourceEvent) { this.interactionManager.pushState(import_ag_charts_community104._ModuleSupport.InteractionState.ContextMenu); this.element.classList.toggle(DEFAULT_CONTEXT_MENU_DARK_CLASS, this.darkTheme); const newMenuElement = this.renderMenu(); this.menuCloser?.close(); if (this.menuElement) { this.element.replaceChild(newMenuElement, this.menuElement); } else { this.element.appendChild(newMenuElement); } this.menuElement = newMenuElement; this.element.style.display = "block"; const overrideFocusVisible = sourceEvent.pointerType === "touch" ? false : void 0; const buttons2 = getChildrenOfType(newMenuElement, HTMLButtonElement); this.menuCloser = initMenuKeyNav2({ menu: newMenuElement, buttons: buttons2, orientation: "vertical", sourceEvent, overrideFocusVisible, autoCloseOnBlur: true, closeCallback: () => this.doClose() }); if (sourceEvent.pointerType === "touch") { this.ctx.chartService.overrideFocusVisible(false); } } hide() { this.menuCloser?.close(); } doClose() { this.interactionManager.popState(import_ag_charts_community104._ModuleSupport.InteractionState.ContextMenu); if (this.menuElement) { this.element.removeChild(this.menuElement); this.menuElement = void 0; this.menuCloser = void 0; } this.element.style.display = "none"; } renderMenu() { const menuElement = createElement4("div"); menuElement.classList.add(`${DEFAULT_CONTEXT_MENU_CLASS}__menu`); menuElement.classList.toggle(DEFAULT_CONTEXT_MENU_DARK_CLASS, this.darkTheme); menuElement.role = "menu"; this.appendMenuGroup(menuElement, this.groups.default, false); this.appendMenuGroup(menuElement, this.groups.extra); this.appendMenuGroup(menuElement, this.groups.extraSeriesArea); if (this.pickedNode) { this.appendMenuGroup(menuElement, this.groups.extraNode); } if (this.pickedLegendItem) { this.appendMenuGroup(menuElement, this.groups.extraLegendItem); } return menuElement; } appendMenuGroup(menuElement, group, divider = true) { if (group.length === 0) return; if (divider) menuElement.appendChild(this.createDividerElement()); group.forEach((i) => { const item = this.renderItem(i); if (item) menuElement.appendChild(item); }); } renderItem(item) { if (item && typeof item === "object" && item.constructor === Object) { return this.createActionElement(item); } } createDividerElement() { const el = createElement4("div"); el.classList.add(`${DEFAULT_CONTEXT_MENU_CLASS}__divider`); el.classList.toggle(DEFAULT_CONTEXT_MENU_DARK_CLASS, this.darkTheme); el.role = "separator"; return el; } createActionElement({ id, label, type, action }) { const disabled = !!(id && this.registry.isDisabled(id)); return this.createButtonElement(type, label, action, disabled); } createButtonOnClick(type, callback2) { if (ContextMenuRegistry2.checkCallback("legend", type, callback2)) { return (event) => { if (this.pickedLegendItem) { const { seriesId, itemId } = this.pickedLegendItem; callback2({ type: "contextmenu", seriesId, itemId, event }); this.hide(); } }; } else if (ContextMenuRegistry2.checkCallback("series-area", type, callback2)) { return () => { callback2({ type: "seriesContextMenuAction", event: this.showEvent }); this.hide(); }; } else if (ContextMenuRegistry2.checkCallback("node", type, callback2)) { return () => { const { pickedNode, showEvent } = this; const event = pickedNode?.series.createNodeContextMenuActionEvent(showEvent, pickedNode); if (event) { callback2(event); } else { logger_exports2.error("series node not found"); } this.hide(); }; } return () => { callback2({ type: "contextMenuEvent", event: this.showEvent }); this.hide(); }; } createButtonElement(type, label, callback2, disabled) { const el = createElement4("button"); el.classList.add(`${DEFAULT_CONTEXT_MENU_CLASS}__item`); el.classList.toggle(DEFAULT_CONTEXT_MENU_DARK_CLASS, this.darkTheme); el.ariaDisabled = disabled.toString(); el.textContent = this.ctx.localeManager.t(label); el.role = "menuitem"; el.onclick = makeAccessibleClickListener2(el, this.createButtonOnClick(type, callback2)); el.addEventListener("mouseover", () => el.focus({ preventScroll: true })); return el; } reposition() { let { x, y } = this; this.element.style.top = "unset"; this.element.style.bottom = "unset"; const canvasRect = this.ctx.domManager.getBoundingClientRect(); const { offsetWidth: width2, offsetHeight: height2 } = this.element; x = import_ag_charts_community104._ModuleSupport.clamp(0, x, canvasRect.width - width2); y = import_ag_charts_community104._ModuleSupport.clamp(0, y, canvasRect.height - height2); this.element.style.left = `${x}px`; this.element.style.top = `calc(${y}px - 0.5em)`; } destroy() { super.destroy(); this.mutationObserver?.disconnect(); this.ctx.domManager.removeStyles(moduleId2); this.ctx.domManager.removeChild("canvas-overlay", moduleId2); } }; __decorateClass2([ Validate36(BOOLEAN13) ], ContextMenu.prototype, "enabled", 2); __decorateClass2([ Validate36(BOOLEAN13) ], ContextMenu.prototype, "darkTheme", 2); var ContextMenuModule = { type: "root", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], optionsKey: "contextMenu", moduleFactory: (ctx) => new ContextMenu(ctx), themeTemplate: { contextMenu: { enabled: true, darkTheme: import_ag_charts_community105._ModuleSupport.ThemeSymbols.IS_DARK_THEME } } }; var import_ag_charts_community108 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community107 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community106 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties13, BOOLEAN: BOOLEAN14, FUNCTION: FUNCTION22, NUMBER: NUMBER10, STRING: STRING19, Validate: Validate37, createId: createId22, setAttribute: setAttribute22 } = import_ag_charts_community106._ModuleSupport; var DEFAULT_LABEL_CLASS = "ag-charts-crosshair-label"; var CrosshairLabelProperties = class extends import_ag_charts_community106._ModuleSupport.ChangeDetectableProperties { constructor() { super(...arguments); this.enabled = true; this.xOffset = 0; this.yOffset = 0; this.format = void 0; this.renderer = void 0; } }; __decorateClass2([ Validate37(BOOLEAN14) ], CrosshairLabelProperties.prototype, "enabled", 2); __decorateClass2([ Validate37(NUMBER10) ], CrosshairLabelProperties.prototype, "xOffset", 2); __decorateClass2([ Validate37(NUMBER10) ], CrosshairLabelProperties.prototype, "yOffset", 2); __decorateClass2([ Validate37(STRING19, { optional: true }) ], CrosshairLabelProperties.prototype, "format", 2); __decorateClass2([ Validate37(FUNCTION22, { optional: true }) ], CrosshairLabelProperties.prototype, "renderer", 2); var CrosshairLabel = class extends BaseProperties13 { constructor(domManager, key, axisId) { super(); this.domManager = domManager; this.id = createId22(this); this.enabled = true; this.xOffset = 0; this.yOffset = 0; this.renderer = void 0; this.element = domManager.addChild("canvas-overlay", `crosshair-label-${this.id}`); this.element.classList.add(DEFAULT_LABEL_CLASS); setAttribute22(this.element, "aria-hidden", true); this.element.setAttribute("data-key", key); this.element.setAttribute("data-axis-id", axisId); } show(meta) { const { element: element2 } = this; const left = meta.x + this.xOffset; const top = meta.y + this.yOffset; element2.style.top = `${Math.round(top)}px`; element2.style.left = `${Math.round(left)}px`; this.toggle(true); } setLabelHtml(html) { if (html !== void 0) { this.element.innerHTML = html; } } getBBox() { const { element: element2 } = this; return new import_ag_charts_community106._ModuleSupport.BBox( element2.clientLeft, element2.clientTop, element2.clientWidth, element2.clientHeight ); } toggle(visible) { this.element.classList.toggle(`ag-charts-crosshair-label--hidden`, !visible); } destroy() { this.domManager.removeChild("canvas-overlay", `crosshair-label-${this.id}`); } toLabelHtml(input, defaults) { if (typeof input === "string") { return input; } defaults = defaults ?? {}; const { text: text22 = defaults.text ?? "", color = defaults.color, backgroundColor = defaults.backgroundColor, opacity = defaults.opacity ?? 1 } = input; const style = `opacity: ${opacity}; background-color: ${backgroundColor?.toLowerCase()}; color: ${color}`; return `
${text22}
`; } }; __decorateClass2([ Validate37(BOOLEAN14) ], CrosshairLabel.prototype, "enabled", 2); __decorateClass2([ Validate37(NUMBER10) ], CrosshairLabel.prototype, "xOffset", 2); __decorateClass2([ Validate37(NUMBER10) ], CrosshairLabel.prototype, "yOffset", 2); __decorateClass2([ Validate37(STRING19, { optional: true }) ], CrosshairLabel.prototype, "format", 2); __decorateClass2([ Validate37(FUNCTION22, { optional: true }) ], CrosshairLabel.prototype, "renderer", 2); var { Group: Group5, TranslatableGroup: TranslatableGroup2, Line: Line3, BBox: BBox4, createId: createId3, POSITIVE_NUMBER: POSITIVE_NUMBER7, RATIO: RATIO6, BOOLEAN: BOOLEAN15, COLOR_STRING: COLOR_STRING4, LINE_DASH: LINE_DASH3, OBJECT: OBJECT16, InteractionState: InteractionState3, Validate: Validate38, ZIndexMap: ZIndexMap4, formatNumber: formatNumber2, isInteger: isInteger2, ChartAxisDirection: ChartAxisDirection12 } = import_ag_charts_community107._ModuleSupport; var Crosshair = class extends import_ag_charts_community107._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.id = createId3(this); this.enabled = false; this.stroke = "rgb(195, 195, 195)"; this.lineDash = [6, 3]; this.lineDashOffset = 0; this.strokeWidth = 1; this.strokeOpacity = 1; this.snap = true; this.label = new CrosshairLabelProperties(); this.seriesRect = new BBox4(0, 0, 0, 0); this.bounds = new BBox4(0, 0, 0, 0); this.crosshairGroup = new TranslatableGroup2({ name: "crosshairs", zIndex: ZIndexMap4.SERIES_CROSSHAIR }); this.lineGroup = this.crosshairGroup.appendChild( new Group5({ name: `${this.id}-crosshair-lines`, zIndex: ZIndexMap4.SERIES_CROSSHAIR }) ); this.lineGroupSelection = import_ag_charts_community107._ModuleSupport.Selection.select(this.lineGroup, Line3, false); this.activeHighlight = void 0; this.axisCtx = ctx.parent; this.labels = {}; this.hideCrosshairs(); ctx.domManager.addEventListener("focusin", ({ target }) => { const isSeriesAreaChild = target instanceof HTMLElement && ctx.domManager.contains(target, "series-area"); if (this.crosshairGroup.visible && !isSeriesAreaChild) { this.hideCrosshairs(); this.ctx.updateService.update(import_ag_charts_community107._ModuleSupport.ChartUpdateType.PERFORM_LAYOUT); } }); this.destroyFns.push( ctx.scene.attachNode(this.crosshairGroup), ctx.widgets.seriesWidget.addListener("mousemove", (event) => this.onMouseHoverLike(event)), ctx.widgets.seriesWidget.addListener("drag-move", (event) => this.onMouseHoverLike(event)), ctx.widgets.seriesWidget.addListener("mouseleave", () => this.onMouseOut()), ctx.widgets.seriesDragInterpreter.addListener("click", (event) => this.onClick(event)), ctx.chartEventManager.addListener("series-focus-change", () => this.onKeyPress()), ctx.zoomManager.addListener("zoom-pan-start", () => this.onMouseOut()), ctx.zoomManager.addListener("zoom-change", () => this.onMouseOut()), ctx.highlightManager.addListener("highlight-change", (event) => this.onHighlightChange(event)), ctx.layoutManager.addListener("layout:complete", (event) => this.layout(event)), () => Object.entries(this.labels).forEach(([_, label]) => label.destroy()) ); } layout({ series: { rect, visible }, axes }) { if (!visible || !axes || !this.enabled) return; this.seriesRect = rect; const { position: axisPosition = "left", axisId } = this.axisCtx; const axisLayout = axes.find((a) => a.id === axisId); if (!axisLayout) return; this.axisLayout = axisLayout; this.bounds = rect.clone().grow(axisLayout.gridPadding + axisLayout.seriesAreaPadding, axisPosition); const { crosshairGroup, bounds } = this; crosshairGroup.translationX = Math.round(bounds.x); crosshairGroup.translationY = Math.round(bounds.y); const crosshairKeys = ["pointer", ...this.axisCtx.seriesKeyProperties()]; this.updateSelections(crosshairKeys); this.updateLines(); this.updateLabels(crosshairKeys); } updateSelections(data) { this.lineGroupSelection.update( data, (group) => group.append(new Line3()), (key) => key ); } updateLabels(keys) { const { labels, ctx } = this; for (const key of keys) { if (this.label.enabled) { labels[key] ?? (labels[key] = new CrosshairLabel(ctx.domManager, key, this.axisCtx.axisId)); } if (labels[key]) { this.updateLabel(labels[key]); } } this.labelFormatter = this.axisCtx.scaleValueFormatter(this.label.format); } updateLabel(label) { const { enabled, xOffset, yOffset, format, renderer } = this.label; label.enabled = enabled; label.xOffset = xOffset; label.yOffset = yOffset; label.format = format; label.renderer = renderer; } updateLines() { const { lineGroupSelection, bounds, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, axisLayout } = this; if (!axisLayout) return; const isVertical = this.isVertical(); lineGroupSelection.each((line) => { line.stroke = stroke22; line.strokeWidth = strokeWidth; line.strokeOpacity = strokeOpacity; line.lineDash = lineDash; line.lineDashOffset = lineDashOffset; line.y1 = 0; line.y2 = isVertical ? bounds.height : 0; line.x1 = 0; line.x2 = isVertical ? 0 : bounds.width; }); } isVertical() { return this.axisCtx.direction === ChartAxisDirection12.X; } isHover(event) { return event.type === "mousemove" || event.type === "click" || event.device === "touch" && this.ctx.chartService.touch.dragAction === "hover"; } formatValue(value) { const { labelFormatter, axisLayout, ctx: { callbackCache } } = this; if (labelFormatter) { const result = callbackCache.call(labelFormatter, value); if (result != null) { return result; } } if (typeof value === "number") { const fractionDigits = (axisLayout?.label.fractionDigits ?? 0) + (isInteger2(value) ? 0 : 1); return formatNumber2(value, fractionDigits); } return String(value ?? ""); } onClick(event) { if (event.device === "touch") { this.onMouseHoverLike(event); } } onMouseHoverLike(event) { if (!this.enabled || this.snap) return; const requiredState = this.isHover(event) ? InteractionState3.Clickable : InteractionState3.AnnotationsMoveable; if (!this.ctx.interactionManager.isState(requiredState)) return; this.updatePositions(this.getData(event)); this.crosshairGroup.visible = true; this.ctx.updateService.update(import_ag_charts_community107._ModuleSupport.ChartUpdateType.SCENE_RENDER); } onMouseOut() { if (!this.ctx.interactionManager.isState(InteractionState3.Clickable)) return; this.hideCrosshairs(); this.ctx.updateService.update(import_ag_charts_community107._ModuleSupport.ChartUpdateType.SCENE_RENDER); } onKeyPress() { if (this.enabled && !this.snap && this.ctx.interactionManager.isState(InteractionState3.Default)) { this.hideCrosshairs(); } } onHighlightChange(event) { if (!this.enabled) return; const { crosshairGroup, axisCtx } = this; const { datum, series } = event.currentHighlight ?? {}; const hasCrosshair = datum && (series?.axes.x?.id === axisCtx.axisId || series?.axes.y?.id === axisCtx.axisId); this.activeHighlight = hasCrosshair ? event.currentHighlight : void 0; if (!this.activeHighlight) { this.hideCrosshairs(); } else if (this.snap) { const activeHighlightData = this.getActiveHighlightData(this.activeHighlight); this.updatePositions(activeHighlightData); crosshairGroup.visible = true; } } isInRange(value) { return this.axisCtx.inRange(value); } updatePositions(data) { const { seriesRect, lineGroupSelection } = this; lineGroupSelection.each((line, key) => { const lineData = data[key]; if (!lineData) { line.visible = false; this.hideLabel(key); return; } line.visible = true; const { value, position } = lineData; let x = 0; let y = 0; if (this.isVertical()) { x = position; line.x = Math.round(x); } else { y = position; line.y = Math.round(y); } if (this.label.enabled) { this.showLabel(x + seriesRect.x, y + seriesRect.y, value, key); } else { this.hideLabel(key); } }); } getData(event) { const { axisCtx } = this; const key = "pointer"; const { datum, xKey = "", yKey = "" } = this.activeHighlight ?? {}; const { currentX, currentY } = event; const isVertical = this.isVertical(); const position = isVertical ? currentX : currentY; let value = datum?.[isVertical ? xKey : yKey] ?? ""; if (axisCtx.continuous) { value = axisCtx.scaleInvert(position); } return { [key]: { position, value } }; } getActiveHighlightData(activeHighlight) { const { axisCtx } = this; const { datum, series, xKey = "", aggregatedValue, cumulativeValue, midPoint } = activeHighlight; const seriesKeyProperties = series.getKeyProperties(axisCtx.direction); const halfBandwidth = (axisCtx.scale.bandwidth ?? 0) / 2; const matchingAxisId = series.axes[axisCtx.direction]?.id === axisCtx.axisId; const isYKey = seriesKeyProperties.indexOf("yKey") > -1 && matchingAxisId; const isXKey = seriesKeyProperties.indexOf("xKey") > -1 && matchingAxisId; const datumValue = aggregatedValue ?? cumulativeValue; if (isYKey && datumValue !== void 0) { const position = axisCtx.scale.convert(datumValue) + halfBandwidth; const isInRange = this.isInRange(position); return isInRange ? { yKey: { value: datumValue, position } } : {}; } if (isXKey) { const position = (this.isVertical() ? midPoint?.x : midPoint?.y) ?? 0; const value = axisCtx.continuous ? axisCtx.scaleInvert(position) : datum[xKey]; return this.isInRange(position) ? { xKey: { value, position } } : {}; } const activeHighlightData = {}; seriesKeyProperties.forEach((key) => { const keyValue = series.properties[key]; const value = datum[keyValue]; const position = axisCtx.scale.convert(value) + halfBandwidth; const isInRange = this.isInRange(position); if (isInRange) { activeHighlightData[key] = { value, position }; } }); return activeHighlightData; } getLabelHtml(value, label) { const fractionDigits = this.axisLayout?.label?.fractionDigits ?? 0; const defaults = { text: this.formatValue(value) }; if (this.label.renderer) { return label.toLabelHtml(this.label.renderer({ value, fractionDigits }), defaults); } return label.toLabelHtml(defaults); } showLabel(x, y, value, key) { if (!this.axisLayout) return; const { bounds } = this; const label = this.labels[key]; const html = this.getLabelHtml(value, label); label.setLabelHtml(html); const { width: width2, height: height2 } = label.getBBox(); const axisPosition = this.axisCtx.position; let padding = this.axisLayout.label.spacing + this.axisLayout.tickSize; if (this.axisCtx.direction === ChartAxisDirection12.X) { padding -= 4; label.show({ x: x - width2 / 2, y: axisPosition === "bottom" ? bounds.y + bounds.height + padding : bounds.y - height2 - padding }); } else { padding -= 8; label.show({ x: axisPosition === "right" ? bounds.x + bounds.width + padding : bounds.x - width2 - padding, y: y - height2 / 2 }); } } hideCrosshairs() { this.crosshairGroup.visible = false; for (const key of Object.keys(this.labels)) { this.hideLabel(key); } } hideLabel(key) { this.labels[key]?.toggle(false); } }; __decorateClass2([ Validate38(BOOLEAN15) ], Crosshair.prototype, "enabled", 2); __decorateClass2([ Validate38(COLOR_STRING4, { optional: true }) ], Crosshair.prototype, "stroke", 2); __decorateClass2([ Validate38(LINE_DASH3, { optional: true }) ], Crosshair.prototype, "lineDash", 2); __decorateClass2([ Validate38(POSITIVE_NUMBER7) ], Crosshair.prototype, "lineDashOffset", 2); __decorateClass2([ Validate38(POSITIVE_NUMBER7) ], Crosshair.prototype, "strokeWidth", 2); __decorateClass2([ Validate38(RATIO6) ], Crosshair.prototype, "strokeOpacity", 2); __decorateClass2([ Validate38(BOOLEAN15) ], Crosshair.prototype, "snap", 2); __decorateClass2([ Validate38(OBJECT16) ], Crosshair.prototype, "label", 2); var CrosshairModule = { type: "axis-option", optionsKey: "crosshair", packageType: "enterprise", chartTypes: ["cartesian"], axisTypes: ["category", "ordinal-time", "number", "log", "time"], moduleFactory: (ctx) => new Crosshair(ctx), themeTemplate: { crosshair: { snap: true, stroke: { $ref: "subtleTextColor" }, strokeWidth: 1, strokeOpacity: 1, lineDash: [5, 6], lineDashOffset: 0, label: { enabled: true } } } }; var import_ag_charts_community109 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN16, FUNCTION: FUNCTION3, ActionOnSet: ActionOnSet5, Validate: Validate39 } = import_ag_charts_community109._ModuleSupport; var DataSource = class extends import_ag_charts_community109._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.enabled = false; this.getData = () => Promise.resolve(); this.dataService = ctx.dataService; } updateCallback(enabled, getData) { if (!this.dataService) return; if (enabled && getData != null) { this.dataService.updateCallback(getData); } else { this.dataService.clearCallback(); } } }; __decorateClass2([ ActionOnSet5({ newValue(enabled) { this.updateCallback(enabled, this.getData); } }), Validate39(BOOLEAN16) ], DataSource.prototype, "enabled", 2); __decorateClass2([ ActionOnSet5({ newValue(getData) { this.updateCallback(this.enabled, getData); } }), Validate39(FUNCTION3) ], DataSource.prototype, "getData", 2); __decorateClass2([ ActionOnSet5({ newValue(requestThrottle) { this.dataService.requestThrottle = requestThrottle; } }) ], DataSource.prototype, "requestThrottle", 2); __decorateClass2([ ActionOnSet5({ newValue(updateThrottle) { this.dataService.dispatchThrottle = updateThrottle; } }) ], DataSource.prototype, "updateThrottle", 2); __decorateClass2([ ActionOnSet5({ newValue(updateDuringInteraction) { this.dataService.dispatchOnlyLatest = !updateDuringInteraction; } }) ], DataSource.prototype, "updateDuringInteraction", 2); var DataSourceModule = { type: "root", optionsKey: "dataSource", packageType: "enterprise", chartTypes: ["cartesian", "hierarchy", "polar", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new DataSource(ctx), themeTemplate: { dataSource: { enabled: false } } }; var import_ag_charts_community114 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community112 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community110 = (init_main4(), __toCommonJS(main_exports)); var { nearestSquaredInContainer: nearestSquaredInContainer2, partialAssign: partialAssign2, mergeDefaults: mergeDefaults2, BBox: BBox5 } = import_ag_charts_community110._ModuleSupport; var HierarchicalBBox = class { constructor(components) { this.components = components; this.union = BBox5.merge(components); } containsPoint(x, y) { if (!this.union.containsPoint(x, y)) { return false; } for (const bbox of this.components) { if (bbox.containsPoint(x, y)) { return true; } } return false; } }; var ErrorBarNode = class extends import_ag_charts_community110._ModuleSupport.Group { constructor() { super(); this.capLength = NaN; this._datum = void 0; this.whiskerPath = new import_ag_charts_community110._ModuleSupport.Path(); this.capsPath = new import_ag_charts_community110._ModuleSupport.Path(); this.bboxes = new HierarchicalBBox([]); this.append([this.whiskerPath, this.capsPath]); } get datum() { return this._datum; } set datum(datum) { this._datum = datum; } calculateCapLength(capsTheme, capDefaults) { const { lengthRatio = 1, length: length2 } = capsTheme; const { lengthRatioMultiplier, lengthMax } = capDefaults; const desiredLength = length2 ?? lengthRatio * lengthRatioMultiplier; return Math.min(desiredLength, lengthMax); } getItemStylerParams(options, style, highlighted) { const { datum } = this; if (datum == null || options.itemStyler == null) return; const { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = options; return { ...style, datum: datum.datum, seriesId: datum.datum.seriesId, xKey: datum.xKey, yKey: datum.yKey, xLowerKey, xUpperKey, yLowerKey, yUpperKey, highlighted }; } formatStyles(style, options, highlighted) { let { cap: capsStyle, ...whiskerStyle } = style; const params = this.getItemStylerParams(options, style, highlighted); if (params != null && options.itemStyler != null) { const result = options.itemStyler(params); whiskerStyle = mergeDefaults2(result, whiskerStyle); capsStyle = mergeDefaults2(result?.cap, result, capsStyle); } return { whiskerStyle, capsStyle }; } applyStyling(target, source) { partialAssign2( ["visible", "stroke", "strokeWidth", "strokeOpacity", "lineDash", "lineDashOffset"], target, source ); } update(style, formatters2, highlighted) { if (this.datum === void 0) { return; } const { whiskerStyle, capsStyle } = this.formatStyles(style, formatters2, highlighted); const { xBar, yBar, capDefaults } = this.datum; const whisker = this.whiskerPath; this.applyStyling(whisker, whiskerStyle); whisker.path.clear(true); if (yBar !== void 0) { whisker.path.moveTo(yBar.lowerPoint.x, yBar.lowerPoint.y); whisker.path.lineTo(yBar.upperPoint.x, yBar.upperPoint.y); } if (xBar !== void 0) { whisker.path.moveTo(xBar.lowerPoint.x, xBar.lowerPoint.y); whisker.path.lineTo(xBar.upperPoint.x, xBar.upperPoint.y); } whisker.path.closePath(); this.capLength = this.calculateCapLength(capsStyle ?? {}, capDefaults); const capOffset = this.capLength / 2; const caps = this.capsPath; this.applyStyling(caps, capsStyle); caps.path.clear(true); if (yBar !== void 0) { caps.path.moveTo(yBar.lowerPoint.x - capOffset, yBar.lowerPoint.y); caps.path.lineTo(yBar.lowerPoint.x + capOffset, yBar.lowerPoint.y); caps.path.moveTo(yBar.upperPoint.x - capOffset, yBar.upperPoint.y); caps.path.lineTo(yBar.upperPoint.x + capOffset, yBar.upperPoint.y); } if (xBar !== void 0) { caps.path.moveTo(xBar.lowerPoint.x, xBar.lowerPoint.y - capOffset); caps.path.lineTo(xBar.lowerPoint.x, xBar.lowerPoint.y + capOffset); caps.path.moveTo(xBar.upperPoint.x, xBar.upperPoint.y - capOffset); caps.path.lineTo(xBar.upperPoint.x, xBar.upperPoint.y + capOffset); } caps.path.closePath(); } updateBBoxes() { const { capLength, whiskerPath: whisker, capsPath: caps } = this; const { yBar, xBar } = this.datum ?? {}; const capOffset = capLength / 2; const components = []; if (yBar !== void 0) { const whiskerHeight = yBar.lowerPoint.y - yBar.upperPoint.y; components.push( new BBox5(yBar.lowerPoint.x, yBar.upperPoint.y, whisker.strokeWidth, whiskerHeight), new BBox5(yBar.lowerPoint.x - capOffset, yBar.lowerPoint.y, capLength, caps.strokeWidth), new BBox5(yBar.upperPoint.x - capOffset, yBar.upperPoint.y, capLength, caps.strokeWidth) ); } if (xBar !== void 0) { const whiskerWidth = xBar.upperPoint.x - xBar.lowerPoint.x; components.push( new BBox5(xBar.lowerPoint.x, xBar.upperPoint.y, whiskerWidth, whisker.strokeWidth), new BBox5(xBar.lowerPoint.x, xBar.lowerPoint.y - capOffset, caps.strokeWidth, capLength), new BBox5(xBar.upperPoint.x, xBar.upperPoint.y - capOffset, caps.strokeWidth, capLength) ); } this.bboxes.components = components; this.bboxes.union = BBox5.merge(components); } containsPoint(x, y) { return this.bboxes.containsPoint(x, y); } pickNode(x, y) { return this.containsPoint(x, y) ? this : void 0; } nearestSquared(x, y, maxDistance) { const { bboxes } = this; if (bboxes.union.distanceSquared(x, y) > maxDistance) { return { nearest: void 0, distanceSquared: Infinity }; } const { distanceSquared: distanceSquared2 } = BBox5.nearestBox(x, y, bboxes.components); return { nearest: this, distanceSquared: distanceSquared2 }; } }; var ErrorBarGroup = class extends import_ag_charts_community110._ModuleSupport.Group { nearestSquared(x, y) { const { nearest, distanceSquared: distanceSquared2 } = nearestSquaredInContainer2(x, y, { children: this.children() }); if (nearest !== void 0 && !isNaN(distanceSquared2)) { return { datum: nearest.datum, distanceSquared: distanceSquared2 }; } } }; var import_ag_charts_community111 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties14, Validate: Validate40, BOOLEAN: BOOLEAN17, COLOR_STRING: COLOR_STRING5, FUNCTION: FUNCTION4, LINE_DASH: LINE_DASH4, NUMBER: NUMBER11, OBJECT: OBJECT17, POSITIVE_NUMBER: POSITIVE_NUMBER8, RATIO: RATIO7, STRING: STRING20 } = import_ag_charts_community111._ModuleSupport; var ErrorBarCap = class extends BaseProperties14 { }; __decorateClass2([ Validate40(BOOLEAN17, { optional: true }) ], ErrorBarCap.prototype, "visible", 2); __decorateClass2([ Validate40(COLOR_STRING5, { optional: true }) ], ErrorBarCap.prototype, "stroke", 2); __decorateClass2([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarCap.prototype, "strokeWidth", 2); __decorateClass2([ Validate40(RATIO7, { optional: true }) ], ErrorBarCap.prototype, "strokeOpacity", 2); __decorateClass2([ Validate40(LINE_DASH4, { optional: true }) ], ErrorBarCap.prototype, "lineDash", 2); __decorateClass2([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarCap.prototype, "lineDashOffset", 2); __decorateClass2([ Validate40(NUMBER11, { optional: true }) ], ErrorBarCap.prototype, "length", 2); __decorateClass2([ Validate40(RATIO7, { optional: true }) ], ErrorBarCap.prototype, "lengthRatio", 2); var ErrorBarProperties = class extends BaseProperties14 { constructor() { super(...arguments); this.visible = true; this.stroke = "black"; this.strokeWidth = 1; this.strokeOpacity = 1; this.cap = new ErrorBarCap(); } }; __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yLowerKey", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yLowerName", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yUpperKey", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yUpperName", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xLowerKey", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xLowerName", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xUpperKey", 2); __decorateClass2([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xUpperName", 2); __decorateClass2([ Validate40(BOOLEAN17, { optional: true }) ], ErrorBarProperties.prototype, "visible", 2); __decorateClass2([ Validate40(COLOR_STRING5, { optional: true }) ], ErrorBarProperties.prototype, "stroke", 2); __decorateClass2([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate40(RATIO7, { optional: true }) ], ErrorBarProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate40(LINE_DASH4, { optional: true }) ], ErrorBarProperties.prototype, "lineDash", 2); __decorateClass2([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate40(FUNCTION4, { optional: true }) ], ErrorBarProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate40(OBJECT17) ], ErrorBarProperties.prototype, "cap", 2); var { fixNumericExtent: fixNumericExtent2, groupAccumulativeValueProperty: groupAccumulativeValueProperty2, mergeDefaults: mergeDefaults22, valueProperty: valueProperty22, ChartAxisDirection: ChartAxisDirection13 } = import_ag_charts_community112._ModuleSupport; function toErrorBoundCartesianSeries(ctx) { for (const supportedType of import_ag_charts_community112.AgErrorBarSupportedSeriesTypes) { if (supportedType === ctx.series.type) { return ctx.series; } } throw new Error( `AG Charts - unsupported series type '${ctx.series.type}', error bars supported series types: ${import_ag_charts_community112.AgErrorBarSupportedSeriesTypes.join(", ")}` ); } var ErrorBars = class _ErrorBars extends import_ag_charts_community112._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.properties = new ErrorBarProperties(); const series = toErrorBoundCartesianSeries(ctx); const { annotationGroup, annotationSelections } = series; this.cartesianSeries = series; this.groupNode = new ErrorBarGroup({ name: `${annotationGroup.id}-errorBars` }); annotationGroup.appendChild(this.groupNode); this.selection = import_ag_charts_community112._ModuleSupport.Selection.select(this.groupNode, () => this.errorBarFactory()); annotationSelections.add(this.selection); series.addEventListener("seriesVisibilityChange", (e) => this.onToggleSeriesItem(e)); this.destroyFns.push( series.addListener("data-processed", (e) => this.onDataProcessed(e)), series.addListener("data-update", (e) => this.onDataUpdate(e)), ctx.highlightManager.addListener("highlight-change", (event) => this.onHighlightChange(event)), () => annotationGroup.removeChild(this.groupNode), () => annotationSelections.delete(this.selection) ); } hasErrorBars() { const { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = this.properties; return isDefined2(xLowerKey) && isDefined2(xUpperKey) || isDefined2(yLowerKey) && isDefined2(yUpperKey); } isStacked() { const stackCount = this.cartesianSeries.seriesGrouping?.stackCount; return stackCount == null ? false : stackCount > 0; } getUnstackPropertyDefinition(opts) { const props = []; const { xLowerKey, xUpperKey, yLowerKey, yUpperKey, xErrorsID, yErrorsID } = this.getMaybeFlippedKeys(); const { xScaleType, yScaleType } = opts; if (yLowerKey != null && yUpperKey != null) { props.push( valueProperty22(yLowerKey, yScaleType, { id: `${yErrorsID}-lower` }), valueProperty22(yUpperKey, yScaleType, { id: `${yErrorsID}-upper` }) ); } if (xLowerKey != null && xUpperKey != null) { props.push( valueProperty22(xLowerKey, xScaleType, { id: `${xErrorsID}-lower` }), valueProperty22(xUpperKey, xScaleType, { id: `${xErrorsID}-upper` }) ); } return props; } getStackPropertyDefinition(opts) { const props = []; const { cartesianSeries } = this; const { xLowerKey, xUpperKey, yLowerKey, yUpperKey, xErrorsID, yErrorsID } = this.getMaybeFlippedKeys(); const { xScaleType, yScaleType } = opts; const groupIndex = cartesianSeries.seriesGrouping?.groupIndex ?? cartesianSeries.id; const groupOpts = { invalidValue: null, missingValue: 0, separateNegative: true, ...cartesianSeries.visible ? {} : { forceValue: 0 } }; const makeErrorProperty = (key, id, type, scaleType) => { return groupAccumulativeValueProperty2( key, "normal", "current", { id: `${id}-${type}`, groupId: `errorGroup-${groupIndex}-${type}`, ...groupOpts }, scaleType ); }; const pushErrorProperties = (lowerKey, upperKey, id, scaleType) => { props.push( ...makeErrorProperty(lowerKey, id, "lower", scaleType), ...makeErrorProperty(upperKey, id, "upper", scaleType) ); }; if (yLowerKey != null && yUpperKey != null) { pushErrorProperties(yLowerKey, yUpperKey, yErrorsID, yScaleType); } if (xLowerKey != null && xUpperKey != null) { pushErrorProperties(xLowerKey, xUpperKey, xErrorsID, xScaleType); } return props; } getPropertyDefinitions(opts) { if (this.isStacked()) { return this.getStackPropertyDefinition(opts); } else { return this.getUnstackPropertyDefinition(opts); } } onDataProcessed(event) { this.dataModel = event.dataModel; this.processedData = event.processedData; } getDomain(direction) { const { xLowerKey, xUpperKey, xErrorsID, yLowerKey, yUpperKey, yErrorsID } = this.getMaybeFlippedKeys(); const hasAxisErrors = direction === ChartAxisDirection13.X ? isDefined2(xLowerKey) && isDefined2(xUpperKey) : isDefined2(yLowerKey) && isDefined2(yUpperKey); if (hasAxisErrors) { const { dataModel, processedData, cartesianSeries: series } = this; if (dataModel != null && processedData != null) { const id = { x: xErrorsID, y: yErrorsID }[direction]; const lowerDomain = dataModel.getDomain(series, `${id}-lower`, "value", processedData); const upperDomain = dataModel.getDomain(series, `${id}-upper`, "value", processedData); const domain = [Math.min(...lowerDomain, ...upperDomain), Math.max(...lowerDomain, ...upperDomain)]; return fixNumericExtent2(domain); } } return []; } onDataUpdate(event) { this.dataModel = event.dataModel; this.processedData = event.processedData; if (isDefined2(event.dataModel) && isDefined2(event.processedData)) { this.createNodeData(); this.update(); } } getNodeData() { return this.hasErrorBars() ? this.cartesianSeries.contextNodeData?.nodeData : void 0; } createNodeData() { const nodeData = this.getNodeData(); const xScale = this.cartesianSeries.axes[ChartAxisDirection13.X]?.scale; const yScale = this.cartesianSeries.axes[ChartAxisDirection13.Y]?.scale; if (!xScale || !yScale || !nodeData) { return; } for (let i = 0; i < nodeData.length; i++) { const { midPoint, xLower, xUpper, yLower, yUpper } = this.getDatum(nodeData, i); if (midPoint != null) { let xBar, yBar; if (isDefined2(xLower) && isDefined2(xUpper)) { xBar = { lowerPoint: { x: this.convert(xScale, xLower), y: midPoint.y }, upperPoint: { x: this.convert(xScale, xUpper), y: midPoint.y } }; } if (isDefined2(yLower) && isDefined2(yUpper)) { yBar = { lowerPoint: { x: midPoint.x, y: this.convert(yScale, yLower) }, upperPoint: { x: midPoint.x, y: this.convert(yScale, yUpper) } }; } nodeData[i].xBar = xBar; nodeData[i].yBar = yBar; } } } getMaybeFlippedKeys() { let { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = this.properties; let [xErrorsID, yErrorsID] = ["xValue-errors", "yValue-errors"]; if (this.cartesianSeries.shouldFlipXY()) { [xLowerKey, yLowerKey] = [yLowerKey, xLowerKey]; [xUpperKey, yUpperKey] = [yUpperKey, xUpperKey]; [xErrorsID, yErrorsID] = [yErrorsID, xErrorsID]; } return { xLowerKey, xUpperKey, xErrorsID, yLowerKey, yUpperKey, yErrorsID }; } static getDatumKey(datum, key, offset4) { if (key == null) { return; } const value = datum.datum[key]; if (value == null) { return; } if (typeof value !== "number") { logger_exports2.warnOnce(`Found [${key}] error value of type ${typeof value}. Expected number type`); return; } return value + offset4; } getDatum(nodeData, datumIndex) { const { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = this.getMaybeFlippedKeys(); const datum = nodeData[datumIndex]; const d = datum.cumulativeValue == null || !this.isStacked() ? 0 : datum.cumulativeValue - datum.yValue; const [xOffset, yOffset] = this.cartesianSeries.shouldFlipXY() ? [d, 0] : [0, d]; return { midPoint: datum.midPoint, xLower: _ErrorBars.getDatumKey(datum, xLowerKey, xOffset), xUpper: _ErrorBars.getDatumKey(datum, xUpperKey, xOffset), yLower: _ErrorBars.getDatumKey(datum, yLowerKey, yOffset), yUpper: _ErrorBars.getDatumKey(datum, yUpperKey, yOffset) }; } convert(scale2, value) { const offset4 = (scale2.bandwidth ?? 0) / 2; return scale2.convert(value) + offset4; } update() { const nodeData = this.getNodeData(); if (nodeData != null) { this.selection.update(nodeData); this.selection.each((node, datum, i) => this.updateNode(node, datum, i)); } } updateNode(node, datum, _index) { node.datum = datum; node.update(this.getDefaultStyle(), this.properties, false); node.updateBBoxes(); } pickNodeExact(point) { const { x, y } = point; const node = this.groupNode.pickNode(x, y); if (node != null) { return { datum: node.datum, distanceSquared: 0 }; } } pickNodeNearest(point) { return this.groupNode.nearestSquared(point.x, point.y); } pickNodeMainAxisFirst(point) { return this.groupNode.nearestSquared(point.x, point.y); } getTooltipParams() { const { xLowerKey, xUpperKey, yLowerKey, yUpperKey, xLowerName = xLowerKey, xUpperName = xUpperKey, yLowerName = yLowerKey, yUpperName = yUpperKey } = this.properties; return { xLowerKey, xLowerName, xUpperKey, xUpperName, yLowerKey, yLowerName, yUpperKey, yUpperName }; } onToggleSeriesItem(event) { this.groupNode.visible = event.visible; } makeStyle(baseStyle) { return { visible: baseStyle.visible, lineDash: baseStyle.lineDash, lineDashOffset: baseStyle.lineDashOffset, stroke: baseStyle.stroke, strokeWidth: baseStyle.strokeWidth, strokeOpacity: baseStyle.strokeOpacity, cap: mergeDefaults22(this.properties.cap, baseStyle) }; } getDefaultStyle() { return this.makeStyle(this.getWhiskerProperties()); } getHighlightStyle() { return this.makeStyle(this.getWhiskerProperties()); } restyleHighlightChange(highlightChange, style, highlighted) { const nodeData = this.getNodeData(); if (nodeData == null) return; for (let i = 0; i < nodeData.length; i++) { if (highlightChange === nodeData[i]) { this.selection.at(i)?.update(style, this.properties, highlighted); break; } } } onHighlightChange(event) { const { previousHighlight, currentHighlight } = event; if (currentHighlight?.series === this.cartesianSeries) { this.restyleHighlightChange(currentHighlight, this.getHighlightStyle(), true); } if (previousHighlight?.series === this.cartesianSeries) { this.restyleHighlightChange(previousHighlight, this.getDefaultStyle(), false); } this.groupNode.opacity = this.cartesianSeries.getOpacity(); } errorBarFactory() { return new ErrorBarNode(); } getWhiskerProperties() { const { stroke: stroke22, strokeWidth, visible, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { stroke: stroke22, strokeWidth, visible, strokeOpacity, lineDash, lineDashOffset }; } }; var import_ag_charts_community113 = (init_main4(), __toCommonJS(main_exports)); var ERROR_BARS_THEME = { series: { errorBar: { visible: true, stroke: { $ref: "foregroundColor" }, strokeWidth: 1, strokeOpacity: 1, cap: { length: void 0, lengthRatio: void 0 } } } }; var ErrorBarsModule = { type: "series-option", identifier: "error-bars", optionsKey: "errorBar", packageType: "enterprise", chartTypes: ["cartesian"], seriesTypes: import_ag_charts_community114.AgErrorBarSupportedSeriesTypes, moduleFactory: (ctx) => new ErrorBars(ctx), themeTemplate: ERROR_BARS_THEME }; var import_ag_charts_community115 = (init_main4(), __toCommonJS(main_exports)); var { ZIndexMap: ZIndexMap5, ActionOnSet: ActionOnSet6, Validate: Validate41, ProxyPropertyOnWrite: ProxyPropertyOnWrite22, OBJECT: OBJECT18, RATIO: RATIO8, COLOR_STRING: COLOR_STRING6 } = import_ag_charts_community115._ModuleSupport; var Foreground = class extends import_ag_charts_community115._ModuleSupport.Background { constructor() { super(...arguments); this.image = new Image2(); this.fill = "transparent"; this.fillOpacity = void 0; } createNode() { return new import_ag_charts_community115._ModuleSupport.Group({ name: "foreground", zIndex: ZIndexMap5.FOREGROUND }); } onLayoutComplete(event) { super.onLayoutComplete(event); const { width: width2, height: height2 } = event.chart; let placement = { x: 0, y: 0, width: width2, height: height2 }; if (this.image) { placement = this.image.performLayout(width2, height2); } if (this.text) { this.updateTextNode(placement); } } onImageLoad() { this.ctx.updateService.update(import_ag_charts_community115._ModuleSupport.ChartUpdateType.SCENE_RENDER); } updateTextNode(placement) { const { textNode } = this; textNode.fontWeight = "bold"; textNode.fontFamily = "Impact, sans-serif"; textNode.fontSize = 19; textNode.opacity = 0.7; textNode.fill = "#9b9b9b"; textNode.textBaseline = "top"; const textBBox = this.textNode.getBBox(); const textPadding = 10; textNode.x = placement.x + placement.width / 2 - textBBox.width / 2; textNode.y = placement.y + placement.height + textPadding; } }; __decorateClass2([ Validate41(OBJECT18, { optional: true }), ActionOnSet6({ newValue(image) { this.node.appendChild(image.node); image.onLoad = () => this.onImageLoad(); }, oldValue(image) { this.node.removeChild(image.node); image.onLoad = void 0; } }) ], Foreground.prototype, "image", 2); __decorateClass2([ Validate41(COLOR_STRING6, { optional: true }), ProxyPropertyOnWrite22("rectNode", "fill") ], Foreground.prototype, "fill", 2); __decorateClass2([ Validate41(RATIO8, { optional: true }), ProxyPropertyOnWrite22("rectNode", "fillOpacity") ], Foreground.prototype, "fillOpacity", 2); var ForegroundModule = { type: "root", optionsKey: "foreground", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Foreground(ctx) }; var import_ag_charts_community123 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community122 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community117 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community116 = (init_main4(), __toCommonJS(main_exports)); var { TranslatableGroup: TranslatableGroup22, ScenePathChangeDetection: ScenePathChangeDetection2 } = import_ag_charts_community116._ModuleSupport; var MiniChartGroup = class extends TranslatableGroup22 { constructor() { super(...arguments); this.inset = 0; this.cornerRadius = 0; } applyClip(ctx, clipRect) { const { cornerRadius, inset } = this; const { x, y, width: width2, height: height2 } = clipRect; ctx.beginPath(); ctx.roundRect(x + inset, y + inset, width2 - 2 * inset, height2 - 2 * inset, cornerRadius); ctx.clip(); } }; __decorateClass2([ ScenePathChangeDetection2() ], MiniChartGroup.prototype, "inset", 2); __decorateClass2([ ScenePathChangeDetection2() ], MiniChartGroup.prototype, "cornerRadius", 2); var { Validate: Validate42, BOOLEAN: BOOLEAN18, POSITIVE_NUMBER: POSITIVE_NUMBER9, ZIndexMap: ZIndexMap6, ActionOnSet: ActionOnSet7, CategoryAxis: CategoryAxis2, TextUtils: TextUtils22, Padding: Padding2, Group: Group6, BBox: BBox6, ProxyProperty: ProxyProperty22 } = import_ag_charts_community117._ModuleSupport; var MiniChartPadding = class { constructor() { this.top = 0; this.bottom = 0; } }; __decorateClass2([ Validate42(POSITIVE_NUMBER9) ], MiniChartPadding.prototype, "top", 2); __decorateClass2([ Validate42(POSITIVE_NUMBER9) ], MiniChartPadding.prototype, "bottom", 2); var MiniChart = class extends import_ag_charts_community117._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = false; this.padding = new MiniChartPadding(); this.root = new Group6({ name: "root" }); this.seriesRoot = this.root.appendChild( new MiniChartGroup({ name: "Series-root", zIndex: ZIndexMap6.SERIES_LAYER, renderToOffscreenCanvas: true }) ); this.axisGridGroup = this.root.appendChild(new Group6({ name: "Axes-Grids", zIndex: ZIndexMap6.AXIS_GRID })); this.axisGroup = this.root.appendChild(new Group6({ name: "Axes-Grids", zIndex: ZIndexMap6.AXIS_GRID })); this.axisLabelGroup = this.root.appendChild(new Group6({ name: "Axes-Labels", zIndex: ZIndexMap6.SERIES_LABEL })); this.axisCrosslineRangeGroup = this.root.appendChild( new Group6({ name: "Axes-Crosslines-Range", zIndex: ZIndexMap6.SERIES_CROSSLINE_RANGE }) ); this.axisCrosslineLineGroup = this.root.appendChild( new Group6({ name: "Axes-Crosslines-Line", zIndex: ZIndexMap6.SERIES_CROSSLINE_LINE }) ); this.axisCrosslineLabelGroup = this.root.appendChild( new Group6({ name: "Axes-Crosslines-Label", zIndex: ZIndexMap6.SERIES_LABEL }) ); this.data = []; this._destroyed = false; this.miniChartAnimationPhase = "initial"; this.axes = []; this.series = []; } destroy() { if (this._destroyed) { return; } this.destroySeries(this.series); this.axes.forEach((a) => a.destroy()); this.axes = []; this._destroyed = true; } onSeriesChange(newValue, oldValue) { const seriesToDestroy = oldValue?.filter((series) => !newValue.includes(series)) ?? []; this.destroySeries(seriesToDestroy); for (const series of newValue) { if (oldValue?.includes(series)) continue; series.attachSeries(this.seriesRoot, this.seriesRoot, void 0); const chart = this; series.chart = { get mode() { return "standalone"; }, get isMiniChart() { return true; }, get seriesRect() { return chart.seriesRect; } }; series.resetAnimation(this.miniChartAnimationPhase === "initial" ? "initial" : "disabled"); } } destroySeries(allSeries) { allSeries?.forEach((series) => { series.destroy(); series.detachSeries(this.seriesRoot, this.seriesRoot, void 0); series.chart = void 0; }); } assignSeriesToAxes() { this.axes.forEach((axis) => { axis.boundSeries = this.series.filter((s) => { const seriesAxis = s.axes[axis.direction]; return seriesAxis === axis; }); }); } assignAxesToSeries() { const directionToAxesMap = {}; this.axes.forEach((axis) => { const direction = axis.direction; const directionAxes = directionToAxesMap[direction] ?? (directionToAxesMap[direction] = []); directionAxes.push(axis); }); this.series.forEach((series) => { series.directions.forEach((direction) => { const directionAxes = directionToAxesMap[direction]; if (!directionAxes) { logger_exports2.warnOnce( `no available axis for direction [${direction}]; check series and axes configuration.` ); return; } const seriesKeys = series.getKeys(direction); const newAxis = this.findMatchingAxis(directionAxes, seriesKeys); if (!newAxis) { logger_exports2.warnOnce( `no matching axis for direction [${direction}] and keys [${seriesKeys}]; check series and axes configuration.` ); return; } series.axes[direction] = newAxis; }); }); } findMatchingAxis(directionAxes, directionKeys) { for (const axis of directionAxes) { if (!axis.keys.length) { return axis; } if (!directionKeys) { continue; } for (const directionKey of directionKeys) { if (axis.keys.includes(directionKey)) { return axis; } } } } updateData(data) { this.series.forEach((s) => s.setChartData(data)); if (this.miniChartAnimationPhase === "initial") { this.ctx.animationManager.onBatchStop(() => { this.miniChartAnimationPhase = "ready"; this.series.forEach((s) => s.resetAnimation("disabled")); }); } } async processData(dataController) { if (this.series.some((s) => s.canHaveAxes)) { this.assignAxesToSeries(); this.assignSeriesToAxes(); } await Promise.all( this.series.map((s) => { s.resetDatumCallbackCache(); return s.processData(dataController); }) ); for (const axis of this.axes) { axis.processData(); } } computeAxisPadding() { const padding = new Padding2(); if (!this.enabled) { return padding; } this.axes.forEach(({ position, thickness, line, label }) => { if (position == null) return; let size; if (thickness) { size = thickness; } else { size = (line.enabled ? line.width : 0) + (label.enabled ? TextUtils22.getLineHeight(label.fontSize ?? 0) + label.spacing : 0); } padding[position] = Math.ceil(size); }); return padding; } async layout(width2, height2) { const { padding } = this; const animated = this.seriesRect != null; const seriesRect = new BBox6(0, 0, width2, height2 - (padding.top + padding.bottom)); this.seriesRect = seriesRect; this.seriesRoot.translationY = padding.top; this.seriesRoot.setClipRectCanvasSpace(new BBox6(0, -padding.top, width2, height2)); this.axes.forEach((axis) => { const { position = "left" } = axis; switch (position) { case "top": case "bottom": axis.range = [0, seriesRect.width]; axis.gridLength = seriesRect.height; break; case "right": case "left": { const isCategoryAxis = axis instanceof CategoryAxis2; axis.range = isCategoryAxis ? [0, seriesRect.height] : [seriesRect.height, 0]; axis.gridLength = seriesRect.width; break; } } axis.gridPadding = 0; axis.translation.x = 0; axis.translation.y = 0; if (position === "right") { axis.translation.x = width2; } else if (position === "bottom") { axis.translation.y = height2; } if (!animated) { axis.resetAnimation("initial"); } axis.calculateLayout(); axis.update(); }); await Promise.all(this.series.map((series) => series.update({ seriesRect }))); } }; __decorateClass2([ Validate42(BOOLEAN18) ], MiniChart.prototype, "enabled", 2); __decorateClass2([ ProxyProperty22(["seriesRoot", "inset"]) ], MiniChart.prototype, "inset", 2); __decorateClass2([ ProxyProperty22(["seriesRoot", "cornerRadius"]) ], MiniChart.prototype, "cornerRadius", 2); __decorateClass2([ ActionOnSet7({ changeValue(newValue, oldValue = []) { const axisNodes = { axisNode: this.axisGroup, gridNode: this.axisGridGroup, labelNode: this.axisLabelGroup, crossLineLineNode: this.axisCrosslineLineGroup, crossLineRangeNode: this.axisCrosslineRangeGroup, crossLineLabelNode: this.axisCrosslineLabelGroup }; for (const axis of oldValue) { if (newValue.includes(axis)) continue; axis.detachAxis(axisNodes); axis.destroy(); } for (const axis of newValue) { if (oldValue?.includes(axis)) continue; axis.attachAxis(axisNodes); } } }) ], MiniChart.prototype, "axes", 2); __decorateClass2([ ActionOnSet7({ changeValue(newValue, oldValue) { this.onSeriesChange(newValue, oldValue); } }) ], MiniChart.prototype, "series", 2); var import_ag_charts_community118 = (init_main4(), __toCommonJS(main_exports)); var { clamp: clamp5, SliderWidget: SliderWidget2 } = import_ag_charts_community118._ModuleSupport; var NavigatorDOMProxy = class { constructor(ctx, sliderHandlers) { this.ctx = ctx; this.sliderHandlers = sliderHandlers; this._min = 0; this._max = 1; this.minRange = 1e-3; this.dragStartX = 0; this.ctx = ctx; this.toolbar = ctx.proxyInteractionService.createProxyContainer({ type: "toolbar", domManagerId: `navigator-toolbar`, classList: ["ag-charts-proxy-navigator-toolbar"], orientation: "vertical", ariaLabel: { id: "ariaLabelNavigator" } }); this.sliders = [ ctx.proxyInteractionService.createProxyElement({ type: "slider", domIndex: 1, ariaLabel: { id: "ariaLabelNavigatorMinimum" }, parent: this.toolbar, cursor: "ew-resize" }), ctx.proxyInteractionService.createProxyElement({ type: "slider", domIndex: -Infinity, ariaLabel: { id: "ariaLabelNavigatorRange" }, parent: this.toolbar, cursor: "grab" }), ctx.proxyInteractionService.createProxyElement({ type: "slider", domIndex: 2, ariaLabel: { id: "ariaLabelNavigatorMaximum" }, parent: this.toolbar, cursor: "ew-resize" }) ]; for (const [index, key] of ["min", "pan", "max"].entries()) { const slider = this.sliders[index]; slider.step = SliderWidget2.STEP_HUNDRETH; slider.keyboardStep = SliderWidget2.STEP_ONE; slider.orientation = "horizontal"; slider.setPreventsDefault(false); slider.addListener("drag-start", (ev) => this.onDragStart(index, ev, key)); slider.addListener("drag-move", (ev) => this.onDrag(slider, ev, key)); slider.addListener("drag-end", () => this.updateSliderRatios()); slider.addListener("contextmenu", (ev) => this.onContextMenu(slider, ev)); } this.sliders[0].addListener("change", () => this.onMinSliderChange()); this.sliders[1].addListener("change", () => this.onPanSliderChange()); this.sliders[2].addListener("change", () => this.onMaxSliderChange()); this.updateSliderRatios(); this.updateVisibility(false); } destroy() { this.toolbar.destroy(); } updateVisibility(visible) { this.toolbar.setHidden(!visible); } updateZoom() { const { _min: min, _max: max } = this; if (min == null || max == null) return; return this.ctx.zoomManager.updateZoom("navigator", { x: { min, max } }); } updateBounds(bounds) { this.toolbar.setBounds(bounds); } updateSliderBounds(sliderIndex, bounds) { this.sliders[sliderIndex].setBounds(bounds); } updateMinMax(min, max) { this._min = min; this._max = max; this.updateSliderRatios(); } updateSliderRatios() { const { _min: min, _max: max } = this; const panAria = this.ctx.localeManager.t("ariaValuePanRange", { min, max }); this.sliders[0].setValueRatio(min); this.sliders[1].setValueRatio(min, { ariaValueText: panAria }); this.sliders[2].setValueRatio(max); } toCanvasOffsets(event) { return { offsetX: this.dragStartX + event.originDeltaX }; } moveToFront(index) { if (index === 1) return; const frontSlider = this.sliders[index]; const otherSlider = this.sliders[2 - index]; this.toolbar.moveChild(otherSlider, frontSlider.domIndex - 1); } onDragStart(index, event, key) { const slider = this.sliders[index]; const toolbarLeft = this.toolbar.cssLeft(); const sliderLeft = slider.cssLeft(); this.dragStartX = toolbarLeft + sliderLeft + event.offsetX; this.moveToFront(index); if (event.device === "touch") { event.sourceEvent.preventDefault(); } this.sliderHandlers.onDragStart(key, this.toCanvasOffsets(event)); } onDrag(_slider, event, key) { if (event.device === "touch") { event.sourceEvent.preventDefault(); } this.sliderHandlers.onDrag(key, this.toCanvasOffsets(event)); } onContextMenu(slider, { sourceEvent, offsetX, offsetY }) { const { x: toolbarX, y: toolbarY } = this.toolbar.getBounds(); const { x: sliderX, y: sliderY } = slider.getBounds(); const canvasX = offsetX + toolbarX + sliderX; const canvasY = offsetY + toolbarY + sliderY; this.ctx.contextMenuRegistry.dispatchContext("all", { sourceEvent, canvasX, canvasY }, {}); } onPanSliderChange() { const ratio2 = this.sliders[1].getValueRatio(); const span = this._max - this._min; this._min = clamp5(0, ratio2, 1 - span); this._max = this._min + span; this.updateZoom(); } onMinSliderChange() { this._min = this.sliders[0].clampValueRatio(0, this._max - this.minRange); this.updateZoom(); } onMaxSliderChange() { this._max = this.sliders[2].clampValueRatio(this._min + this.minRange, 1); this.updateZoom(); } }; var import_ag_charts_community119 = (init_main4(), __toCommonJS(main_exports)); var { Validate: Validate43, ScenePathChangeDetection: ScenePathChangeDetection22, POSITIVE_NUMBER: POSITIVE_NUMBER10, BOOLEAN: BOOLEAN19, BBox: BBox7, ExtendedPath2D: ExtendedPath2D2 } = import_ag_charts_community119._ModuleSupport; var RangeHandle = class extends import_ag_charts_community119._ModuleSupport.Path { constructor() { super(...arguments); this.zIndex = 3; this.centerX = 0; this.centerY = 0; this.width = 8; this.height = 16; this.cornerRadius = 4; this.grip = true; this.gripPath = new ExtendedPath2D2(); } setCenter(x, y) { this.dirtyPath = true; if (this.centerX !== x || this.centerY !== y) { this.centerX = x; this.centerY = y; this.markDirty(); } } static align(minHandle, maxHandle, x, y, width2, height2, min, max, pixelAlign) { const minHandleX = minHandle.align(x + width2 * min) + pixelAlign; const maxHandleX = minHandleX + minHandle.align(x + width2 * min, width2 * (max - min)) - 2 * pixelAlign; const handleY = minHandle.align(y + height2 / 2); minHandle.setCenter(minHandleX, handleY); maxHandle.setCenter(maxHandleX, handleY); } computeBBox() { const { centerX, centerY, width: width2, height: height2 } = this; const x = centerX - width2 / 2; const y = centerY - height2 / 2; return new BBox7(x, y, width2, height2); } isPointInPath(x, y) { const bbox = this.getBBox(); return bbox.containsPoint(x, y); } updatePath() { const { centerX, centerY, path, gripPath, strokeWidth, cornerRadius, grip } = this; const pixelAlign = strokeWidth / 2; const pixelRatio = this.layerManager?.canvas?.pixelRatio ?? 1; path.clear(); gripPath.clear(); const halfWidth = Math.floor(this.width / 2 * pixelRatio) / pixelRatio; const halfHeight = Math.floor(this.height / 2 * pixelRatio) / pixelRatio; path.roundRect( centerX - halfWidth + pixelAlign, centerY - halfHeight + pixelAlign, 2 * (halfWidth - pixelAlign), 2 * (halfHeight - pixelAlign), cornerRadius ); const gripSpacing = 3; if (grip) { for (let x = -0.5; x <= 0.5; x += 1) { for (let y = -1; y <= 1; y += 1) { gripPath.arc(centerX + x * gripSpacing, centerY + y * gripSpacing, 1, 0, 2 * Math.PI); gripPath.closePath(); } } } } renderFill(ctx, path) { const { stroke: stroke22 } = this; super.renderFill(ctx, path); ctx.fillStyle = typeof stroke22 === "string" ? stroke22 : "black"; ctx.fill(this.gripPath.getPath2D()); } }; RangeHandle.className = "RangeHandle"; __decorateClass2([ Validate43(POSITIVE_NUMBER10), ScenePathChangeDetection22() ], RangeHandle.prototype, "width", 2); __decorateClass2([ Validate43(POSITIVE_NUMBER10), ScenePathChangeDetection22() ], RangeHandle.prototype, "height", 2); __decorateClass2([ Validate43(POSITIVE_NUMBER10), ScenePathChangeDetection22() ], RangeHandle.prototype, "cornerRadius", 2); __decorateClass2([ Validate43(BOOLEAN19), ScenePathChangeDetection22() ], RangeHandle.prototype, "grip", 2); var import_ag_charts_community120 = (init_main4(), __toCommonJS(main_exports)); var { Path: Path6, BBox: BBox8, ExtendedPath2D: ExtendedPath2D22, clippedRoundRect: clippedRoundRect2, POSITIVE_NUMBER: POSITIVE_NUMBER11, Validate: Validate44, ScenePathChangeDetection: ScenePathChangeDetection3 } = import_ag_charts_community120._ModuleSupport; var RangeMask = class extends Path6 { constructor() { super(...arguments); this.cornerRadius = 4; this.zIndex = 2; this.x = 0; this.y = 0; this.width = 200; this.height = 30; this.min = 0; this.max = 1; this.visiblePath = new ExtendedPath2D22(); } layout(x, y, width2, height2, min, max) { min = isNaN(min) ? this.min : min; max = isNaN(max) ? this.max : max; if (x !== this.x || y !== this.y || width2 !== this.width || this.height !== height2 || min !== this.min || max !== this.max) { this.x = x; this.y = y; this.width = width2; this.height = height2; this.min = min; this.max = max; this.dirtyPath = true; this.markDirty(); } } computeBBox() { const { x, y, width: width2, height: height2 } = this; return new BBox8(x, y, width2, height2); } computeVisibleRangeBBox() { const { x, y, width: width2, height: height2, min, max } = this; const minX = x + width2 * min; const maxX = x + width2 * max; return new BBox8(minX, y, maxX - minX, height2); } updatePath() { const { path, visiblePath, x, y, width: width2, height: height2, min, max, strokeWidth, cornerRadius } = this; const pixelAlign = strokeWidth / 2; path.clear(); visiblePath.clear(); const ax = this.align(x) + pixelAlign; const ay = this.align(y) + pixelAlign; const aw = this.align(x, width2) - 2 * pixelAlign; const ah = this.align(y, height2) - 2 * pixelAlign; const minX = this.align(x + width2 * min) + pixelAlign; const maxX = minX + this.align(x + width2 * min, width2 * (max - min)) - 2 * pixelAlign; const cornerRadiusParams = { topLeft: cornerRadius, topRight: cornerRadius, bottomRight: cornerRadius, bottomLeft: cornerRadius }; clippedRoundRect2(path, ax, ay, aw, ah, cornerRadiusParams, new BBox8(ax, ay, minX - ax, ah)); clippedRoundRect2(path, ax, ay, aw, ah, cornerRadiusParams, new BBox8(maxX, ay, aw + ax - maxX, ah)); if (maxX - minX > 1) { clippedRoundRect2(visiblePath, ax, ay, aw, ah, cornerRadiusParams, new BBox8(minX, ay, maxX - minX, ah)); } } renderStroke(ctx, path) { super.renderStroke(ctx, path); super.renderStroke(ctx, this.visiblePath.getPath2D()); } }; RangeMask.className = "RangeMask"; __decorateClass2([ Validate44(POSITIVE_NUMBER11), ScenePathChangeDetection3() ], RangeMask.prototype, "cornerRadius", 2); var import_ag_charts_community121 = (init_main4(), __toCommonJS(main_exports)); var RangeSelector = class extends import_ag_charts_community121._ModuleSupport.Group { constructor(children) { super({ name: "rangeSelectorGroup", zIndex: import_ag_charts_community121._ModuleSupport.ZIndexMap.NAVIGATOR }); this.x = 0; this.y = 0; this.width = 200; this.height = 30; this.lOffset = 0; this.rOffset = 0; this.background = this.appendChild( new import_ag_charts_community121._ModuleSupport.TranslatableGroup({ name: "navigator-background", zIndex: 1 }) ); this.append(children); } layout(x, y, width2, height2, lOffset, rOffset) { this.x = x; this.y = y; this.width = width2; this.height = height2; this.lOffset = lOffset; this.rOffset = rOffset; this.background.translationX = x; this.background.translationY = y; this.markDirty(); } updateBackground(oldGroup, newGroup) { if (oldGroup != null) { this.background.removeChild(oldGroup); } if (newGroup != null) { this.background.appendChild(newGroup); } this.markDirty(); } computeBBox() { const { x, y, width: width2, height: height2, lOffset, rOffset } = this; return new import_ag_charts_community121._ModuleSupport.BBox(x - lOffset, y, width2 + (lOffset + rOffset), height2); } }; var { clamp: clamp6, BaseModuleInstance: BaseModuleInstance22, ObserveChanges: ObserveChanges4, Validate: Validate45, BOOLEAN: BOOLEAN20, POSITIVE_NUMBER: POSITIVE_NUMBER12 } = import_ag_charts_community122._ModuleSupport; var Navigator = class extends BaseModuleInstance22 { constructor(ctx) { super(); this.ctx = ctx; this.enabled = false; this.mask = new RangeMask(); this.minHandle = new RangeHandle(); this.maxHandle = new RangeHandle(); this.maskVisibleRange = { id: "navigator-mask-visible-range", getBBox: () => this.mask.computeVisibleRangeBBox(), toCanvasBBox: () => this.mask.computeVisibleRangeBBox(), fromCanvasPoint: (x, y) => ({ x, y }) }; this.height = 30; this.cornerRadius = 0; this.spacing = 10; this.x = 0; this.y = 0; this.width = 0; this.rangeSelector = new RangeSelector([this.mask, this.minHandle, this.maxHandle]); this.destroyFns.push( ctx.scene.attachNode(this.rangeSelector), this.ctx.localeManager.addListener("locale-changed", () => this.updateZoom()), this.ctx.layoutManager.registerElement( import_ag_charts_community122._ModuleSupport.LayoutElement.Navigator, (e) => this.onLayoutStart(e) ), this.ctx.layoutManager.addListener("layout:complete", (e) => this.onLayoutComplete(e)), ctx.zoomManager.addListener("zoom-change", (event) => this.onZoomChange(event)) ); this.domProxy = new NavigatorDOMProxy(ctx, this); this.updateGroupVisibility(); this.miniChart = new MiniChart(ctx); } updateBackground(oldGroup, newGroup) { this.rangeSelector?.updateBackground(oldGroup, newGroup); } updateGroupVisibility() { const { enabled } = this; if (this.rangeSelector == null || enabled === this.rangeSelector.visible) return; this.rangeSelector.visible = enabled; this.domProxy.updateVisibility(enabled); if (enabled) { this.updateZoom(); } else { this.ctx.zoomManager.updateZoom("navigator"); } } onLayoutStart(ctx) { if (this.enabled) { const { layoutBox } = ctx; const navigatorTotalHeight = this.height + this.spacing; layoutBox.shrink(navigatorTotalHeight, "bottom"); this.y = layoutBox.y + layoutBox.height + this.spacing; } else { this.y = 0; } if (this.enabled && this.miniChart) { const { top, bottom } = this.miniChart.computeAxisPadding(); ctx.layoutBox.shrink(top + bottom, "bottom"); this.y -= bottom; this.miniChart.inset = this.mask.strokeWidth / 2; this.miniChart.cornerRadius = this.mask.cornerRadius; } } onLayoutComplete(opts) { const { x, width: width2 } = opts.series.rect; const { y, height: height2 } = this; this.domProxy.updateVisibility(this.enabled); if (this.enabled) { const { _min: min, _max: max } = this.domProxy; this.layoutNodes(x, y, width2, height2, min, max); this.domProxy.updateBounds({ x, y, width: width2, height: height2 }); } this.x = x; this.width = width2; this.miniChart?.layout(width2, height2).catch((e) => logger_exports2.error(e)); } canDrag() { return this.enabled && this.ctx.interactionManager.isState(import_ag_charts_community122._ModuleSupport.InteractionState.ZoomDraggable); } onDragStart(dragging, { offsetX }) { if (!this.canDrag()) return; if (dragging === "pan") { this.panStart = (offsetX - this.x) / this.width - this.domProxy._min; } this.ctx.zoomManager.fireZoomPanStartEvent("navigator"); } onDrag(dragging, { offsetX }) { if (!this.canDrag()) return; const { panStart, x, width: width2 } = this; const { minRange } = this.domProxy; let { _min: min, _max: max } = this.domProxy; const ratio2 = (offsetX - x) / width2; if (dragging === "min") { min = clamp6(0, ratio2, max - minRange); } else if (dragging === "max") { max = clamp6(min + minRange, ratio2, 1); } else if (dragging === "pan" && panStart != null) { const span = max - min; min = clamp6(0, ratio2 - panStart, 1 - span); max = min + span; } this.domProxy._min = min; this.domProxy._max = max; this.updateZoom(); } onZoomChange(event) { const { x: xZoom } = event; if (!xZoom) return; const { x, y, width: width2, height: height2 } = this; const { min, max } = xZoom; this.domProxy.updateMinMax(min, max); this.layoutNodes(x, y, width2, height2, min, max); } layoutNodes(x, y, width2, height2, min, max) { const { rangeSelector, mask, minHandle, maxHandle } = this; mask.layout(x, y, width2, height2, min, max); rangeSelector.layout(x, y, width2, height2, minHandle.width / 2, maxHandle.width / 2); RangeHandle.align(minHandle, maxHandle, x, y, width2, height2, min, max, mask.strokeWidth / 2); if (min + (max - min) / 2 < 0.5) { minHandle.zIndex = 3; maxHandle.zIndex = 4; } else { minHandle.zIndex = 4; maxHandle.zIndex = 3; } [minHandle, this.maskVisibleRange, maxHandle].forEach((node, index) => { const bbox = node.getBBox(); const tbox = { x: bbox.x - x, y: bbox.y - y, height: bbox.height, width: bbox.width }; this.domProxy.updateSliderBounds(index, tbox); }); } updateZoom() { if (!this.enabled) return; this.domProxy.updateZoom(); } updateData(data) { return this.miniChart?.updateData(data); } async processData(dataController) { if (this.miniChart) { return this.miniChart?.processData(dataController); } } }; __decorateClass2([ ObserveChanges4((target, value, oldValue) => { target.updateBackground(oldValue?.root, value?.root); }) ], Navigator.prototype, "miniChart", 2); __decorateClass2([ Validate45(BOOLEAN20), ObserveChanges4((target, value) => { target.ctx.zoomManager.setNavigatorEnabled(Boolean(value)); target.updateGroupVisibility(); }) ], Navigator.prototype, "enabled", 2); __decorateClass2([ Validate45(POSITIVE_NUMBER12) ], Navigator.prototype, "height", 2); __decorateClass2([ Validate45(POSITIVE_NUMBER12), ObserveChanges4((target, value) => { target.mask.cornerRadius = value; }) ], Navigator.prototype, "cornerRadius", 2); __decorateClass2([ Validate45(POSITIVE_NUMBER12) ], Navigator.prototype, "spacing", 2); var NavigatorModule = { type: "root", optionsKey: "navigator", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new Navigator(ctx), removable: false, // Toggling this module causes zoom state flakiness. themeTemplate: { navigator: { enabled: false, height: 18, cornerRadius: 4, mask: { fill: { $ref: "foregroundColor" }, fillOpacity: 0.1, stroke: { $ref: "borderColor" }, strokeWidth: 1 }, minHandle: { fill: { $ref: "backgroundColor" }, stroke: { $ref: "borderColor" }, strokeWidth: 1, width: 12, height: 24, cornerRadius: 4 }, maxHandle: { fill: { $ref: "backgroundColor" }, stroke: { $ref: "borderColor" }, strokeWidth: 1, width: 12, height: 24, cornerRadius: 4 }, miniChart: { enabled: false, label: { color: { $ref: "textColor" }, fontSize: { $rem: [import_ag_charts_community123._ModuleSupport.FONT_SIZE_RATIO.SMALLER] }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, spacing: 5 }, padding: { top: 0, bottom: 0 } } } } }; var import_ag_charts_community125 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community124 = (init_main4(), __toCommonJS(main_exports)); var { AND: AND4, ARRAY: ARRAY4, FUNCTION: FUNCTION5, NUMBER: NUMBER12, OR: OR3, ToolbarButtonProperties: ToolbarButtonProperties3, Validate: Validate46 } = import_ag_charts_community124._ModuleSupport; var RangesButtonProperties = class extends ToolbarButtonProperties3 { }; __decorateClass2([ Validate46(OR3(NUMBER12, AND4(ARRAY4, ARRAY4.restrict({ length: 2 })), FUNCTION5)) ], RangesButtonProperties.prototype, "value", 2); var { BOOLEAN: BOOLEAN21, OBJECT: OBJECT19, ChartAxisDirection: ChartAxisDirection14, LayoutElement: LayoutElement3, PropertiesArray: PropertiesArray4, Toolbar: Toolbar2, Validate: Validate47 } = import_ag_charts_community125._ModuleSupport; var Ranges = class extends import_ag_charts_community125._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = false; this.buttons = new PropertiesArray4(RangesButtonProperties); this.verticalSpacing = 10; this.container = ctx.domManager.addChild("canvas-overlay", "range-buttons"); this.container.role = "presentation"; this.toolbar = new Toolbar2(this.ctx.localeManager); this.toolbar.addClass("ag-charts-range-buttons"); this.container.append(this.toolbar.getElement()); this.destroyFns.push( this.toolbar.addToolbarListener("button-pressed", this.onButtonPress.bind(this)), ctx.layoutManager.registerElement(LayoutElement3.ToolbarBottom, this.onLayoutStart.bind(this)), ctx.zoomManager.addListener("zoom-change", this.onZoomChanged.bind(this)), this.teardown.bind(this) ); } teardown() { this.container.removeChild(this.toolbar.getElement()); this.toolbar.destroy(); } onLayoutStart(event) { const { buttons: buttons2, ctx, enabled, toolbar: toolbar2, verticalSpacing } = this; const { layoutBox } = event; if (!enabled || !ctx.zoomManager.isZoomEnabled()) { toolbar2.setHidden(true); return; } toolbar2.setHidden(false); toolbar2.updateButtons(buttons2); const height2 = toolbar2.getBounds().height; toolbar2.setBounds({ x: layoutBox.x, y: layoutBox.y + layoutBox.height - height2, width: layoutBox.width, height: height2 }); layoutBox.shrink({ bottom: height2 + verticalSpacing }); } onZoomChanged() { this.toolbar.clearActiveButton(); } onButtonPress({ button: { index } }) { const { zoomManager } = this.ctx; const button = this.buttons.at(index); if (!button) return; const { value } = button; if (typeof value === "number") { zoomManager.extendToEnd("zoom-buttons", ChartAxisDirection14.X, value); } else if (Array.isArray(value)) { zoomManager.updateWith("zoom-buttons", ChartAxisDirection14.X, () => value); } else if (typeof value === "function") { zoomManager.updateWith("zoom-buttons", ChartAxisDirection14.X, value); } this.toolbar.toggleActiveButtonByIndex(index); } }; __decorateClass2([ Validate47(BOOLEAN21) ], Ranges.prototype, "enabled", 2); __decorateClass2([ Validate47(OBJECT19) ], Ranges.prototype, "buttons", 2); var DAY = 1e3 * 60 * 60 * 24; var MONTH = DAY * 30; var YEAR = DAY * 365; var RangesModule = { type: "root", optionsKey: "ranges", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new Ranges(ctx), themeTemplate: { ranges: { enabled: false, buttons: [ { label: "toolbarRange1Month", ariaLabel: "toolbarRange1MonthAria", value: MONTH }, { label: "toolbarRange3Months", ariaLabel: "toolbarRange3MonthsAria", value: 3 * MONTH }, { label: "toolbarRange6Months", ariaLabel: "toolbarRange6MonthsAria", value: 6 * MONTH }, { label: "toolbarRangeYearToDate", ariaLabel: "toolbarRangeYearToDateAria", value: (_start, end2) => [(/* @__PURE__ */ new Date(`${new Date(end2).getFullYear()}-01-01`)).getTime(), end2] }, { label: "toolbarRange1Year", ariaLabel: "toolbarRange1YearAria", value: YEAR }, { label: "toolbarRangeAll", ariaLabel: "toolbarRangeAllAria", value: (start2, end2) => [start2, end2] } ] } } }; var import_ag_charts_community127 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community126 = (init_main4(), __toCommonJS(main_exports)); var _SharedToolbar = class _SharedToolbar2 extends import_ag_charts_community126._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.activeSections = /* @__PURE__ */ new Set(); this.sectionButtons = { annotations: [], chartToolbar: [] }; this.container = this.ctx.domManager.addChild("canvas-overlay", "shared-toolbar"); this.container.role = "presentation"; } getSharedToolbar(section) { if (!this.sharedToolbar) { this.createSharedToolbar(); } return this.toolbarWithSection(section); } createSharedToolbar() { this.sharedToolbar = new import_ag_charts_community126._ModuleSupport.Toolbar(this.ctx.localeManager, "vertical"); this.sharedToolbar.addClass("ag-charts-shared-toolbar"); this.container.append(this.sharedToolbar.getElement()); this.destroyFns.push(() => { if (!this.sharedToolbar) return; this.container.removeChild(this.sharedToolbar.getElement()); this.sharedToolbar.destroy(); this.sharedToolbar = void 0; }); } toolbarWithSection(section) { const sharedToolbar = this.sharedToolbar; const withSection = { layout: (layoutBox, padding) => { if (this.firstLayoutSection != null && this.firstLayoutSection !== section && this.activeSections.has(this.firstLayoutSection)) { return; } this.firstLayoutSection = section; const width2 = sharedToolbar.getBounds().width; sharedToolbar.setBounds({ x: layoutBox.x, y: layoutBox.y, width: width2 }); layoutBox.shrink({ left: width2 + sharedToolbar.horizontalSpacing + (padding ?? 0) }); }, addToolbarListener: (eventType, handler) => { return sharedToolbar.addToolbarListener(eventType, (sharedEvent) => { const sectionIndex = this.getSectionIndex(section, sharedEvent.button.index); if (sectionIndex < 0) return; const event = { ...sharedEvent, button: this.sectionButtons[section][sectionIndex] }; handler(event); }); }, updateButtons: (buttons2) => { this.sectionButtons[section] = buttons2; const sharedButtons = _SharedToolbar2.SECTION_ORDER.flatMap((order) => this.sectionButtons[order]); sharedToolbar.updateButtons(sharedButtons); }, updateButtonByIndex: (index, button) => { sharedToolbar.updateButtonByIndex(this.getIndex(section, index), button); }, toggleActiveButtonByIndex: (index) => { sharedToolbar.toggleActiveButtonByIndex(this.getIndex(section, index)); }, toggleButtonEnabledByIndex: (index, enabled) => { sharedToolbar.toggleButtonEnabledByIndex(this.getIndex(section, index), enabled); }, setHidden: (hidden) => { if (hidden) { this.activeSections.delete(section); } else { this.activeSections.add(section); } let sum2 = 0; for (const order of _SharedToolbar2.SECTION_ORDER) { if (order !== section) { sum2 += this.sectionButtons[order].length; continue; } for (const index of this.sectionButtons[section].keys()) { sharedToolbar.setButtonHiddenByIndex(sum2 + index, hidden); } } }, destroy: () => { withSection.setHidden(true); if (this.activeSections.size === 0) { this.destroy(); } }, clearActiveButton: sharedToolbar.clearActiveButton.bind(sharedToolbar), addListener: sharedToolbar.addListener.bind(sharedToolbar), removeListener: sharedToolbar.removeListener.bind(sharedToolbar) }; withSection.setHidden(false); return withSection; } getIndex(section, index) { let sum2 = 0; for (const order of _SharedToolbar2.SECTION_ORDER) { if (order === section) return sum2 + index; sum2 += this.sectionButtons[order].length; } return -1; } getSectionIndex(section, index) { let sum2 = 0; for (const order of _SharedToolbar2.SECTION_ORDER) { if (order === section) { if (index >= sum2 + this.sectionButtons[section].length) return -1; return index - sum2; } sum2 += this.sectionButtons[order].length; } return -1; } }; _SharedToolbar.SECTION_ORDER = ["chartToolbar", "annotations"]; var SharedToolbar = _SharedToolbar; var SharedToolbarModule = { type: "context", contextKey: "sharedToolbar", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new SharedToolbar(ctx) }; var import_ag_charts_community129 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community128 = (init_main4(), __toCommonJS(main_exports)); var { CachedTextMeasurerPool: CachedTextMeasurerPool22, ZIndexMap: ZIndexMap7, LayoutElement: LayoutElement4, Validate: Validate48, BaseProperties: BaseProperties15, OBJECT: OBJECT20, BOOLEAN: BOOLEAN222, STRING: STRING21, COLOR_STRING: COLOR_STRING7, RATIO: RATIO9, valueProperty: valueProperty3, TextUtils: TextUtils3, Group: Group7, Label: Label22, Rect: Rect2, Text: Text2 } = import_ag_charts_community128._ModuleSupport; var chartConfigurations = { ohlc: 2 | 4 | 8 | 16 | 32, candlestick: 2 | 4 | 8 | 16 | 32, "hollow-candlestick": 2 | 4 | 8 | 16 | 32, line: 64 | 32, "step-line": 64 | 32, hlc: 128 | 8 | 16 | 32, "high-low": 512 | 256 | 32 /* Volume */ }; var itemIdMap = { up: "positive", down: "negative" }; var neutralColorMap = { hlc: "altNeutral" }; var StatusBarBackground = class extends BaseProperties15 { constructor() { super(...arguments); this.fill = "black"; this.fillOpacity = 1; } }; __decorateClass2([ Validate48(COLOR_STRING7) ], StatusBarBackground.prototype, "fill", 2); __decorateClass2([ Validate48(RATIO9) ], StatusBarBackground.prototype, "fillOpacity", 2); var StatusBar = class extends import_ag_charts_community128._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = false; this.openKey = void 0; this.highKey = void 0; this.lowKey = void 0; this.closeKey = void 0; this.volumeKey = void 0; this.title = new Label22(); this.positive = new Label22(); this.negative = new Label22(); this.neutral = new Label22(); this.altNeutral = new Label22(); this.background = new StatusBarBackground(); this.layoutStyle = "block"; this.id = "status-bar"; this.data = void 0; this.layer = new Group7({ name: "StatusBar", zIndex: ZIndexMap7.STATUS_BAR }); this.labelGroup = this.layer.appendChild(new import_ag_charts_community128._ModuleSupport.TranslatableGroup()); this.backgroundNode = this.labelGroup.appendChild(new Rect2()); this.labels = [ { label: "O", configuration: 2, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), id: "openValue", key: "openKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "H", configuration: 16, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), id: "highValue", key: "highKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "H", configuration: 256, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), style: "neutral", id: "highValue", key: "highKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "L", configuration: 8, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), id: "lowValue", key: "lowKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "L", configuration: 512, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), style: "neutral", id: "lowValue", key: "lowKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "C", configuration: 4, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), id: "closeValue", key: "closeKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "C", configuration: 128, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), id: "closeValue", key: "closeKey", style: "neutral", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "", configuration: 64, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), style: "neutral", id: "closeValue", key: "closeKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { notation: "compact", minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "Vol", configuration: 32, title: this.labelGroup.appendChild(new Text2()), value: this.labelGroup.appendChild(new Text2()), id: "volumeValue", key: "volumeKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { notation: "compact", minimumFractionDigits: 2, maximumFractionDigits: 2 }) } ]; this.highlightManager = ctx.highlightManager; this.labelGroup.visible = false; this.destroyFns.push( ctx.scene.attachNode(this.layer), ctx.layoutManager.registerElement(LayoutElement4.Overlay, (e) => this.startPerformLayout(e)), ctx.layoutManager.addListener("layout:complete", (e) => this.onLayoutComplete(e)), ctx.highlightManager.addListener("highlight-change", () => this.updateHighlight()) ); } async processData(dataController) { if (!this.enabled || this.data == null) return; const props = []; for (const label of this.labels) { const { id, key } = label; const datumKey = this[key]; if (datumKey == null) { label.domain = void 0; } else { props.push(valueProperty3(datumKey, "number", { id })); } } if (props.length === 0) return; const { processedData, dataModel } = await dataController.request(this.id, this.data, { props }); for (const label of this.labels) { const { id, key } = label; const datumKey = this[key]; if (datumKey != null) { label.domain = dataModel.getDomain(this, id, "value", processedData); } } } startPerformLayout(opts) { this.labelGroup.translationX = 0; this.labelGroup.translationY = 0; if (!this.enabled) return; const { layoutBox } = opts; const innerSpacing = 4; const outerSpacing = 12; const spacingAbove = 0; const spacingBelow = 8; this.labelGroup.translationY = layoutBox.y + spacingAbove; const maxFontSize = Math.max(this.title.fontSize, this.positive.fontSize, this.negative.fontSize); const lineHeight = TextUtils3.getLineHeight(maxFontSize); const labelConfigurations = chartConfigurations[this.getChartType()] ?? 0; let left = 0; let offsetTop; let textVAlign = "alphabetic"; if (this.layoutStyle === "block") { layoutBox.shrink(spacingAbove + lineHeight + spacingBelow, "top"); offsetTop = maxFontSize + (lineHeight - maxFontSize) / 2; } else { const { title } = this.ctx.chartService; textVAlign = "top"; offsetTop = spacingAbove + title.padding; if (title.enabled) { const titleBox = title.node.getBBox(); left = titleBox.x + titleBox.width + outerSpacing; } else { left = title.padding; } } for (const { label, configuration, title, value, domain, formatter } of this.labels) { if (domain == null || (labelConfigurations & configuration) === 0) { title.visible = false; value.visible = false; continue; } const maxValueWidth = Math.max( CachedTextMeasurerPool22.measureText(formatter.format(domain[0]), { font: this.positive.getFont(), textBaseline: textVAlign, textAlign: "left" }).width, CachedTextMeasurerPool22.measureText(formatter.format(domain[1]), { font: this.positive.getFont(), textBaseline: textVAlign, textAlign: "left" }).width, CachedTextMeasurerPool22.measureText(formatter.format(domain[0]), { font: this.negative.getFont(), textBaseline: textVAlign, textAlign: "left" }).width, CachedTextMeasurerPool22.measureText(formatter.format(domain[1]), { font: this.negative.getFont(), textBaseline: textVAlign, textAlign: "left" }).width ); title.visible = true; value.visible = true; const titleMetrics = CachedTextMeasurerPool22.measureText(label, { font: this.title.getFont(), textBaseline: textVAlign, textAlign: "left" }); title.setFont(this.title); title.fill = this.title.color; title.text = label; title.textBaseline = textVAlign; title.y = offsetTop; title.x = left; left += titleMetrics.width + innerSpacing; value.textBaseline = textVAlign; value.y = offsetTop; value.x = left; left += maxValueWidth + outerSpacing; } this.backgroundNode.x = 0; this.backgroundNode.y = 0; this.backgroundNode.width = left - outerSpacing; this.backgroundNode.height = lineHeight + spacingAbove + spacingBelow; this.backgroundNode.fill = this.background.fill; this.backgroundNode.fillOpacity = this.background.fillOpacity; } onLayoutComplete(opts) { this.labelGroup.translationX = opts.series.rect.x; this.updateHighlight(); } updateHighlight() { if (!this.enabled) return; const activeHighlight = this.highlightManager.getActiveHighlight(); const datum = activeHighlight?.datum ?? this.data?.at(-1); if (datum == null) { this.labelGroup.visible = false; return; } this.labelGroup.visible = true; const itemId = activeHighlight?.itemId; let baseStyle = itemId != null ? itemIdMap[itemId] : void 0; if (baseStyle == null && this.openKey != null && this.closeKey != null) { if (datum[this.openKey] < datum[this.closeKey]) { baseStyle = "positive"; } else { baseStyle = "negative"; } } for (const { domain, value, key, formatter, style } of this.labels) { if (domain == null) continue; let labelStyle = style ?? baseStyle ?? "neutral"; if (labelStyle === "neutral") { labelStyle = neutralColorMap[this.getChartType()] ?? labelStyle; } const datumKey = this[key]; const datumValue = datumKey != null ? datum?.[datumKey] : void 0; value.setFont(this[labelStyle]); value.fill = this[labelStyle].color; value.text = typeof datumValue === "number" ? formatter.format(datumValue) : ""; } } getChartType() { let chartType = this.ctx.chartService.publicApi?.getOptions()?.chartType; if (chartType == null || chartConfigurations[chartType] == null) { chartType = "candlestick"; } return chartType; } }; __decorateClass2([ Validate48(BOOLEAN222) ], StatusBar.prototype, "enabled", 2); __decorateClass2([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "openKey", 2); __decorateClass2([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "highKey", 2); __decorateClass2([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "lowKey", 2); __decorateClass2([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "closeKey", 2); __decorateClass2([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "volumeKey", 2); __decorateClass2([ Validate48(OBJECT20) ], StatusBar.prototype, "title", 2); __decorateClass2([ Validate48(OBJECT20) ], StatusBar.prototype, "positive", 2); __decorateClass2([ Validate48(OBJECT20) ], StatusBar.prototype, "negative", 2); __decorateClass2([ Validate48(OBJECT20) ], StatusBar.prototype, "neutral", 2); __decorateClass2([ Validate48(OBJECT20) ], StatusBar.prototype, "altNeutral", 2); __decorateClass2([ Validate48(OBJECT20) ], StatusBar.prototype, "background", 2); __decorateClass2([ Validate48(STRING21) ], StatusBar.prototype, "layoutStyle", 2); var StatusBarModule = { type: "root", identifier: "status-bar", optionsKey: "statusBar", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new StatusBar(ctx), themeTemplate: { statusBar: { enabled: false, layoutStyle: import_ag_charts_community129._ModuleSupport.ThemeSymbols.DEFAULT_CAPTION_LAYOUT_STYLE, title: { color: { $ref: "textColor" }, fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: { $ref: "fontWeight" } }, positive: { color: import_ag_charts_community129._ModuleSupport.ThemeSymbols.PALETTE_UP_STROKE, fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: { $ref: "fontWeight" } }, negative: { color: import_ag_charts_community129._ModuleSupport.ThemeSymbols.PALETTE_DOWN_STROKE, fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: { $ref: "fontWeight" } }, neutral: { color: import_ag_charts_community129._ModuleSupport.ThemeSymbols.PALETTE_NEUTRAL_STROKE, fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: { $ref: "fontWeight" } }, background: { fill: { $ref: "backgroundColor" }, fillOpacity: 0.5 }, altNeutral: { color: "gray" } } } }; var import_ag_charts_community130 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN23, STRING: STRING222, UNION: UNION7, BaseProperties: BaseProperties16, CartesianAxis: CartesianAxis22, ChartUpdateType: ChartUpdateType22, ObserveChanges: ObserveChanges5, TooltipManager: TooltipManager2, Validate: Validate49 } = import_ag_charts_community130._ModuleSupport; var ChartSync = class extends BaseProperties16 { constructor(moduleContext) { super(); this.moduleContext = moduleContext; this.enabled = false; this.axes = "x"; this.nodeInteraction = true; this.zoom = true; } updateSiblings(groupId) { const { syncManager } = this.moduleContext; for (const chart of syncManager.getGroupSiblings(groupId ?? this.groupId)) { this.updateChart(chart); } } updateChart(chart, updateType = ChartUpdateType22.UPDATE_DATA) { chart.ctx.updateService.update(updateType, { skipSync: true }); } enabledZoomSync() { const { syncManager, zoomManager } = this.moduleContext; this.disableZoomSync = zoomManager.addListener("zoom-change", () => { for (const chart of syncManager.getGroupSiblings(this.groupId)) { if (chart.modulesManager.getModule("sync")?.zoom) { chart.ctx.zoomManager.updateZoom("sync", this.mergeZoom(chart)); } } }); } enabledNodeInteractionSync() { const { highlightManager, syncManager } = this.moduleContext; this.disableNodeInteractionSync = highlightManager.addListener("highlight-change", (event) => { for (const chart of syncManager.getGroupSiblings(this.groupId)) { if (!chart.modulesManager.getModule("sync")?.nodeInteraction) continue; if (!event.currentHighlight?.datum) { chart.ctx.highlightManager.updateHighlight(chart.id); chart.ctx.tooltipManager.removeTooltip(chart.id); continue; } for (const axis of chart.axes) { const validDirection = this.axes === "xy" ? "x" : this.axes; if (!CartesianAxis22.is(axis) || axis.direction !== validDirection) continue; const matchingNodes = chart.series.map((series) => { const seriesKeys = series.getKeys(axis.direction); if (axis.keys.length && !axis.keys.some((key) => seriesKeys.includes(key))) return; const { nodeData } = series.contextNodeData; if (!nodeData?.length) return; const valueKey = nodeData[0][`${axis.direction}Key`]; let eventValue = event.currentHighlight.datum[valueKey]; const valueIsDate = isDate2(eventValue); if (valueIsDate) { eventValue = eventValue.getTime(); } const nodeDatum = nodeData.find((datum) => { const nodeValue = datum.datum[valueKey]; return valueIsDate ? nodeValue.getTime() === eventValue : nodeValue === eventValue; }); return nodeDatum ? { series, nodeDatum } : null; }).filter(isDefined2); if (matchingNodes.length < 2 && matchingNodes[0]?.nodeDatum !== chart.ctx.highlightManager.getActiveHighlight()) { const { series, nodeDatum } = matchingNodes[0] ?? {}; chart.ctx.highlightManager.updateHighlight(chart.id, nodeDatum); if (nodeDatum) { const canvasX = nodeDatum.midPoint?.x ?? nodeDatum.point?.x ?? 0; const canvasY = nodeDatum.midPoint?.y ?? nodeDatum.point?.y ?? 0; const tooltipMeta = TooltipManager2.makeTooltipMeta( { type: "pointermove", canvasX, canvasY }, series, nodeDatum ); delete tooltipMeta.lastPointerEvent; chart.ctx.tooltipManager.updateTooltip( chart.id, tooltipMeta, series.getTooltipContent(nodeDatum) ); } else { chart.ctx.tooltipManager.removeTooltip(chart.id); } this.updateChart(chart, ChartUpdateType22.SERIES_UPDATE); } } } }); } getSyncedDomain(axis) { if (!CartesianAxis22.is(axis) || this.axes !== "xy" && this.axes !== axis.direction) { return; } const { syncManager } = this.moduleContext; const syncGroup = syncManager.getGroup(this.groupId); const [{ axes: syncAxes }] = syncGroup; const { direction, min, max, nice, reverse } = axis; for (const mainAxis of syncAxes) { if (direction !== mainAxis.direction) continue; if (nice !== mainAxis.nice || reverse !== mainAxis.reverse || min !== mainAxis.min && (isFiniteNumber2(min) || isFiniteNumber2(mainAxis.min)) || max !== mainAxis.max && (isFiniteNumber2(max) || isFiniteNumber2(mainAxis.max))) { logger_exports2.warnOnce( "To allow synchronization, ensure that all charts have matching min, max, nice, and reverse properties on the synchronized axes." ); this.enabled = false; return; } } return unique2( syncGroup.flatMap((c) => c.series).filter((series) => { if (series.visible) { const seriesKeys = series.getKeys(axis.direction); return axis.keys.length ? axis.keys.some((key) => seriesKeys.includes(key)) : true; } }).flatMap((series) => series.getDomain(axis.direction)) ); } mergeZoom(chart) { const { zoomManager } = this.moduleContext; if (this.axes === "xy") { return zoomManager.getZoom(); } const combinedZoom = chart.ctx.zoomManager.getZoom() ?? {}; combinedZoom[this.axes] = zoomManager.getZoom()?.[this.axes]; return combinedZoom; } onEnabledChange() { const { syncManager } = this.moduleContext; if (this.enabled) { syncManager.subscribe(this.groupId); } else { syncManager.unsubscribe(this.groupId); } this.updateSiblings(); this.onNodeInteractionChange(); this.onZoomChange(); } onGroupIdChange(newValue, oldValue) { if (!this.enabled || newValue === oldValue) return; const { syncManager } = this.moduleContext; syncManager.unsubscribe(oldValue); syncManager.subscribe(newValue); this.updateSiblings(oldValue); this.updateSiblings(newValue); } onAxesChange() { if (!this.enabled) return; const { syncManager } = this.moduleContext; this.updateChart(syncManager.getChart()); } onNodeInteractionChange() { if (this.enabled && this.nodeInteraction) { this.enabledNodeInteractionSync(); } else { this.disableNodeInteractionSync?.(); } } onZoomChange() { if (this.enabled && this.zoom) { this.enabledZoomSync(); } else { this.disableZoomSync?.(); } } destroy() { const { syncManager } = this.moduleContext; syncManager.unsubscribe(this.groupId); this.updateSiblings(); this.disableZoomSync?.(); } }; ChartSync.className = "Sync"; __decorateClass2([ Validate49(BOOLEAN23), ObserveChanges5((target) => target.onEnabledChange()) ], ChartSync.prototype, "enabled", 2); __decorateClass2([ Validate49(STRING222, { optional: true }), ObserveChanges5((target, newValue, oldValue) => target.onGroupIdChange(newValue, oldValue)) ], ChartSync.prototype, "groupId", 2); __decorateClass2([ Validate49(UNION7(["x", "y", "xy"], "an axis")), ObserveChanges5((target) => target.onAxesChange()) ], ChartSync.prototype, "axes", 2); __decorateClass2([ Validate49(BOOLEAN23), ObserveChanges5((target) => target.onNodeInteractionChange()) ], ChartSync.prototype, "nodeInteraction", 2); __decorateClass2([ Validate49(BOOLEAN23), ObserveChanges5((target) => target.onZoomChange()) ], ChartSync.prototype, "zoom", 2); var SyncModule = { type: "root", optionsKey: "sync", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new ChartSync(ctx), themeTemplate: { sync: { enabled: false } } }; var import_ag_charts_community140 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community131 = (init_main4(), __toCommonJS(main_exports)); var { COLOR_STRING: COLOR_STRING8, RATIO: RATIO10, Validate: Validate50 } = import_ag_charts_community131._ModuleSupport; var VALID_COLOR = "#2196f3"; var INVALID_COLOR = "#8a8a8a"; var ZoomRect = class extends import_ag_charts_community131._ModuleSupport.Rect { constructor() { super(...arguments); this.fill = VALID_COLOR; this.fillOpacity = 0.2; this.zIndex = import_ag_charts_community131._ModuleSupport.ZIndexMap.ZOOM_SELECTION; } updateValid() { this.fill = VALID_COLOR; } updateInvalid() { this.fill = INVALID_COLOR; } }; ZoomRect.className = "ZoomRect"; __decorateClass2([ Validate50(COLOR_STRING8) ], ZoomRect.prototype, "fill", 2); __decorateClass2([ Validate50(RATIO10) ], ZoomRect.prototype, "fillOpacity", 2); var import_ag_charts_community133 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community132 = (init_main4(), __toCommonJS(main_exports)); var { UNION: UNION8, clamp: clamp7, isNumberEqual: isNumberEqual8, round: round5 } = import_ag_charts_community132._ModuleSupport; var UNIT = { min: 0, max: 1 }; var DEFAULT_ANCHOR_POINT_X = "end"; var DEFAULT_ANCHOR_POINT_Y = "middle"; var ANCHOR_POINT = UNION8(["pointer", "start", "middle", "end"], "an anchor point"); var constrain = (value, min = UNIT.min, max = UNIT.max) => clamp7(min, value, max); function unitZoomState() { return { x: { ...UNIT }, y: { ...UNIT } }; } function dx(zoom) { return zoom.x.max - zoom.x.min; } function dy(zoom) { return zoom.y.max - zoom.y.min; } function isZoomRangeEqual(left, right, epsilon2 = 1e-10) { return isNumberEqual8(left.min, right.min, epsilon2) && isNumberEqual8(left.max, right.max, epsilon2); } function isZoomEqual(left, right, epsilon2) { return isZoomRangeEqual(left.x, right.x, epsilon2) && isZoomRangeEqual(left.y, right.y, epsilon2); } function definedZoomState(zoom) { return { x: { min: zoom?.x?.min ?? UNIT.min, max: zoom?.x?.max ?? UNIT.max }, y: { min: zoom?.y?.min ?? UNIT.min, max: zoom?.y?.max ?? UNIT.max } }; } function pointToRatio(bbox, x, y) { if (!bbox) return { x: 0, y: 0 }; const constrainedX = constrain(x - bbox.x, 0, bbox.x + bbox.width); const constrainedY = constrain(y - bbox.y, 0, bbox.y + bbox.height); const rx = 1 / bbox.width * constrainedX; const ry = 1 - 1 / bbox.height * constrainedY; return { x: constrain(rx), y: constrain(ry) }; } function translateZoom(zoom, x, y) { return { x: { min: zoom.x.min + x, max: zoom.x.max + x }, y: { min: zoom.y.min + y, max: zoom.y.max + y } }; } function scaleZoom(zoom, sx, sy) { return { x: { min: zoom.x.min, max: zoom.x.min + dx(zoom) * sx }, y: { min: zoom.y.min, max: zoom.y.min + dy(zoom) * sy } }; } function scaleZoomCenter(zoom, sx, sy) { const dx_ = dx(zoom); const dy_ = dy(zoom); const cx = zoom.x.min + dx_ / 2; const cy = zoom.y.min + dy_ / 2; return { x: { min: cx - dx_ * sx / 2, max: cx + dx_ * sx / 2 }, y: { min: cy - dy_ * sy / 2, max: cy + dy_ * sy / 2 } }; } function scaleZoomAxisWithAnchor(newState, oldState, anchor, origin3) { const { min, max } = oldState; const center2 = min + (max - min) / 2; const diff8 = newState.max - newState.min; switch (anchor) { case "start": return { min, max: oldState.min + diff8 }; case "end": return { min: oldState.max - diff8, max }; case "middle": return { min: center2 - diff8 / 2, max: center2 + diff8 / 2 }; case "pointer": return scaleZoomAxisWithPoint(newState, oldState, origin3 ?? center2); default: return { min, max }; } } function scaleZoomAxisWithPoint(newState, oldState, origin3) { const newDelta = newState.max - newState.min; const oldDelta = oldState.max - oldState.min; const scaledOrigin = origin3 * (1 - (oldDelta - newDelta)); const translation = origin3 - scaledOrigin; const min = newState.min + translation; const max = newState.max + translation; return { min, max }; } function multiplyZoom(zoom, nx, ny) { return { x: { min: zoom.x.min * nx, max: zoom.x.max * nx }, y: { min: zoom.y.min * ny, max: zoom.y.max * ny } }; } function constrainZoom(zoom) { return { x: constrainAxis(zoom.x), y: constrainAxis(zoom.y) }; } function constrainAxis(axis) { const size = axis.max - axis.min; let min = axis.max > UNIT.max ? UNIT.max - size : axis.min; let max = axis.min < UNIT.min ? size : axis.max; min = Math.max(UNIT.min, min); max = Math.min(UNIT.max, max); return { min, max }; } var ZoomAxisDragger = class { update(event, direction, anchor, bbox, zoom, axisZoom) { this.oldZoom ?? (this.oldZoom = definedZoomState( direction === import_ag_charts_community133._ModuleSupport.ChartAxisDirection.X ? { ...zoom, x: axisZoom } : { ...zoom, y: axisZoom } )); this.updateCoords(event.currentX, event.currentY); return this.updateZoom(direction, anchor, bbox); } stop() { this.coords = void 0; this.oldZoom = void 0; } updateCoords(x, y) { if (this.coords) { this.coords.x2 = x; this.coords.y2 = y; } else { this.coords = { x1: x, y1: y, x2: x, y2: y }; } } updateZoom(direction, anchor, bbox) { const { coords, oldZoom } = this; let newZoom = definedZoomState(oldZoom); if (!coords || !oldZoom) { if (direction === import_ag_charts_community133._ModuleSupport.ChartAxisDirection.X) return newZoom.x; return newZoom.y; } const origin3 = pointToRatio(bbox, coords.x1, coords.y1); const target = pointToRatio(bbox, coords.x2, coords.y2); if (direction === import_ag_charts_community133._ModuleSupport.ChartAxisDirection.X) { const scaleX = (target.x - origin3.x) * dx(oldZoom); newZoom.x.max += scaleX; newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchor, origin3.x); newZoom = constrainZoom(newZoom); return newZoom.x; } const scaleY = (target.y - origin3.y) * dy(oldZoom); newZoom.y.max -= scaleY; newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchor, origin3.y); newZoom = constrainZoom(newZoom); return newZoom.y; } }; var CONTEXT_ZOOM_ACTION_ID = "zoom-action"; var CONTEXT_PAN_ACTION_ID = "pan-action"; var ZoomContextMenu = class { constructor(contextMenuRegistry, zoomManager, getModuleProperties, getRect, updateZoom, isZoomValid) { this.contextMenuRegistry = contextMenuRegistry; this.zoomManager = zoomManager; this.getModuleProperties = getModuleProperties; this.getRect = getRect; this.updateZoom = updateZoom; this.isZoomValid = isZoomValid; } registerActions(enabled) { if (!enabled) return; const { contextMenuRegistry } = this; const destroyZoomToCursor = contextMenuRegistry.registerDefaultAction({ id: CONTEXT_ZOOM_ACTION_ID, type: "series-area", label: "contextMenuZoomToCursor", action: this.onZoomToHere.bind(this), toggleEnabledOnShow: (event) => { const rect = this.getRect(); if (!rect) return true; const origin3 = pointToRatio(rect, event.x, event.y); return this.iterateFindNextZoomAtPoint(origin3) != null; } }); const destroyPanToCursor = contextMenuRegistry.registerDefaultAction({ id: CONTEXT_PAN_ACTION_ID, type: "series-area", label: "contextMenuPanToCursor", action: this.onPanToHere.bind(this), toggleEnabledOnShow: () => !isZoomEqual(definedZoomState(this.zoomManager.getZoom()), unitZoomState()) }); return () => { destroyZoomToCursor(); destroyPanToCursor(); }; } computeOrigin(event) { const rect = this.getRect(); const { enabled } = this.getModuleProperties(); if (!enabled || !rect || !event?.target || !(event instanceof MouseEvent)) return; const relativeRect = { x: 0, y: 0, width: rect.width, height: rect.height }; return pointToRatio(relativeRect, event.offsetX, event.offsetY); } onZoomToHere({ event }) { const origin3 = this.computeOrigin(event); if (!origin3) return; const zoom = this.iterateFindNextZoomAtPoint(origin3); if (zoom == null) return; this.updateZoom(zoom); } onPanToHere({ event }) { const origin3 = this.computeOrigin(event); if (!origin3) return; const zoom = definedZoomState(this.zoomManager.getZoom()); const scaleX = dx(zoom); const scaleY = dy(zoom); const scaledOriginX = origin3.x * scaleX; const scaledOriginY = origin3.y * scaleY; const halfSize = (UNIT.max - UNIT.min) / 2; let newZoom = { x: { min: origin3.x - halfSize, max: origin3.x + halfSize }, y: { min: origin3.y - halfSize, max: origin3.y + halfSize } }; newZoom = scaleZoomCenter(newZoom, scaleX, scaleY); newZoom = translateZoom(newZoom, zoom.x.min - origin3.x + scaledOriginX, zoom.y.min - origin3.y + scaledOriginY); this.updateZoom(constrainZoom(newZoom)); } iterateFindNextZoomAtPoint(origin3) { const { scrollingStep } = this.getModuleProperties(); for (let i = scrollingStep; i <= 1 - scrollingStep; i += scrollingStep) { const zoom = this.getNextZoomAtPoint(origin3, i); if (this.isZoomValid(zoom)) { return zoom; } } } getNextZoomAtPoint(origin3, step) { const { isScalingX, isScalingY } = this.getModuleProperties(); const zoom = definedZoomState(this.zoomManager.getZoom()); const scaledOriginX = origin3.x * dx(zoom); const scaledOriginY = origin3.y * dy(zoom); const size = UNIT.max - UNIT.min; const halfSize = size / 2; let newZoom = { x: { min: origin3.x - halfSize, max: origin3.x + halfSize }, y: { min: origin3.y - halfSize, max: origin3.y + halfSize } }; newZoom = scaleZoomCenter(newZoom, isScalingX ? dx(zoom) * step : size, isScalingY ? dy(zoom) * step : size); newZoom = translateZoom(newZoom, zoom.x.min - origin3.x + scaledOriginX, zoom.y.min - origin3.y + scaledOriginY); return constrainZoom(newZoom); } }; var import_ag_charts_community134 = (init_main4(), __toCommonJS(main_exports)); var { BBoxValues: BBoxValues2 } = import_ag_charts_community134._ModuleSupport; var ZoomDOMProxy = class { constructor(axesHandlers) { this.axesHandlers = axesHandlers; this.axes = []; } initAxis(ctx, axisId, handlers, direction) { const { X, Y } = import_ag_charts_community134._ModuleSupport.ChartAxisDirection; const cursor = { [X]: "ew-resize", [Y]: "ns-resize" }[direction]; const where = "afterend"; const div = ctx.proxyInteractionService.createProxyElement({ type: "region", domManagerId: axisId, where }); div.setCursor(cursor); div.addListener("drag-start", (e) => { if (e.device === "touch") { e.sourceEvent.preventDefault(); } handlers.onDragStart(axisId, direction); }); div.addListener("drag-move", (ev) => handlers.onDrag(ev)); div.addListener("drag-end", handlers.onDragEnd); div.addListener("dblclick", () => handlers.onDoubleClick(axisId, direction)); return { axisId, div }; } destroy() { this.axes.forEach((a) => a.div.destroy()); } update(enableAxisDragging, ctx) { this.axes.forEach((ax) => ax.div.setHidden(!enableAxisDragging)); if (!enableAxisDragging) return; const { X, Y } = import_ag_charts_community134._ModuleSupport.ChartAxisDirection; const axesCtx = [...ctx.axisManager.getAxisContext(X), ...ctx.axisManager.getAxisContext(Y)]; const { removed, added } = this.diffAxisIds(axesCtx); if (removed.length > 0) { this.axes = this.axes.filter((entry) => { if (removed.includes(entry.axisId)) { entry.div.destroy(); return false; } return true; }); } for (const newAxisCtx of added) { const { axisId, direction } = newAxisCtx; this.axes.push(this.initAxis(ctx, axisId, this.axesHandlers, direction)); } for (const axis of this.axes) { const axisCtx = axesCtx.filter((ac) => ac.axisId === axis.axisId)[0]; const bbox = axisCtx.getCanvasBounds(); axis.div.setHidden(BBoxValues2.isEmpty(bbox)); if (bbox !== void 0) { axis.div.setBounds(bbox); } } } diffAxisIds(axesCtx) { const myIds = this.axes.map((entry) => entry.axisId); const ctxIds = axesCtx.map((ctx) => ctx.axisId); const removed = myIds.filter((id) => !ctxIds.includes(id)); const added = axesCtx.filter((ac) => !myIds.includes(ac.axisId)); return { removed, added }; } }; var import_ag_charts_community135 = (init_main4(), __toCommonJS(main_exports)); var maxZoomCoords = 16; var decelerationValues = { off: 1, short: 0.01, long: 2e-3 }; var ZoomPanner = class { constructor() { this.deceleration = 1; this.zoomCoordsHistoryIndex = 0; this.coordsHistory = []; } get decelerationValue() { const { deceleration } = this; return Math.max( typeof deceleration === "number" ? deceleration : decelerationValues[deceleration] ?? 1, 1e-4 ); } addListener(_type, fn) { this.onUpdate = fn; return () => { this.onUpdate = void 0; }; } stopInteractions() { if (this.inertiaHandle != null) { cancelAnimationFrame(this.inertiaHandle); this.inertiaHandle = void 0; } } update(event) { this.updateCoords(event.currentX, event.currentY); const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = this.coords ?? {}; this.onUpdate?.({ type: "update", deltaX: x1 - x2, deltaY: y1 - y2 }); } start() { this.coordsMonitorTimeout = setInterval(this.recordCurrentZoomCoords.bind(this), 16); } stop() { const { coordsHistory } = this; let deltaX = 0; let deltaY = 0; let deltaT = 0; if (coordsHistory.length > 0) { const arrayIndex = this.zoomCoordsHistoryIndex % maxZoomCoords; let index1 = arrayIndex - 1; if (index1 < 0) index1 = coordsHistory.length - 1; let index0 = arrayIndex; if (index0 >= coordsHistory.length) index0 = 0; const coords1 = coordsHistory[index1]; const coords0 = coordsHistory[index0]; deltaX = coords1.x - coords0.x; deltaY = coords1.y - coords0.y; deltaT = coords1.t - coords0.t; } this.coords = void 0; clearInterval(this.coordsMonitorTimeout); this.coordsMonitorTimeout = void 0; this.zoomCoordsHistoryIndex = 0; this.coordsHistory.length = 0; if (deltaT > 0 && this.decelerationValue < 1) { const xVelocity = deltaX / deltaT; const yVelocity = deltaY / deltaT; const velocity = Math.hypot(xVelocity, yVelocity); const angle2 = Math.atan2(yVelocity, xVelocity); const t0 = performance.now(); this.inertiaHandle = import_ag_charts_community135._ModuleSupport.getWindow().requestAnimationFrame((t) => { this.animateInertia(t, t, t0, velocity, angle2); }); } } recordCurrentZoomCoords() { const { coords, coordsHistory, zoomCoordsHistoryIndex } = this; if (!coords) return; const { x2: x, y2: y } = coords; const t = Date.now(); coordsHistory[zoomCoordsHistoryIndex % maxZoomCoords] = { x, y, t }; this.zoomCoordsHistoryIndex += 1; } animateInertia(t, prevT, t0, velocity, angle2) { const friction = 1 - this.decelerationValue; const maxS = -velocity / Math.log(friction); const s0 = velocity * (friction ** (prevT - t0) - 1) / Math.log(friction); const s1 = velocity * (friction ** (t - t0) - 1) / Math.log(friction); this.onUpdate?.({ type: "update", deltaX: -Math.cos(angle2) * (s1 - s0), deltaY: -Math.sin(angle2) * (s1 - s0) }); if (s1 >= maxS - 1) return; this.inertiaHandle = requestAnimationFrame((nextT) => { this.animateInertia(nextT, t, t0, velocity, angle2); }); } updateCoords(x, y) { if (this.coords) { this.coords = { x1: this.coords.x2, y1: this.coords.y2, x2: x, y2: y }; } else { this.coords = { x1: x, y1: y, x2: x, y2: y }; } } translateZooms(bbox, currentZooms, deltaX, deltaY) { const offset4 = pointToRatio(bbox, bbox.x + Math.abs(deltaX), bbox.y + bbox.height - Math.abs(deltaY)); const offsetX = Math.sign(deltaX) * offset4.x; const offsetY = -Math.sign(deltaY) * offset4.y; const newZooms = {}; for (const [axisId, { direction, zoom: currentZoom }] of Object.entries(currentZooms)) { if (currentZoom && currentZoom.min === UNIT.min && currentZoom.max === UNIT.max) { continue; } let zoom = definedZoomState({ [direction]: currentZoom }); zoom = constrainZoom(translateZoom(zoom, offsetX * dx(zoom), offsetY * dy(zoom))); newZooms[axisId] = { direction, zoom: zoom[direction] }; } return newZooms; } }; var import_ag_charts_community136 = (init_main4(), __toCommonJS(main_exports)); var DELTA_SCALE = 200; var ZoomScrollPanner = class { update(event, step, bbox, zooms) { const deltaX = event.deltaX * step * DELTA_SCALE; return this.translateZooms(bbox, zooms, deltaX); } translateZooms(bbox, currentZooms, deltaX) { const newZooms = {}; const offset4 = pointToRatio(bbox, bbox.x + Math.abs(deltaX), 0); const offsetX = deltaX < 0 ? -offset4.x : offset4.x; for (const [axisId, { direction, zoom: currentZoom }] of Object.entries(currentZooms)) { if (direction !== import_ag_charts_community136._ModuleSupport.ChartAxisDirection.X) continue; let zoom = definedZoomState({ x: currentZoom }); zoom = constrainZoom(translateZoom(zoom, offsetX * dx(zoom), 0)); newZooms[axisId] = { direction, zoom: zoom.x }; } return newZooms; } }; var import_ag_charts_community137 = (init_main4(), __toCommonJS(main_exports)); var ZoomScroller = class { updateAxes(event, props, bbox, zooms) { const sourceEvent = event.sourceEvent; const newZooms = {}; const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props; const origin3 = pointToRatio( bbox, sourceEvent.offsetX ?? sourceEvent.clientX, sourceEvent.offsetY ?? sourceEvent.clientY ); for (const [axisId, { direction, zoom }] of Object.entries(zooms)) { if (zoom == null) continue; let newZoom = { ...zoom }; const delta4 = scrollingStep * event.deltaY * (zoom.max - zoom.min); if (direction === import_ag_charts_community137._ModuleSupport.ChartAxisDirection.X && isScalingX) { newZoom.max += delta4; newZoom = scaleZoomAxisWithAnchor(newZoom, zoom, anchorPointX, origin3.x); } else if (direction === import_ag_charts_community137._ModuleSupport.ChartAxisDirection.Y && isScalingY) { newZoom.max += delta4; newZoom = scaleZoomAxisWithAnchor(newZoom, zoom, anchorPointY, origin3.y); } else { continue; } newZooms[axisId] = { direction, zoom: constrainAxis(newZoom) }; } return newZooms; } update(event, props, bbox, oldZoom) { const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props; const canvasX = event.offsetX + bbox.x; const canvasY = event.offsetY + bbox.y; const origin3 = pointToRatio(bbox, canvasX, canvasY); const dir = event.deltaY; let newZoom = definedZoomState(oldZoom); newZoom.x.max += isScalingX ? scrollingStep * dir * dx(oldZoom) : 0; newZoom.y.max += isScalingY ? scrollingStep * dir * dy(oldZoom) : 0; if (isScalingX) { newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchorPointX, origin3.x); } if (isScalingY) { newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchorPointY, origin3.y); } newZoom = constrainZoom(newZoom); return newZoom; } updateDelta(delta4, props, oldZoom) { const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props; let newZoom = definedZoomState(oldZoom); newZoom.x.max += isScalingX ? scrollingStep * -delta4 * dx(oldZoom) : 0; newZoom.y.max += isScalingY ? scrollingStep * -delta4 * dy(oldZoom) : 0; if (isScalingX) { newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchorPointX); } if (isScalingY) { newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchorPointY); } newZoom = constrainZoom(newZoom); return newZoom; } }; var ZoomSelector = class { constructor(rect, getZoom, isZoomValid) { this.rect = rect; this.getZoom = getZoom; this.isZoomValid = isZoomValid; this.rect.visible = false; } update(event, props, bbox) { const canvasX = event.currentX + (bbox?.x ?? 0); const canvasY = event.currentY + (bbox?.y ?? 0); this.rect.visible = true; this.updateCoords(canvasX, canvasY, props, bbox); this.updateRect(bbox); } stop(innerBBox, bbox, currentZoom) { let zoom = definedZoomState(); if (!innerBBox || !bbox) return zoom; if (this.coords) { zoom = this.createZoomFromCoords(bbox, currentZoom); } const multiplyX = bbox.width / innerBBox.width; const multiplyY = bbox.height / innerBBox.height; zoom = constrainZoom(multiplyZoom(zoom, multiplyX, multiplyY)); this.reset(); return zoom; } reset() { this.coords = void 0; this.rect.visible = false; } didUpdate() { return this.rect.visible && this.rect.width > 0 && this.rect.height > 0; } updateCoords(x, y, props, bbox) { if (!this.coords) { this.coords = { x1: x, y1: y, x2: x, y2: y }; return; } const { coords } = this; coords.x2 = x; coords.y2 = y; if (!bbox) return; const { isScalingX, isScalingY, keepAspectRatio } = props; const normal = this.getNormalisedDimensions(); if (keepAspectRatio && isScalingX && isScalingY) { const aspectRatio = bbox.width / bbox.height; if (coords.y2 < coords.y1) { coords.y2 = Math.min(coords.y1 - normal.width / aspectRatio, coords.y1); } else { coords.y2 = Math.max(coords.y1 + normal.width / aspectRatio, coords.y1); } } if (!isScalingX) { coords.x1 = bbox.x; coords.x2 = bbox.x + bbox.width; } if (!isScalingY) { coords.y1 = bbox.y; coords.y2 = bbox.y + bbox.height; } } updateRect(bbox) { if (!bbox) return; const { rect } = this; const normal = this.getNormalisedDimensions(); const { width: width2, height: height2 } = normal; let { x, y } = normal; x = Math.max(x, bbox.x); x -= Math.max(0, x + width2 - (bbox.x + bbox.width)); y = Math.max(y, bbox.y); y -= Math.max(0, y + height2 - (bbox.y + bbox.height)); rect.x = x; rect.y = y; rect.width = width2; rect.height = height2; const zoom = this.createZoomFromCoords(bbox, this.getZoom()); if (this.isZoomValid(zoom)) { rect.updateValid(); } else { rect.updateInvalid(); } } createZoomFromCoords(bbox, currentZoom) { const oldZoom = definedZoomState(currentZoom); const normal = this.getNormalisedDimensions(); const origin3 = pointToRatio(bbox, normal.x, normal.y + normal.height); const xFactor = normal.width / bbox.width; const yFactor = normal.height / bbox.height; let newZoom = scaleZoom(oldZoom, xFactor, yFactor); const translateX = origin3.x * dx(oldZoom); const translateY = origin3.y * dy(oldZoom); newZoom = translateZoom(newZoom, translateX, translateY); newZoom = constrainZoom(newZoom); return newZoom; } getNormalisedDimensions() { const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = this.coords ?? {}; const x = x1 <= x2 ? x1 : x2; const y = y1 <= y2 ? y1 : y2; const width2 = x1 <= x2 ? x2 - x1 : x1 - x2; const height2 = y1 <= y2 ? y2 - y1 : y1 - y2; return { x, y, width: width2, height: height2 }; } }; var import_ag_charts_community138 = (init_main4(), __toCommonJS(main_exports)); var { ARRAY: ARRAY5, BOOLEAN: BOOLEAN24, STRING: STRING23, UNION: UNION9, ActionOnSet: ActionOnSet8, BaseProperties: BaseProperties17, ChartAxisDirection: ChartAxisDirection15, NativeWidget: NativeWidget22, PropertiesArray: PropertiesArray5, Toolbar: Toolbar22, ToolbarButtonProperties: ToolbarButtonProperties4, Validate: Validate51, createElement: createElement5 } = import_ag_charts_community138._ModuleSupport; var ZoomButtonProperties = class extends ToolbarButtonProperties4 { }; __decorateClass2([ Validate51(UNION9(["reset", "zoom-in", "zoom-out", "pan-left", "pan-right", "pan-start", "pan-end"])) ], ZoomButtonProperties.prototype, "value", 2); __decorateClass2([ Validate51(STRING23) ], ZoomButtonProperties.prototype, "section", 2); var ZoomToolbar = class extends BaseProperties17 { constructor(ctx, getModuleProperties, getResetZoom, updateZoom, updateAxisZoom, resetZoom, isZoomValid) { super(); this.ctx = ctx; this.getModuleProperties = getModuleProperties; this.getResetZoom = getResetZoom; this.updateZoom = updateZoom; this.updateAxisZoom = updateAxisZoom; this.resetZoom = resetZoom; this.isZoomValid = isZoomValid; this.enabled = false; this.buttons = new PropertiesArray5(ZoomButtonProperties); this.visible = "hover"; this.verticalSpacing = 10; this.detectionRange = 38; this.destroyFns = []; this.container = new NativeWidget22(createElement5("div")); this.container.addClass("ag-charts-zoom-buttons"); ctx.domManager.addChild("canvas-overlay", "zoom-buttons", this.container.getElement()); this.toolbar = new Toolbar22(ctx.localeManager); this.container.addChild(this.toolbar); this.toggleVisibility(this.visible === "always"); this.destroyFns.push( this.toolbar.addToolbarListener("button-pressed", this.onButtonPress.bind(this)), this.toolbar.addToolbarListener("button-focused", this.onButtonFocus.bind(this)), ctx.widgets.containerWidget.addListener("mousemove", this.onHover.bind(this)), ctx.widgets.containerWidget.addListener("mouseleave", this.onLeave.bind(this)), ctx.layoutManager.addListener("layout:complete", this.onLayoutComplete.bind(this)), this.teardown.bind(this) ); } destroy() { for (const fn of this.destroyFns) { fn(); } } toggleVisibleZoomed(isMaxZoom) { if (this.visible !== "zoomed") return; this.toggleVisibility(!isMaxZoom); } teardown() { this.ctx.domManager.removeChild("canvas-overlay", "zoom-buttons"); this.container.destroy(); } onLayoutComplete(event) { const { buttons: buttons2, container } = this; const { rect } = event.series; this.toolbar.updateButtons(buttons2); this.toggleButtons(); const height2 = container.getBounds().height; container.setBounds({ y: rect.y + rect.height - height2 }); } onHover(event) { if (!this.enabled || this.visible !== "hover" || this.toolbar.isHidden()) return; const { container, detectionRange, ctx: { scene } } = this; const { currentY, sourceEvent: { target } } = event; const element2 = container.getElement(); const detectionY = element2.offsetTop - detectionRange; const visible = currentY > detectionY && currentY < scene.canvas.element.offsetHeight || target === element2; this.toggleVisibility(visible); } onLeave() { if (this.visible !== "hover") return; this.toggleVisibility(false); } toggleVisibility(visible, immediate = false) { const { container, toolbar: toolbar2, verticalSpacing } = this; toolbar2.toggleClass("ag-charts-zoom-buttons__toolbar--hidden", !visible); const element2 = toolbar2.getElement(); element2.style.transitionDuration = immediate ? "0s" : ""; element2.style.transform = visible ? "translateY(0)" : `translateY(${container.getBounds().height + verticalSpacing}px)`; } toggleButtons() { const zoom = definedZoomState(this.ctx.zoomManager.getZoom()); if (this.previousZoom && isZoomEqual(this.previousZoom, zoom)) return; this.previousZoom = zoom; for (const [index, button] of this.buttons.entries()) { let enabled = true; switch (button?.value) { case "pan-start": enabled = zoom.x.min > UNIT.min; break; case "pan-end": enabled = zoom.x.max < UNIT.max; break; case "pan-left": enabled = zoom.x.min > UNIT.min; break; case "pan-right": enabled = zoom.x.max < UNIT.max; break; case "zoom-out": enabled = !isZoomEqual(zoom, unitZoomState()); break; case "zoom-in": enabled = this.isZoomValid( this.getNextZoomStateUnified("zoom-in", zoom, this.getModuleProperties()) ); break; case "reset": enabled = !isZoomEqual(zoom, this.getResetZoom()); break; } this.toolbar.toggleButtonEnabledByIndex(index, enabled); } } onButtonPress({ button }) { if (!this.enabled || this.toolbar.isHidden()) return; const props = this.getModuleProperties(); if (props.independentAxes && button.value !== "reset") { const axisZooms = this.ctx.zoomManager.getAxisZooms(); for (const [axisId, { direction, zoom }] of Object.entries(axisZooms)) { if (zoom == null) continue; this.onButtonPressAxis(button, props, axisId, direction, zoom); } } else { this.onButtonPressUnified(button, props); } } onButtonFocus(_event) { this.toggleVisibility(true, true); } onButtonPressAxis(event, props, axisId, direction, zoom) { const { isScalingX, isScalingY, scrollingStep } = props; let newZoom = { ...zoom }; const delta4 = zoom.max - zoom.min; switch (event.value) { case "pan-start": newZoom.max = delta4; newZoom.min = 0; break; case "pan-end": newZoom.min = newZoom.max - delta4; newZoom.max = UNIT.max; break; case "pan-left": newZoom.min -= delta4 * scrollingStep; newZoom.max -= delta4 * scrollingStep; break; case "pan-right": newZoom.min += delta4 * scrollingStep; newZoom.max += delta4 * scrollingStep; break; case "zoom-in": case "zoom-out": { const isDirectionX = direction === ChartAxisDirection15.X; const isScalingDirection = isDirectionX && isScalingX || !isDirectionX && isScalingY; let scale2 = event.value === "zoom-in" ? 1 - scrollingStep : 1 + scrollingStep; if (!isScalingDirection) scale2 = 1; const anchorPoint = isDirectionX ? this.getAnchorPointX(props) : this.getAnchorPointY(props); newZoom.max = newZoom.min + (newZoom.max - newZoom.min) * scale2; newZoom = scaleZoomAxisWithAnchor(newZoom, zoom, anchorPoint); break; } } this.updateAxisZoom(axisId, direction, constrainAxis(newZoom)); } onButtonPressUnified(event, props) { const { scrollingStep } = props; const oldZoom = definedZoomState(this.ctx.zoomManager.getZoom()); let zoom = definedZoomState(oldZoom); switch (event.value) { case "reset": this.resetZoom(); return; case "pan-start": zoom.x.max = dx(zoom); zoom.x.min = 0; break; case "pan-end": zoom.x.min = UNIT.max - dx(zoom); zoom.x.max = UNIT.max; break; case "pan-left": zoom = translateZoom(zoom, -dx(zoom) * scrollingStep, 0); break; case "pan-right": zoom = translateZoom(zoom, dx(zoom) * scrollingStep, 0); break; case "zoom-in": case "zoom-out": { zoom = this.getNextZoomStateUnified(event.value, oldZoom, props); break; } } this.updateZoom(constrainZoom(zoom)); } getNextZoomStateUnified(button, oldZoom, props) { const { isScalingX, isScalingY, scrollingStep } = props; const scale2 = button === "zoom-in" ? 1 - scrollingStep : 1 + scrollingStep; const zoom = scaleZoom(oldZoom, isScalingX ? scale2 : 1, isScalingY ? scale2 : 1); zoom.x = scaleZoomAxisWithAnchor(zoom.x, oldZoom.x, this.getAnchorPointX(props)); zoom.y = scaleZoomAxisWithAnchor(zoom.y, oldZoom.y, this.getAnchorPointY(props)); return zoom; } getAnchorPointX(props) { const anchorPointX = this.anchorPointX ?? props.anchorPointX; return anchorPointX === "pointer" ? DEFAULT_ANCHOR_POINT_X : anchorPointX; } getAnchorPointY(props) { const anchorPointY = this.anchorPointY ?? props.anchorPointY; return anchorPointY === "pointer" ? DEFAULT_ANCHOR_POINT_Y : anchorPointY; } }; __decorateClass2([ Validate51(BOOLEAN24), ActionOnSet8({ changeValue(enabled) { this.toolbar?.setHidden(!enabled); } }) ], ZoomToolbar.prototype, "enabled", 2); __decorateClass2([ Validate51(ARRAY5) ], ZoomToolbar.prototype, "buttons", 2); __decorateClass2([ Validate51(UNION9(["always", "zoomed", "hover"])), ActionOnSet8({ changeValue(visible, oldValue) { if (oldValue == null) return; this.toggleVisibility(visible === "always"); } }) ], ZoomToolbar.prototype, "visible", 2); __decorateClass2([ Validate51(ANCHOR_POINT) ], ZoomToolbar.prototype, "anchorPointX", 2); __decorateClass2([ Validate51(ANCHOR_POINT) ], ZoomToolbar.prototype, "anchorPointY", 2); var import_ag_charts_community139 = (init_main4(), __toCommonJS(main_exports)); var N = 1e6; function clientToNormal({ min, max }, a, Rx, Rw) { if (Rw === 0) return 0; return N * ((a - Rx) / Rw * (max - min) + min); } function solveTwoUnknowns(x1, x2, a1, a2, Rx, Rw) { [x1, x2] = [Math.min(x1, x2), Math.max(x1, x2)]; [a1, a2] = [Math.min(a1, a2), Math.max(a1, a2)]; const t1 = N * (a1 - Rx) / Rw; const t2 = N * (a2 - Rx) / Rw; const c = (a1 - Rx) / (a2 - Rx); const min = (x1 - c * x2) / (N - t1 + c * (t2 - N)); const max = (x2 + (t2 - N) * min) / t2; return { min, max }; } function isRangeOverlapping(centerA, radiusA, centerB, radiusB) { if (radiusA === 0) radiusA = 30; if (radiusB === 0) radiusB = 30; const minA = centerA - radiusA; const maxA = centerA + radiusA; const minB = centerB - radiusB; const maxB = centerB + radiusB; return !(maxA < minB || maxB < minA); } var ZoomTwoFingers = class { constructor() { this.touchStart = { origins: [ { identifier: 0, normalX: NaN, normalY: NaN }, { identifier: 0, normalX: NaN, normalY: NaN } ] }; this.initialZoom = { x: { min: 0, max: 1 }, y: { min: 0, max: 1 } }; this.previous = { a1: NaN, a2: NaN, b1: NaN, b2: NaN }; } start(event, target, zoom) { if (event.sourceEvent.targetTouches.length !== 2) return false; event.sourceEvent.preventDefault(); const targetTouches = Array.from(event.sourceEvent.targetTouches); const { x: Rx, y: Ry, width: Rw, height: Rh } = target.getBoundingClientRect(); this.initialZoom.x.min = zoom.x?.min ?? 0; this.initialZoom.x.max = zoom.x?.max ?? 1; this.initialZoom.y.min = zoom.y?.min ?? 0; this.initialZoom.y.max = zoom.y?.max ?? 1; this.touchStart.origins.forEach((t) => t.identifier = 0); this.previous.a1 = NaN; this.previous.a2 = NaN; this.previous.b1 = NaN; this.previous.b2 = NaN; for (const i of [0, 1]) { const a = targetTouches[i].clientX; const b = Ry + Rh - targetTouches[i].clientY; this.touchStart.origins[i].identifier = targetTouches[i].identifier; this.touchStart.origins[i].normalX = clientToNormal(this.initialZoom.x, a, Rx, Rw); this.touchStart.origins[i].normalY = clientToNormal(this.initialZoom.y, b, Ry, Rh); } const [tA, tB] = targetTouches; const [oA, oB] = this.touchStart.origins; const xOverlap = isRangeOverlapping(tA.clientX, tA.radiusX, tB.clientX, tB.radiusX); const yOverlap = isRangeOverlapping(tA.clientY, tA.radiusY, tB.clientY, tB.radiusY); if (yOverlap) oA.normalY = oB.normalY = (oA.normalY + oB.normalY) / 2; if (xOverlap) oA.normalX = oB.normalX = (oA.normalX + oB.normalX) / 2; return true; } update(event, target) { event.sourceEvent.preventDefault(); const targetTouches = Array.from(event.sourceEvent.targetTouches); const { x: Rx, y: Ry, width: Rw, height: Rh } = target.getBoundingClientRect(); const { origins } = this.touchStart; const touches = [0, 1].map((i) => targetTouches.find((t) => t.identifier === origins[i].identifier)); const x1 = origins[0].normalX; const x2 = origins[1].normalX; const a1 = touches[0].clientX; const a2 = touches[1].clientX; const y1 = origins[0].normalY; const y2 = origins[1].normalY; const b1 = Ry + Rh - touches[0].clientY; const b2 = Ry + Rh - touches[1].clientY; return this.twitchTolerantZoomPan4(x1, x2, a1, a2, y1, y2, b1, b2, Rx, Ry, Rw, Rh); } end(event) { const identifiers = Array.from(event.sourceEvent.targetTouches).map((t) => t.identifier); return !identifiers.includes(this.touchStart.origins[0].identifier) || !identifiers.includes(this.touchStart.origins[1].identifier); } // Small touch deltas on an axis, which can defined as one fingers moving ±1 pixel and the other not moving, can // cause the canvas to flicker between two zoompan views. // // For example, consider two fingers moving upwards slowly on the Y-axis with the following events (Y=0 is the top // of the screen): // // [0]: { finger1: { clientY: 101 }, finger2: { clientY: 201 } } // [1]: { finger1: { clientY: 101 }, finger2: { clientY: 200 } } // [2]: { finger1: { clientY: 100 }, finger2: { clientY: 200 } } // // The following transitions cause these changes to the zoompan respectively. // // [0] => [1] : yMin decreases, yMax increases // [1] => [2] : yMin increases, yMax decreases // // At highly-zoomed views, this sudden shift in yMin/yMax in the [1] => [2] transition is very noticeable. When many // of these kind of a transitions occur, the chart flickers between pan states instead of smoothly panning. Note // however that, if we didn't receive event [1], our transition would like this: // // [0] => [2] : yMin increases, yMax increases // // ... which is a smooth panning transition. Therefore to prevent flickering, we skip event [1]. twitchTolerantZoomPan4(x1, x2, a1, a2, y1, y2, b1, b2, Rx, Ry, Rw, Rh) { const { initialZoom, previous } = this; const x = twitchTolerantZoomPan2(x1, x2, a1, a2, previous, "a1", "a2", Rx, Rw, initialZoom.x); const y = twitchTolerantZoomPan2(y1, y2, b1, b2, previous, "b1", "b2", Ry, Rh, initialZoom.y); return { x, y }; } }; function twitchTolerantZoomPan2(x1, x2, a1, a2, previous, previousKey1, previousKey2, Rx, Rw, initialZoom) { if (x1 != x2) { const a1prev = previous[previousKey1]; const a2prev = previous[previousKey2]; const dx2 = Math.abs(a1 - a1prev) + Math.abs(a2 - a2prev); if (dx2 <= 1) { a1 = a1prev; a2 = a2prev; } else { previous[previousKey1] = a1; previous[previousKey2] = a2; } return solveTwoUnknowns(x1, x2, a1, a2, Rx, Rw); } else { const xn1 = clientToNormal(initialZoom, a1, Rx, Rw); const xn2 = clientToNormal(initialZoom, a2, Rx, Rw); const xavg = (xn1 + xn2) / 2; const dzoom = (x1 - xavg) / N; return { min: initialZoom.min + dzoom, max: initialZoom.max + dzoom }; } } var { BOOLEAN: BOOLEAN25, NUMBER: NUMBER13, POSITIVE_NUMBER: POSITIVE_NUMBER13, RATIO: RATIO11, UNION: UNION10, OBJECT: OBJECT21, OR: OR4, ActionOnSet: ActionOnSet9, ChartAxisDirection: ChartAxisDirection16, ChartUpdateType: ChartUpdateType3, Deprecated: Deprecated2, Validate: Validate52, InteractionState: InteractionState4, ProxyProperty: ProxyProperty3, round: sharedRound } = import_ag_charts_community140._ModuleSupport; var round22 = (value) => sharedRound(value, 10); var CURSOR_ID = "zoom-cursor"; var TOOLTIP_ID = "zoom-tooltip"; var ZoomAutoScaling = class extends import_ag_charts_community140._ModuleSupport.BaseProperties { constructor(onChange) { super(); this.onChange = onChange; this.enabled = false; this.padding = 0; } }; __decorateClass2([ Validate52(BOOLEAN25), ActionOnSet9({ changeValue(enabled) { this.onChange({ enabled, padding: this.padding }); } }) ], ZoomAutoScaling.prototype, "enabled", 2); __decorateClass2([ Validate52(RATIO11), ActionOnSet9({ changeValue(padding) { this.onChange({ enabled: this.enabled, padding }); } }) ], ZoomAutoScaling.prototype, "padding", 2); var Zoom = class extends import_ag_charts_community140._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = false; this.enableAxisDragging = true; this.enableDoubleClickToReset = true; this.enablePanning = true; this.enableScrolling = true; this.enableSelecting = false; this.enableTwoFingerZoom = true; this.panKey = "alt"; this.axes = "x"; this.scrollingStep = (UNIT.max - UNIT.min) / 10; this.keepAspectRatio = false; this.minVisibleItems = 2; this.anchorPointX = DEFAULT_ANCHOR_POINT_X; this.anchorPointY = DEFAULT_ANCHOR_POINT_Y; this.autoScaling = new ZoomAutoScaling((newValue) => { this.ctx.zoomManager.setAutoScaleYAxis(newValue.enabled, newValue.padding); }); this.buttons = new ZoomToolbar( this.ctx, this.getModuleProperties.bind(this), this.getResetZoom.bind(this), this.updateZoom.bind(this), this.updateAxisZoom.bind(this), this.resetZoom.bind(this), this.isZoomValid.bind(this) ); this.axisDragger = new ZoomAxisDragger(); this.panner = new ZoomPanner(); this.scroller = new ZoomScroller(); this.scrollPanner = new ZoomScrollPanner(); this.twoFingers = new ZoomTwoFingers(); this.deceleration = "short"; this.dragState = 0; this.isState = (state) => this.ctx.interactionManager.isState(state); this.destroyContextMenuActions = void 0; this.isFirstWheelEvent = true; this.debouncedWheelReset = debounce(() => { this.isFirstWheelEvent = true; }, 100); const selectionRect = new ZoomRect(); this.selector = new ZoomSelector(selectionRect, this.getZoom.bind(this), this.isZoomValid.bind(this)); this.contextMenu = new ZoomContextMenu( ctx.contextMenuRegistry, ctx.zoomManager, this.getModuleProperties.bind(this), () => this.paddedRect, this.updateZoom.bind(this), this.isZoomValid.bind(this) ); this.domProxy = new ZoomDOMProxy({ onDragStart: (id, dir) => this.onAxisDragStart(id, dir), onDrag: (ev) => { this.onDragMove({ ...ev, currentX: ev.offsetX, currentY: ev.offsetY }); }, onDragEnd: () => this.onDragEnd(), onDoubleClick: (id, direction) => { this.hoveredAxis = { id, direction }; this.onDoubleClick(); this.hoveredAxis = void 0; } }); this.destroyFns.push( ctx.scene.attachNode(selectionRect), ctx.chartEventManager.addListener("series-keynav-zoom", (event) => this.onNavZoom(event)), ctx.widgets.seriesDragInterpreter.addListener("dblclick", (event) => this.onDoubleClick(event)), ctx.widgets.seriesDragInterpreter.addListener("drag-move", (event) => this.onDragMove(event)), ctx.widgets.seriesDragInterpreter.addListener("drag-start", (event) => this.onDragStart(event)), ctx.widgets.seriesDragInterpreter.addListener("drag-end", () => this.onDragEnd()), ctx.widgets.seriesWidget.addListener("wheel", (event) => this.onWheel(event)), ctx.widgets.seriesWidget.addListener("touchstart", (event, current) => this.onTouchStart(event, current)), ctx.widgets.seriesWidget.addListener("touchmove", (event, current) => this.onTouchMove(event, current)), ctx.widgets.seriesWidget.addListener("touchend", (event) => this.onTouchEnd(event)), ctx.widgets.seriesWidget.addListener("touchcancel", (event) => this.onTouchEnd(event)), ctx.updateService.addListener("process-data", (event) => this.onProcessData(event)), ctx.layoutManager.addListener("layout:complete", (event) => this.onLayoutComplete(event)), ctx.zoomManager.addListener("zoom-change", (event) => this.onZoomChange(event)), ctx.zoomManager.addListener("zoom-pan-start", (event) => this.onZoomPanStart(event)), this.panner.addListener("update", (event) => this.onPanUpdate(event)), () => this.teardown() ); } teardown() { this.ctx.zoomManager.setZoomModuleEnabled(false); this.buttons.destroy(); this.destroyContextMenuActions?.(); } onEnabledChange(enabled) { this.ctx.zoomManager.setZoomModuleEnabled(enabled); if (this.contextMenu) { this.destroyContextMenuActions?.(); this.destroyContextMenuActions = this.contextMenu.registerActions(enabled); } } isIgnoredTouch(event) { if (event?.device !== "touch") { return false; } if (this.ctx.chartService.touch.dragAction !== "drag") { return true; } if (this.enableSelecting) { return false; } if (!this.enablePanning) { return true; } const { x, y } = this.getZoom(); return x.min === 0 && x.max === 1 && y.min === 0 && y.max === 1; } onDoubleClick(event) { const { enabled, enableDoubleClickToReset, hoveredAxis, ctx: { zoomManager } } = this; if (!enabled || !enableDoubleClickToReset || !this.isState(InteractionState4.ZoomClickable)) return; if (hoveredAxis) { zoomManager.resetAxisZoom("zoom", hoveredAxis.id); } else if (!event?.preventZoomDblClick) { this.resetZoom(); } } onDragStart(event) { const { enabled, enableAxisDragging, enablePanning, enableSelecting, hoveredAxis, ctx: { domManager, zoomManager } } = this; if (!enabled) return; if (!this.hoveredAxis) { if (!this.isState(InteractionState4.ZoomDraggable) || this.dragState !== 0 || this.isIgnoredTouch(event)) { return; } } this.panner.stopInteractions(); let newDragState = 0; if (enableAxisDragging && hoveredAxis) { newDragState = 1; } else if (event != null) { const panKeyPressed = this.isPanningKeyPressed(event.sourceEvent); if (enablePanning && (!enableSelecting || panKeyPressed)) { domManager.updateCursor(CURSOR_ID, "grabbing"); newDragState = 2; this.panner.start(); } else if (enableSelecting && !panKeyPressed) { newDragState = 3; } } if ((this.dragState = newDragState) !== 0) { zoomManager.fireZoomPanStartEvent("zoom"); } } onDragMove(event) { const { anchorPointX, anchorPointY, axisDragger, dragState, enabled, paddedRect, panner, selector, seriesRect, shouldFlipXY, hoveredAxis, ctx: { interactionManager, tooltipManager, updateService, zoomManager } } = this; if (!enabled || !paddedRect || !seriesRect) return; if (!hoveredAxis) { if (!this.isState(InteractionState4.ZoomDraggable) || this.isIgnoredTouch(event)) { return; } } interactionManager.pushState(import_ag_charts_community140._ModuleSupport.InteractionState.ZoomDrag); if (event.device === "touch") { event.sourceEvent.preventDefault(); } const zoom = this.getZoom(); switch (dragState) { case 1: { if (!hoveredAxis) break; const { id: axisId, direction } = hoveredAxis; let anchor = direction === ChartAxisDirection16.X ? anchorPointX : anchorPointY; if (shouldFlipXY) anchor = direction === ChartAxisDirection16.X ? anchorPointY : anchorPointX; const axisZoom = zoomManager.getAxisZoom(axisId); const newZoom = axisDragger.update(event, direction, anchor, seriesRect, zoom, axisZoom); zoomManager.setAxisManuallyAdjusted("zoom", axisId); this.updateAxisZoom(axisId, direction, newZoom); break; } case 2: panner.update(event); break; case 3: selector.update(event, this.getModuleProperties(), paddedRect); break; case 0: return; } tooltipManager.updateTooltip(TOOLTIP_ID); updateService.update(ChartUpdateType3.PERFORM_LAYOUT, { skipAnimations: true }); } onDragEnd() { const { axisDragger, dragState, enabled, panner, selector, ctx: { domManager, interactionManager, tooltipManager } } = this; interactionManager.popState(import_ag_charts_community140._ModuleSupport.InteractionState.ZoomDrag); if (!enabled || dragState === 0) return; switch (dragState) { case 1: this.hoveredAxis = void 0; axisDragger.stop(); break; case 2: panner.stop(); break; case 3: { if (!selector.didUpdate()) break; const zoom = this.getZoom(); const newZoom = selector.stop(this.seriesRect, this.paddedRect, zoom); this.updateZoom(newZoom); break; } } this.dragState = 0; domManager.updateCursor(CURSOR_ID); tooltipManager.removeTooltip(TOOLTIP_ID); } onNavZoom(event) { const { enabled, enableScrolling, scroller } = this; const isDefaultState = this.ctx.interactionManager.isState(import_ag_charts_community140._ModuleSupport.InteractionState.Default); if (!isDefaultState || !enabled || !enableScrolling) return; event.widgetEvent.sourceEvent.preventDefault(); this.updateZoom(scroller.updateDelta(event.delta, this.getModuleProperties(), this.getZoom())); } onWheel(event) { const { enabled, enablePanning, enableScrolling, paddedRect } = this; if (!enabled || !enableScrolling || !paddedRect || !this.isState(InteractionState4.ZoomWheelable)) return; const { deltaX, deltaY } = event.sourceEvent; const isHorizontalScrolling = deltaX != null && deltaY != null && Math.abs(deltaX) > Math.abs(deltaY); if (enablePanning && isHorizontalScrolling) { this.onWheelPanning(event); } else { this.onWheelScrolling(event); } } onWheelPanning(event) { const { scrollingStep, scrollPanner, seriesRect, ctx: { zoomManager } } = this; if (!seriesRect) return; event.sourceEvent.preventDefault(); const newZooms = scrollPanner.update(event, scrollingStep, seriesRect, zoomManager.getAxisZooms()); for (const [axisId, { direction, zoom }] of Object.entries(newZooms)) { this.updateAxisZoom(axisId, direction, zoom); } } onWheelScrolling(event) { const { enableAxisDragging, enableIndependentAxes, hoveredAxis, scroller, seriesRect, ctx: { zoomManager } } = this; if (!seriesRect) return; const zoom = this.getZoom(); let isZoomCapped = event.deltaY > 0 && this.isMaxZoom(zoom); const isAxisScrolling = enableAxisDragging && hoveredAxis != null; let isScalingX = this.isScalingX(); let isScalingY = this.isScalingY(); if (isAxisScrolling) { isScalingX = hoveredAxis.direction === import_ag_charts_community140._ModuleSupport.ChartAxisDirection.X; isScalingY = !isScalingX; } const props = this.getModuleProperties({ isScalingX, isScalingY }); let updated = true; if (enableIndependentAxes === true) { const newZooms = scroller.updateAxes(event, props, seriesRect, zoomManager.getAxisZooms()); for (const [axisId, { direction, zoom: axisZoom }] of Object.entries(newZooms)) { if (isAxisScrolling && hoveredAxis.id !== axisId) continue; updated && (updated = this.updateAxisZoom(axisId, direction, axisZoom)); } } else { const newZoom = scroller.update(event, props, seriesRect, this.getZoom()); updated = this.updateUnifiedZoom(newZoom); } isZoomCapped || (isZoomCapped = event.deltaY < 0 && !updated); if (!this.isFirstWheelEvent || !isZoomCapped) { event.sourceEvent.preventDefault(); } this.isFirstWheelEvent = false; this.debouncedWheelReset(); } onAxisDragStart(id, direction) { this.hoveredAxis = { id, direction }; this.onDragStart(void 0); } onTouchStart(event, current) { if (!this.enableTwoFingerZoom || this.dragState !== 0) return; if (this.twoFingers.start(event, current, this.getZoom())) { this.dragState = 4; } } onTouchMove(event, current) { if (!this.enableTwoFingerZoom || this.dragState !== 4) return; const newZoom = this.twoFingers.update(event, current); this.updateZoom(constrainZoom(newZoom)); } onTouchEnd(event) { if (!this.enableTwoFingerZoom || this.dragState !== 4) return; event.sourceEvent.preventDefault(); if (this.twoFingers.end(event)) { this.dragState = 0; } } onProcessData(event) { this.shouldFlipXY = event.series.shouldFlipXY; } onLayoutComplete(event) { this.domProxy.update(this.enableAxisDragging, this.ctx); const { enabled } = this; if (!enabled) return; const { series: { rect, paddedRect } } = event; this.seriesRect = rect; this.paddedRect = paddedRect; } onZoomChange(event) { if (event.callerId !== "zoom") { this.panner.stopInteractions(); } const zoom = this.getZoom(); this.buttons.toggleVisibleZoomed(this.isMaxZoom(zoom)); } onZoomPanStart(event) { if (event.callerId === "zoom") { this.panner.stopInteractions(); } } onPanUpdate(event) { const { panner, seriesRect, ctx: { tooltipManager, zoomManager } } = this; if (!seriesRect) return; const newZooms = panner.translateZooms(seriesRect, zoomManager.getAxisZooms(), event.deltaX, event.deltaY); for (const [axisId, { direction, zoom }] of Object.entries(newZooms)) { this.updateAxisZoom(axisId, direction, zoom); } tooltipManager.updateTooltip(TOOLTIP_ID); } isPanningKeyPressed(event) { switch (this.panKey) { case "alt": return event.altKey; case "ctrl": return event.ctrlKey; case "shift": return event.shiftKey; case "meta": return event.metaKey; } } isScalingX() { if (this.axes === "xy") return true; return this.shouldFlipXY ? this.axes === "y" : this.axes === "x"; } isScalingY() { if (this.axes === "xy") return true; return this.shouldFlipXY ? this.axes === "x" : this.axes === "y"; } getAnchorPointX() { return this.shouldFlipXY ? this.anchorPointY : this.anchorPointX; } getAnchorPointY() { return this.shouldFlipXY ? this.anchorPointX : this.anchorPointY; } isMaxZoom(zoom) { return isZoomEqual(zoom, unitZoomState()); } isZoomValid(newZoom) { const { minVisibleItems, minVisibleItemsX, minVisibleItemsY, ctx: { zoomManager } } = this; if (minVisibleItems === 0) return true; const zoom = this.getZoom(); const zoomedInX = round22(dx(newZoom)) < round22(dx(zoom)); const zoomedInY = round22(dy(newZoom)) < round22(dy(zoom)); if (!zoomedInX && !zoomedInY) return true; if (minVisibleItemsX != null && zoomedInX) { return zoomManager.isVisibleItemsCountAtLeast(newZoom, minVisibleItemsX); } if (minVisibleItemsY != null && zoomedInY) { return zoomManager.isVisibleItemsCountAtLeast(newZoom, minVisibleItemsY); } return zoomManager.isVisibleItemsCountAtLeast(newZoom, minVisibleItems); } isAxisZoomValid(direction, axisZoom) { const { minVisibleItems, minVisibleItemsX, minVisibleItemsY, ctx: { zoomManager } } = this; const zoom = this.getZoom(); const deltaAxis = axisZoom.max - axisZoom.min; const deltaOld = zoom[direction].max - zoom[direction].min; const newZoom = { ...zoom, [direction]: axisZoom }; const minVisibleDir = direction === ChartAxisDirection16.X ? minVisibleItemsX : minVisibleItemsY; return deltaAxis >= deltaOld || zoomManager.isVisibleItemsCountAtLeast(newZoom, minVisibleDir ?? minVisibleItems); } resetZoom() { this.ctx.zoomManager.resetZoom("zoom"); } updateZoom(zoom) { if (this.enableIndependentAxes) { this.updatePrimaryAxisZooms(zoom); } else { this.updateUnifiedZoom(zoom); } } updateUnifiedZoom(zoom) { if (!this.isZoomValid(zoom)) { this.ctx.updateService.update(ChartUpdateType3.SCENE_RENDER, { skipAnimations: true }); return false; } this.ctx.zoomManager.updateZoom("zoom", zoom); return true; } updatePrimaryAxisZooms(zoom) { this.updatePrimaryAxisZoom(zoom, ChartAxisDirection16.X); this.updatePrimaryAxisZoom(zoom, ChartAxisDirection16.Y); } updatePrimaryAxisZoom(zoom, direction) { const axisId = this.ctx.zoomManager.getPrimaryAxisId(direction); if (axisId == null) return; this.updateAxisZoom(axisId, direction, zoom[direction]); } updateAxisZoom(axisId, direction, axisZoom) { const { enableIndependentAxes, ctx: { zoomManager } } = this; if (!axisZoom) return false; const zoom = this.getZoom(); if (enableIndependentAxes !== true) { zoom[direction] = axisZoom; return this.updateUnifiedZoom(zoom); } if (!this.isAxisZoomValid(direction, axisZoom)) return false; zoomManager.updateAxisZoom("zoom", axisId, axisZoom); return true; } getZoom() { return definedZoomState(this.ctx.zoomManager.getZoom()); } getResetZoom() { return definedZoomState(this.ctx.zoomManager.getRestoredZoom()); } getModuleProperties(overrides) { return { anchorPointX: overrides?.anchorPointX ?? this.getAnchorPointX(), anchorPointY: overrides?.anchorPointY ?? this.getAnchorPointY(), enabled: overrides?.enabled ?? this.enabled, independentAxes: overrides?.independentAxes ?? this.enableIndependentAxes === true, isScalingX: overrides?.isScalingX ?? this.isScalingX(), isScalingY: overrides?.isScalingY ?? this.isScalingY(), keepAspectRatio: overrides?.keepAspectRatio ?? this.keepAspectRatio, scrollingStep: overrides?.scrollingStep ?? this.scrollingStep }; } }; __decorateClass2([ ActionOnSet9({ newValue(enabled) { this.onEnabledChange(enabled); } }), Validate52(BOOLEAN25) ], Zoom.prototype, "enabled", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableAxisDragging", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableDoubleClickToReset", 2); __decorateClass2([ ActionOnSet9({ changeValue(newValue) { this.ctx.zoomManager.setIndependentAxes(Boolean(newValue)); } }), Validate52(BOOLEAN25, { optional: true }) ], Zoom.prototype, "enableIndependentAxes", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "enablePanning", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableScrolling", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableSelecting", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableTwoFingerZoom", 2); __decorateClass2([ Validate52(UNION10(["alt", "ctrl", "meta", "shift"], "a pan key")) ], Zoom.prototype, "panKey", 2); __decorateClass2([ Validate52(UNION10(["x", "y", "xy"], "an axis")) ], Zoom.prototype, "axes", 2); __decorateClass2([ Validate52(RATIO11) ], Zoom.prototype, "scrollingStep", 2); __decorateClass2([ Validate52(BOOLEAN25) ], Zoom.prototype, "keepAspectRatio", 2); __decorateClass2([ Validate52(POSITIVE_NUMBER13) ], Zoom.prototype, "minVisibleItems", 2); __decorateClass2([ Deprecated2("Use [minVisibleItems] instead."), Validate52(NUMBER13.restrict({ min: 1 })) ], Zoom.prototype, "minVisibleItemsX", 2); __decorateClass2([ Deprecated2("Use [minVisibleItems] instead."), Validate52(NUMBER13.restrict({ min: 1 })) ], Zoom.prototype, "minVisibleItemsY", 2); __decorateClass2([ Validate52(ANCHOR_POINT) ], Zoom.prototype, "anchorPointX", 2); __decorateClass2([ Validate52(ANCHOR_POINT) ], Zoom.prototype, "anchorPointY", 2); __decorateClass2([ Validate52(OBJECT21) ], Zoom.prototype, "autoScaling", 2); __decorateClass2([ Validate52(OBJECT21) ], Zoom.prototype, "buttons", 2); __decorateClass2([ ProxyProperty3("panner.deceleration"), Validate52(OR4(RATIO11, UNION10(["off", "short", "long"], "a deceleration"))) ], Zoom.prototype, "deceleration", 2); var buttons = { enabled: true, visible: "hover", buttons: [ { icon: "zoom-out", tooltip: "toolbarZoomZoomOut", value: "zoom-out", section: "scale" }, { icon: "zoom-in", tooltip: "toolbarZoomZoomIn", value: "zoom-in", section: "scale" }, { icon: "pan-left", tooltip: "toolbarZoomPanLeft", value: "pan-left", section: "pan" }, { icon: "pan-right", tooltip: "toolbarZoomPanRight", value: "pan-right", section: "pan" }, { icon: "reset", tooltip: "toolbarZoomReset", value: "reset", section: "reset" } ] }; var ZoomModule = { type: "root", optionsKey: "zoom", packageType: "enterprise", chartTypes: ["cartesian", "topology"], moduleFactory: (ctx) => new Zoom(ctx), themeTemplate: { zoom: { anchorPointX: "end", anchorPointY: "middle", axes: "x", buttons, enabled: false, enableAxisDragging: true, enableDoubleClickToReset: true, enablePanning: true, enableScrolling: true, enableSelecting: false, enableTwoFingerZoom: true, deceleration: "short", minVisibleItems: 2, panKey: "alt", scrollingStep: 0.1, autoScaling: { enabled: false, padding: 0.05 } } } }; var import_ag_charts_community142 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community141 = (init_main4(), __toCommonJS(main_exports)); var { BOOLEAN: BOOLEAN26, OBJECT: OBJECT222, POSITION: POSITION2, POSITIVE_NUMBER: POSITIVE_NUMBER14, BaseProperties: BaseProperties18, AxisTicks: AxisTicks2, ZIndexMap: ZIndexMap8, ProxyProperty: ProxyProperty4, Validate: Validate53, LayoutElement: LayoutElement5, createId: createId4, Group: Group8, Rect: Rect22, Marker: Marker2, TranslatableGroup: TranslatableGroup3, LinearGradient: LinearGradient2 } = import_ag_charts_community141._ModuleSupport; var GradientBar = class extends BaseProperties18 { constructor() { super(...arguments); this.thickness = 16; this.preferredLength = 100; } }; __decorateClass2([ Validate53(POSITIVE_NUMBER14) ], GradientBar.prototype, "thickness", 2); __decorateClass2([ Validate53(POSITIVE_NUMBER14) ], GradientBar.prototype, "preferredLength", 2); var GradientLegendScale = class { constructor(axisTicks) { this.axisTicks = axisTicks; } }; __decorateClass2([ ProxyProperty4("axisTicks.label") ], GradientLegendScale.prototype, "label", 2); __decorateClass2([ ProxyProperty4("axisTicks.interval") ], GradientLegendScale.prototype, "interval", 2); __decorateClass2([ ProxyProperty4("axisTicks.padding") ], GradientLegendScale.prototype, "padding", 2); var GradientLegend = class { constructor(ctx) { this.ctx = ctx; this.id = createId4(this); this.legendGroup = new TranslatableGroup3({ name: "legend", zIndex: ZIndexMap8.LEGEND }); this.gradientRect = new Rect22(); this.arrow = new Marker2({ shape: "triangle" }); this.ticksGroup = new Group8({ name: "legend-axis-group" }); this.destroyFns = []; this.enabled = false; this.position = "bottom"; this.reverseOrder = false; this.gradient = new GradientBar(); this.spacing = 20; this.data = []; this.highlightManager = ctx.highlightManager; this.axisTicks = new AxisTicks2(); this.axisTicks.attachAxis(this.ticksGroup); this.scale = new GradientLegendScale(this.axisTicks); this.legendGroup.append([this.gradientRect, this.arrow, this.ticksGroup]); this.destroyFns.push( ctx.highlightManager.addListener("highlight-change", () => this.onChartHoverChange()), ctx.layoutManager.registerElement(LayoutElement5.Legend, (e) => this.onStartLayout(e)), () => this.legendGroup.remove() ); } isVertical() { return this.position === "right" || this.position === "left"; } destroy() { this.destroyFns.forEach((f) => f()); } attachLegend(scene) { scene.appendChild(this.legendGroup); } onStartLayout(ctx) { const [data] = this.data; if (!this.enabled || !data?.enabled) { this.legendGroup.visible = false; return; } const { colorRange } = this.normalizeColorArrays(data); this.updateGradientRect(ctx.layoutBox, colorRange); const axisBBox = this.updateAxis(data); const { left, top } = this.getMeasurements(ctx.layoutBox, axisBBox); this.updateArrow(); this.legendGroup.visible = true; this.legendGroup.translationX = left; this.legendGroup.translationY = top; } normalizeColorArrays(data) { let colorDomain = data.colorDomain.slice(); const colorRange = data.colorRange.slice(); if (colorDomain.length === colorRange.length) { return { colorDomain, colorRange }; } if (colorDomain.length > colorRange.length) { colorRange.splice(colorDomain.length); } const [d0, d1] = colorDomain; const count = colorRange.length; colorDomain = colorRange.map((_, i) => { if (i === 0) { return d0; } else if (i === count - 1) { return d1; } return d0 + (d1 - d0) * i / (count - 1); }); return { colorDomain, colorRange }; } updateGradientRect(shrinkRect, colorRange) { const { gradientRect } = this; const { preferredLength, thickness } = this.gradient; let angle2; if (this.isVertical()) { angle2 = 0; gradientRect.width = thickness; gradientRect.height = Math.min(shrinkRect.height, preferredLength); } else { angle2 = 90; gradientRect.width = Math.min(shrinkRect.width, preferredLength); gradientRect.height = thickness; } gradientRect.fill = new LinearGradient2( "oklch", colorRange.map((color, i) => ({ offset: i / (colorRange.length - 1), color })), angle2 ); } updateAxis(data) { const { axisTicks } = this; const vertical = this.isVertical(); const positiveAxis = this.reverseOrder !== vertical; axisTicks.position = this.position; axisTicks.translationX = vertical ? this.gradient.thickness : 0; axisTicks.translationY = vertical ? 0 : this.gradient.thickness; axisTicks.scale.domain = positiveAxis ? data.colorDomain.slice().reverse() : data.colorDomain; axisTicks.scale.range = vertical ? [0, this.gradientRect.height] : [0, this.gradientRect.width]; return axisTicks.calculateLayout(); } updateArrow() { const highlighted = this.highlightManager.getActiveHighlight(); const { arrow } = this; if (highlighted?.colorValue == null) { arrow.visible = false; return; } const { scale: scale2, label } = this.axisTicks; const size = label.fontSize ?? 0; const t = scale2.convert(highlighted.colorValue); let { x, y } = this.gradientRect; let rotation = Math.PI; if (this.isVertical()) { x -= size / 2; y += t; rotation /= 2; } else { x += t; y -= size / 2; } arrow.visible = true; arrow.fill = label.color; arrow.rotation = rotation; arrow.size = size; arrow.translationX = x; arrow.translationY = y; } getMeasurements(shrinkRect, axisBox) { let { x: left, y: top } = shrinkRect; let { width: width2, height: height2 } = this.gradientRect; if (this.isVertical()) { width2 += axisBox.width + 5; } else { height2 += axisBox.height + 5; } switch (this.position) { case "left": top += shrinkRect.height / 2 - height2 / 2; shrinkRect.shrink(width2 + this.spacing, "left"); break; case "right": left += shrinkRect.width - width2; top += shrinkRect.height / 2 - height2 / 2; shrinkRect.shrink(width2 + this.spacing, "right"); break; case "top": left += shrinkRect.width / 2 - width2 / 2; shrinkRect.shrink(height2 + this.spacing, "top"); break; case "bottom": left += shrinkRect.width / 2 - width2 / 2; top += shrinkRect.height - height2; shrinkRect.shrink(height2 + this.spacing, "bottom"); } return { top, left }; } onChartHoverChange() { if (!this.enabled) return; this.updateArrow(); } }; GradientLegend.className = "GradientLegend"; __decorateClass2([ Validate53(BOOLEAN26) ], GradientLegend.prototype, "enabled", 2); __decorateClass2([ Validate53(POSITION2) ], GradientLegend.prototype, "position", 2); __decorateClass2([ Validate53(BOOLEAN26) ], GradientLegend.prototype, "reverseOrder", 2); __decorateClass2([ Validate53(OBJECT222) ], GradientLegend.prototype, "gradient", 2); __decorateClass2([ Validate53(POSITIVE_NUMBER14) ], GradientLegend.prototype, "spacing", 2); var GradientLegendModule = { type: "legend", optionsKey: "gradientLegend", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], identifier: "gradient", moduleFactory: (ctx) => new GradientLegend(ctx), themeTemplate: { enabled: false, position: "bottom", spacing: 20, scale: { padding: 13, label: { color: { $ref: "textColor" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" } }, interval: { minSpacing: 15 } }, gradient: { preferredLength: 100, thickness: 16 }, reverseOrder: false }, removable: "standalone-only" }; var import_ag_charts_community143 = (init_main4(), __toCommonJS(main_exports)); function injectWatermark(domManager, text22) { const element2 = domManager.addChild("canvas-overlay", "watermark"); const textElement = import_ag_charts_community143._ModuleSupport.createElement("span"); textElement.innerText = text22; element2.addEventListener("animationend", () => { domManager.removeChild("canvas-overlay", "watermark"); domManager.removeStyles("watermark"); }); element2.classList.add("ag-watermark"); element2.appendChild(textElement); } var import_ag_charts_community147 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community146 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community145 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community144 = (init_main4(), __toCommonJS(main_exports)); var { findMinMax: findMinMax22 } = import_ag_charts_community144._ModuleSupport; var X_MIN2 = 0; var X_MAX2 = 1; var Y_MIN2 = 2; var Y_MAX2 = 3; var SPAN3 = 4; function maxRangeFittingPoints(data, precision = 1) { let power = Math.ceil(Math.log2(data.length / precision)) - 1; power = Math.min(Math.max(power, 0), 16); return 2 ** power | 0; } function aggregationDomain(domain) { return findMinMax22(domain.map((x) => Number(x))); } function xRatioForDatumIndex(xValue, d0, d1) { return (xValue.valueOf() - d0) / (d1 - d0); } function aggregationIndexForXRatio(xRatio, maxRange) { return Math.min(Math.floor(xRatio * maxRange), maxRange - 1) * SPAN3 | 0; } function createAggregationIndices(xValues, yMaxValues, yMinValues, d0, d1, maxRange) { const indexData = new Int32Array(maxRange * SPAN3).fill(-1); const valueData = new Float64Array(maxRange * SPAN3).fill(NaN); for (let datumIndex = 0; datumIndex < xValues.length; datumIndex += 1) { const xValue = xValues[datumIndex]; const yMaxValue = yMaxValues[datumIndex]; const yMinValue = yMinValues[datumIndex]; if (xValue == null || yMaxValue == null || yMinValue == null) continue; const xRatio = xRatioForDatumIndex(xValue, d0, d1); const yMax = yMaxValue.valueOf(); const yMin = yMinValue.valueOf(); const aggIndex = aggregationIndexForXRatio(xRatio, maxRange); const unset = indexData[aggIndex + X_MIN2] === -1; if (unset || xRatio < valueData[aggIndex + X_MIN2]) { indexData[aggIndex + X_MIN2] = datumIndex; valueData[aggIndex + X_MIN2] = xRatio; } if (unset || xRatio > valueData[aggIndex + X_MAX2]) { indexData[aggIndex + X_MAX2] = datumIndex; valueData[aggIndex + X_MAX2] = xRatio; } if (unset || yMin < valueData[aggIndex + Y_MIN2]) { indexData[aggIndex + Y_MIN2] = datumIndex; valueData[aggIndex + Y_MIN2] = yMin; } if (unset || yMax > valueData[aggIndex + Y_MAX2]) { indexData[aggIndex + Y_MAX2] = datumIndex; valueData[aggIndex + Y_MAX2] = yMax; } } return { indexData, valueData }; } function compactAggregationIndices(indexData, valueData, maxRange, { inPlace = false } = {}) { const nextMaxRange = maxRange / 2 | 0; const nextIndexData = !inPlace ? new Int32Array(nextMaxRange * SPAN3) : indexData; const nextValueData = !inPlace ? new Float64Array(nextMaxRange * SPAN3) : valueData; for (let i = 0; i < nextMaxRange; i += 1) { const aggIndex = i * SPAN3 | 0; const index0 = aggIndex * 2 | 0; const index1 = index0 + SPAN3 | 0; const index1Unset = indexData[index1 + X_MIN2] === -1; const xMinAggIndex = index1Unset || valueData[index0 + X_MIN2] < valueData[index1 + X_MIN2] ? index0 : index1; nextIndexData[aggIndex + X_MIN2] = indexData[xMinAggIndex + X_MIN2]; nextValueData[aggIndex + X_MIN2] = valueData[xMinAggIndex + X_MIN2]; const xMaxAggIndex = index1Unset || valueData[index0 + X_MAX2] > valueData[index1 + X_MAX2] ? index0 : index1; nextIndexData[aggIndex + X_MAX2] = indexData[xMaxAggIndex + X_MAX2]; nextValueData[aggIndex + X_MAX2] = valueData[xMaxAggIndex + X_MAX2]; const yMinAggIndex = index1Unset || valueData[index0 + Y_MIN2] < valueData[index1 + Y_MIN2] ? index0 : index1; nextIndexData[aggIndex + Y_MIN2] = indexData[yMinAggIndex + Y_MIN2]; nextValueData[aggIndex + Y_MIN2] = valueData[yMinAggIndex + Y_MIN2]; const yMaxAggIndex = index1Unset || valueData[index0 + Y_MAX2] > valueData[index1 + Y_MAX2] ? index0 : index1; nextIndexData[aggIndex + Y_MAX2] = indexData[yMaxAggIndex + Y_MAX2]; nextValueData[aggIndex + Y_MAX2] = valueData[yMaxAggIndex + Y_MAX2]; } return { maxRange: nextMaxRange, indexData: nextIndexData, valueData: nextValueData }; } var indexes = { xMin: X_MIN2, xMax: X_MAX2, yMin: Y_MIN2, yMax: Y_MAX2, span: SPAN3 }; var AGGREGATION_THRESHOLD = 1e3; var PRECISION = 5; function getIndices(maxRange, indexData) { return Array.from({ length: maxRange }, (_, index) => { const aggIndex = index * SPAN3; const xMinIndex = indexData[aggIndex + X_MIN2]; const xMaxIndex = indexData[aggIndex + X_MAX2]; return (xMinIndex + xMaxIndex) / 2 | 0; }); } function aggregateBarData(xValues, yValues, domain) { if (xValues.length < AGGREGATION_THRESHOLD) return; const [d0, d1] = aggregationDomain(domain); let maxRange = maxRangeFittingPoints(xValues, PRECISION); let { indexData, valueData } = createAggregationIndices(xValues, yValues, yValues, d0, d1, maxRange); let indices = getIndices(maxRange, indexData); const filters = [{ maxRange, indexData, indices, indexes }]; while (maxRange > 64) { ({ indexData, valueData, maxRange } = compactAggregationIndices(indexData, valueData, maxRange)); indices = getIndices(maxRange, indexData); filters.push({ maxRange, indexData, indices, indexes }); } filters.reverse(); return filters; } var { ChartAxisDirection: ChartAxisDirection17, ContinuousScale: ContinuousScale22, OrdinalTimeScale: OrdinalTimeScale22 } = import_ag_charts_community146._ModuleSupport; var BarSeries2 = class extends import_ag_charts_community146._ModuleSupport.BarSeries { aggregateData(dataModel, processedData) { if (processedData?.type !== "ungrouped") return; const xAxis = this.axes[ChartAxisDirection17.X]; if (xAxis == null || !(ContinuousScale22.is(xAxis.scale) || OrdinalTimeScale22.is(xAxis.scale))) return; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const yValues = dataModel.resolveColumnById(this, `yValue-raw`, processedData); const { index } = dataModel.resolveProcessedDataDefById(this, `xValue`); const domain = processedData.domain.keys[index]; return aggregateBarData(xValues, yValues, domain); } }; var { BarSeriesModule: BarSeriesModule2 } = import_ag_charts_community147._ModuleSupport; var BarModule = { ...BarSeriesModule2, type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "bar", moduleFactory: (ctx) => new BarSeries2(ctx) }; var import_ag_charts_community152 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community150 = (init_main4(), __toCommonJS(main_exports)); function prepareBoxPlotFromTo(isVertical) { const from3 = isVertical ? { scalingX: 1, scalingY: 0 } : { scalingX: 0, scalingY: 1 }; const to = { scalingX: 1, scalingY: 1 }; return { from: from3, to }; } function resetBoxPlotSelectionsScalingCenterFn(isVertical) { return (_node, datum) => { if (isVertical) { return { scalingCenterY: datum.scaledValues.medianValue }; } return { scalingCenterX: datum.scaledValues.medianValue }; }; } var import_ag_charts_community148 = (init_main4(), __toCommonJS(main_exports)); var { ScalableGroup: ScalableGroup2, Rect: Rect3, Line: Line4, BBox: BBox9, Selection: Selection3 } = import_ag_charts_community148._ModuleSupport; var BoxPlotGroup = class extends ScalableGroup2 { constructor() { super(); this.append([ new Rect3({ tag: 0 /* Box */ }), new Rect3({ tag: 0 /* Box */ }), new Rect3({ tag: 2 /* Outline */ }), new Rect3({ tag: 1 /* Median */ }), new Line4({ tag: 3 /* Whisker */ }), new Line4({ tag: 3 /* Whisker */ }), new Line4({ tag: 4 /* Cap */ }), new Line4({ tag: 4 /* Cap */ }) ]); } updateDatumStyles(datum, activeStyles, isVertical, isReversedValueAxis) { const { bandwidth, scaledValues: { xValue: axisValue, medianValue } } = datum; let { minValue, q1Value, q3Value, maxValue } = datum.scaledValues; if (isVertical && !isReversedValueAxis || !isVertical && isReversedValueAxis) { [maxValue, q3Value, q1Value, minValue] = [minValue, q1Value, q3Value, maxValue]; } const position = (x, y, width2, height2) => isVertical ? { y: x, x: y, width: height2, height: width2 } : { x, y, width: width2, height: height2 }; const hPosition = (x1, x2, y) => isVertical ? { y1: x1, y2: x2, x: y } : { x1, x2, y }; const vPosition = (x, y1, y2) => isVertical ? { x1: y1, x2: y2, y: x } : { x, y1, y2 }; const bbox = (x, y, width2, height2) => { ({ x, y, width: width2, height: height2 } = position(x, y, width2, height2)); return new BBox9(x, y, width2, height2); }; const { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius, cap, whisker: whiskerStyles } = activeStyles; const selection = Selection3.select(this, Rect3); const boxes = selection.selectByTag( 0 /* Box */ ); const [outline] = selection.selectByTag( 2 /* Outline */ ); const [median] = selection.selectByTag( 1 /* Median */ ); const whiskers = selection.selectByTag( 3 /* Whisker */ ); const caps = selection.selectByTag( 4 /* Cap */ ); if (whiskerStyles.strokeWidth > bandwidth) { whiskerStyles.strokeWidth = bandwidth; } const boxesPosition = position(q1Value, axisValue, q3Value - q1Value, bandwidth); outline.setProperties(boxesPosition); boxes[0].setProperties(boxesPosition); boxes[0].setProperties({ cornerRadius, clipBBox: bbox(q1Value, axisValue, Math.round(medianValue - q1Value + strokeWidth / 2), bandwidth) }); boxes[1].setProperties(boxesPosition); boxes[1].setProperties({ cornerRadius, clipBBox: bbox( Math.round(medianValue - strokeWidth / 2), axisValue, Math.floor(q3Value - medianValue + strokeWidth / 2), bandwidth ) }); const medianStart = Math.max(Math.round(medianValue - strokeWidth / 2), q1Value + strokeWidth); const medianEnd = Math.min(Math.round(medianValue + strokeWidth / 2), q3Value - strokeWidth); median.setProperties(boxesPosition); median.setProperties({ visible: medianStart < medianEnd, cornerRadius, clipBBox: bbox( medianStart, axisValue + strokeWidth, medianEnd - medianStart, Math.max(0, bandwidth - strokeWidth * 2) ) }); const capStart = Math.floor(axisValue + bandwidth * (1 - cap.lengthRatio) / 2); const capEnd = Math.ceil(axisValue + bandwidth * (1 + cap.lengthRatio) / 2); caps[0].setProperties(vPosition(minValue, capStart, capEnd)); caps[1].setProperties(vPosition(maxValue, capStart, capEnd)); whiskers[0].setProperties( hPosition( Math.round(minValue + whiskerStyles.strokeWidth / 2), q1Value, Math.floor(axisValue + bandwidth / 2) ) ); whiskers[1].setProperties( hPosition( q3Value, Math.round(maxValue - whiskerStyles.strokeWidth / 2), Math.floor(axisValue + bandwidth / 2) ) ); for (const element2 of boxes) { element2.setProperties({ fill, fillOpacity, strokeWidth: strokeWidth * 2, strokeOpacity: 0 }); } median.setProperties({ fill: stroke22, fillOpacity: strokeOpacity, strokeWidth: 0 }); for (const element2 of [...whiskers, ...caps]) { element2.setProperties(whiskerStyles); } outline.setProperties({ stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius, fillOpacity: 0 }); } distanceSquared(x, y) { const nodes = Selection3.selectByClass(this, Rect3, Line4); return import_ag_charts_community148._ModuleSupport.nearestSquared(x, y, nodes).distanceSquared; } get midPoint() { const datum = this.datum; if (datum.midPoint === void 0) { logger_exports2.error("BoxPlotGroup.datum.midPoint is undefined"); return { x: NaN, y: NaN }; } return datum.midPoint; } }; var import_ag_charts_community149 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties19, AbstractBarSeriesProperties: AbstractBarSeriesProperties2, SeriesTooltip: SeriesTooltip2, Validate: Validate54, COLOR_STRING: COLOR_STRING9, FUNCTION: FUNCTION6, LINE_DASH: LINE_DASH5, OBJECT: OBJECT23, POSITIVE_NUMBER: POSITIVE_NUMBER15, RATIO: RATIO12, STRING: STRING24, mergeDefaults: mergeDefaults3 } = import_ag_charts_community149._ModuleSupport; var BoxPlotSeriesCap = class extends BaseProperties19 { constructor() { super(...arguments); this.lengthRatio = 0.5; } }; __decorateClass2([ Validate54(RATIO12) ], BoxPlotSeriesCap.prototype, "lengthRatio", 2); var BoxPlotSeriesWhisker = class extends BaseProperties19 { }; __decorateClass2([ Validate54(COLOR_STRING9, { optional: true }) ], BoxPlotSeriesWhisker.prototype, "stroke", 2); __decorateClass2([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesWhisker.prototype, "strokeWidth", 2); __decorateClass2([ Validate54(RATIO12) ], BoxPlotSeriesWhisker.prototype, "strokeOpacity", 2); __decorateClass2([ Validate54(LINE_DASH5, { optional: true }) ], BoxPlotSeriesWhisker.prototype, "lineDash", 2); __decorateClass2([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesWhisker.prototype, "lineDashOffset", 2); var BoxPlotSeriesProperties = class extends AbstractBarSeriesProperties2 { constructor() { super(...arguments); this.fill = "#c16068"; this.fillOpacity = 1; this.stroke = "#333"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.cap = new BoxPlotSeriesCap(); this.whisker = new BoxPlotSeriesWhisker(); this.tooltip = new SeriesTooltip2(); this.backgroundFill = "white"; } toJson() { const { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this; const properties = super.toJson(); properties.whisker = mergeDefaults3(properties.whisker, { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset }); return properties; } }; __decorateClass2([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "xKey", 2); __decorateClass2([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "minKey", 2); __decorateClass2([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "q1Key", 2); __decorateClass2([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "medianKey", 2); __decorateClass2([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "q3Key", 2); __decorateClass2([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "maxKey", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "xName", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "yName", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "minName", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "q1Name", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "medianName", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "q3Name", 2); __decorateClass2([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "maxName", 2); __decorateClass2([ Validate54(COLOR_STRING9, { optional: true }) ], BoxPlotSeriesProperties.prototype, "fill", 2); __decorateClass2([ Validate54(RATIO12) ], BoxPlotSeriesProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate54(COLOR_STRING9) ], BoxPlotSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate54(RATIO12) ], BoxPlotSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate54(LINE_DASH5) ], BoxPlotSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate54(FUNCTION6, { optional: true }) ], BoxPlotSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate54(OBJECT23) ], BoxPlotSeriesProperties.prototype, "cap", 2); __decorateClass2([ Validate54(OBJECT23) ], BoxPlotSeriesProperties.prototype, "whisker", 2); __decorateClass2([ Validate54(OBJECT23) ], BoxPlotSeriesProperties.prototype, "tooltip", 2); __decorateClass2([ Validate54(COLOR_STRING9) ], BoxPlotSeriesProperties.prototype, "backgroundFill", 2); var { extractDecoratedProperties: extractDecoratedProperties2, fixNumericExtent: fixNumericExtent22, keyProperty: keyProperty22, mergeDefaults: mergeDefaults4, SeriesNodePickMode: SeriesNodePickMode2, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL2, valueProperty: valueProperty4, diff: diff2, animationValidation: animationValidation2, computeBarFocusBounds: computeBarFocusBounds2, createDatumId: createDatumId2, Color: Color6, ContinuousScale: ContinuousScale3, ChartAxisDirection: ChartAxisDirection18, motion: motion2 } = import_ag_charts_community150._ModuleSupport; var BoxPlotSeriesNodeEvent = class extends import_ag_charts_community150._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.xKey = series.properties.xKey; this.minKey = series.properties.minKey; this.q1Key = series.properties.q1Key; this.medianKey = series.properties.medianKey; this.q3Key = series.properties.q3Key; this.maxKey = series.properties.maxKey; } }; var BoxPlotSeries = class extends import_ag_charts_community150._ModuleSupport.AbstractBarSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [SeriesNodePickMode2.NEAREST_NODE, SeriesNodePickMode2.EXACT_SHAPE_MATCH], directionKeys: { x: ["xKey"], y: ["medianKey", "q1Key", "q3Key", "minKey", "maxKey"] }, directionNames: { x: ["xName"], y: ["medianName", "q1Name", "q3Name", "minName", "maxName"] }, pathsPerSeries: [], hasHighlightedLabels: true }); this.properties = new BoxPlotSeriesProperties(); this.NodeEvent = BoxPlotSeriesNodeEvent; } async processData(dataController) { if (!this.properties.isValid() || !this.visible) return; const { xKey, minKey, q1Key, medianKey, q3Key, maxKey } = this.properties; const animationEnabled = !this.ctx.animationManager.isSkipped(); const xScale = this.getCategoryAxis()?.scale; const yScale = this.getValueAxis()?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const extraProps = []; if (animationEnabled && this.processedData) { extraProps.push(diff2(this.id, this.processedData)); } if (animationEnabled) { extraProps.push(animationValidation2()); } const { processedData } = await this.requestDataModel(dataController, this.data, { props: [ keyProperty22(xKey, xScaleType, { id: `xValue` }), valueProperty4(minKey, yScaleType, { id: `minValue` }), valueProperty4(q1Key, yScaleType, { id: `q1Value` }), valueProperty4(medianKey, yScaleType, { id: `medianValue` }), valueProperty4(q3Key, yScaleType, { id: `q3Value` }), valueProperty4(maxKey, yScaleType, { id: `maxValue` }), ...isContinuousX ? [SMALLEST_KEY_INTERVAL2] : [], ...extraProps ] }); this.smallestDataInterval = processedData.reduced?.smallestKeyInterval; this.animationState.transition("updateData"); } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (!(processedData && dataModel)) return []; if (direction !== this.getBarDirection()) { const { index, def } = dataModel.resolveProcessedDataDefById(this, `xValue`); const keys = processedData.domain.keys[index]; if (def.type === "key" && def.valueType === "category") { return keys; } return this.padBandExtent(keys); } const yExtent = this.domainForClippedRange(ChartAxisDirection18.Y, ["minValue", "maxValue"], "xValue", true); return fixNumericExtent22(yExtent); } getSeriesRange(_direction, visibleRange) { return this.domainForVisibleRange(ChartAxisDirection18.Y, ["maxValue", "minValue"], "xValue", visibleRange, true); } createNodeData() { const { visible, dataModel, processedData } = this; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!(dataModel && processedData && xAxis && yAxis)) return; const { xKey, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cap, whisker } = this.properties; const nodeData = []; const xValues = dataModel.resolveKeysById(this, "xValue", processedData); const minValues = dataModel.resolveColumnById(this, "minValue", processedData); const q1Values = dataModel.resolveColumnById(this, "q1Value", processedData); const medianValues = dataModel.resolveColumnById(this, "medianValue", processedData); const q3Values = dataModel.resolveColumnById(this, "q3Value", processedData); const maxValues = dataModel.resolveColumnById(this, "maxValue", processedData); const { barWidth, groupIndex } = this.updateGroupScale(xAxis); const barOffset = ContinuousScale3.is(xAxis.scale) ? barWidth * -0.5 : 0; const { groupScale } = this; const isVertical = this.isVertical(); const context = { itemId: xKey, nodeData, labelData: [], scales: this.calculateScaling(), visible: this.visible }; if (!visible) return context; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const xValue = xValues[datumIndex]; if (xValue == null) return; const minValue = minValues[datumIndex]; const q1Value = q1Values[datumIndex]; const medianValue = medianValues[datumIndex]; const q3Value = q3Values[datumIndex]; const maxValue = maxValues[datumIndex]; if ([minValue, q1Value, medianValue, q3Value, maxValue].some((value) => typeof value !== "number") || minValue > q1Value || q1Value > medianValue || medianValue > q3Value || q3Value > maxValue) { return; } const scaledValues = { xValue: Math.round(xAxis.scale.convert(xValue)), minValue: Math.round(yAxis.scale.convert(minValue)), q1Value: Math.round(yAxis.scale.convert(q1Value)), medianValue: Math.round(yAxis.scale.convert(medianValue)), q3Value: Math.round(yAxis.scale.convert(q3Value)), maxValue: Math.round(yAxis.scale.convert(maxValue)) }; scaledValues.xValue += Math.round(groupScale.convert(String(groupIndex))) + barOffset; const bandwidth = Math.round(barWidth); const height2 = Math.abs(scaledValues.q3Value - scaledValues.q1Value); const midX = scaledValues.xValue + bandwidth / 2; const midY = Math.min(scaledValues.q3Value, scaledValues.q1Value) + height2 / 2; const midPoint = { x: isVertical ? midX : midY, y: isVertical ? midY : midX }; let focusRect; if (isVertical) { focusRect = { x: midPoint.x - bandwidth / 2, y: scaledValues.minValue, width: bandwidth, height: scaledValues.maxValue - scaledValues.minValue }; } else { focusRect = { x: scaledValues.minValue, y: midPoint.y - bandwidth / 2, width: scaledValues.maxValue - scaledValues.minValue, height: bandwidth }; } nodeData.push({ series: this, itemId: xValue, datum, datumIndex, xKey, bandwidth, scaledValues, cap, whisker, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, midPoint, focusRect }); }); return context; } legendItemSymbol() { const { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { marker: { fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { const { id: seriesId, ctx: { legendManager }, visible } = this; const { xKey, yName, showInLegend, legendItemName } = this.properties; if (!xKey || legendType !== "category") { return []; } return [ { legendType: "category", id: seriesId, itemId: seriesId, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: seriesId }), label: { text: legendItemName ?? yName ?? seriesId }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend } ]; } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { xKey, xName, yName, medianKey, medianName, q1Key, q1Name, q3Key, q3Name, minKey, minName, maxKey, maxName, legendItemName, tooltip } = properties; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const minValue = dataModel.resolveColumnById(this, `minValue`, processedData)[datumIndex]; const q1Value = dataModel.resolveColumnById(this, `q1Value`, processedData)[datumIndex]; const medianValue = dataModel.resolveColumnById(this, `medianValue`, processedData)[datumIndex]; const q3Value = dataModel.resolveColumnById(this, `q3Value`, processedData)[datumIndex]; const maxValue = dataModel.resolveColumnById(this, `maxValue`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datum, format, false)); return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), title: legendItemName ?? yName, symbol: this.legendItemSymbol(), data: [ { label: minName, fallbackLabel: minKey, value: yAxis.formatDatum(minValue) }, { label: q1Name, fallbackLabel: q1Key, value: yAxis.formatDatum(q1Value) }, { label: medianName, fallbackLabel: medianKey, value: yAxis.formatDatum(medianValue) }, { label: q3Name, fallbackLabel: q3Key, value: yAxis.formatDatum(q3Value) }, { label: maxName, fallbackLabel: maxKey, value: yAxis.formatDatum(maxValue) } ] }, { seriesId, datum, title: yName, xKey, xName, yName, medianKey, medianName, q1Key, q1Name, q3Key, q3Name, minKey, minName, maxKey, maxName, ...format } ); } animateEmptyUpdateReady({ datumSelection }) { const isVertical = this.isVertical(); const { from: from3, to } = prepareBoxPlotFromTo(isVertical); motion2.resetMotion([datumSelection], resetBoxPlotSelectionsScalingCenterFn(isVertical)); motion2.staticFromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], from3, to, { phase: "initial" }); } isLabelEnabled() { return false; } updateDatumSelection(opts) { const data = opts.nodeData ?? []; return opts.datumSelection.update(data); } getItemBaseStyle(highlighted) { const { properties } = this; const { cornerRadius, cap, whisker } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; const strokeWidth = this.getStrokeWidth(properties.strokeWidth); return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash ?? [], lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset, cornerRadius, cap, whisker }; } getItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, minKey, q1Key, medianKey, q3Key, maxKey, itemStyler } = properties; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId2(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, xKey, minKey, q1Key, medianKey, q3Key, maxKey, highlighted, ...format }); }); } updateDatumNodes({ datumSelection, isHighlight: highlighted }) { const isVertical = this.isVertical(); const isReversedValueAxis = this.getValueAxis()?.isReversed(); datumSelection.each((boxPlotGroup, nodeDatum) => { let activeStyles = this.getFormattedStyles(nodeDatum, highlighted ? "highlight" : "node"); if (highlighted) { activeStyles = mergeDefaults4(this.properties.highlightStyle.item, activeStyles); } const { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = activeStyles; activeStyles.whisker = mergeDefaults4(activeStyles.whisker, { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset }); boxPlotGroup.updateDatumStyles( nodeDatum, activeStyles, isVertical, isReversedValueAxis ); }); } updateLabelNodes() { } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; return labelSelection.update(labelData); } nodeFactory() { return new BoxPlotGroup(); } getFormattedStyles(nodeDatum, scope) { const { id: seriesId, properties } = this; const { xKey, minKey, q1Key, medianKey, q3Key, maxKey, itemStyler, backgroundFill, cornerRadius } = properties; const { datum, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cap, whisker } = nodeDatum; let fill; let fillOpacity; const useFakeFill = true; if (useFakeFill) { fill = nodeDatum.fill; fillOpacity = properties.fillOpacity; } else { try { fill = Color6.mix( Color6.fromString(backgroundFill), Color6.fromString(nodeDatum.fill), properties.fillOpacity ).toString(); } catch { fill = nodeDatum.fill; } fillOpacity = void 0; } const activeStyles = { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius, cap: extractDecoratedProperties2(cap), whisker: extractDecoratedProperties2(whisker) }; if (itemStyler) { const formatStyles = this.cachedDatumCallback( createDatumId2(datum.index, scope), () => itemStyler({ datum, seriesId, highlighted: scope === "highlight", ...activeStyles, xKey, minKey, q1Key, medianKey, q3Key, maxKey }) ); if (formatStyles) { return mergeDefaults4(formatStyles, activeStyles); } } return activeStyles; } computeFocusBounds({ datumIndex }) { return computeBarFocusBounds2(this, this.contextNodeData?.nodeData[datumIndex].focusRect); } }; BoxPlotSeries.className = "BoxPlotSeries"; BoxPlotSeries.type = "box-plot"; var import_ag_charts_community151 = (init_main4(), __toCommonJS(main_exports)); var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE2 } = import_ag_charts_community151._ModuleSupport.ThemeConstants; var BOX_PLOT_SERIES_THEME = { series: { direction: "vertical", // @todo(AG-11876) Use fillOpacity to match area, range area, radar area, chord, and sankey series // fillOpacity: 0.3, strokeWidth: 2 }, axes: { [CARTESIAN_AXIS_TYPE2.NUMBER]: { crosshair: { snap: false } }, [CARTESIAN_AXIS_TYPE2.CATEGORY]: { groupPaddingInner: 0.2, crosshair: { enabled: false, snap: false } } } }; var { Color: Color7, swapAxisCondition: swapAxisCondition2, ThemeSymbols: { DEFAULT_BACKGROUND_COLOUR: DEFAULT_BACKGROUND_COLOUR2 }, ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE22, CARTESIAN_POSITION: CARTESIAN_POSITION2 } } = import_ag_charts_community152._ModuleSupport; var BoxPlotModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "box-plot", moduleFactory: (ctx) => new BoxPlotSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: swapAxisCondition2( [ { type: CARTESIAN_AXIS_TYPE22.NUMBER, position: CARTESIAN_POSITION2.LEFT }, { type: CARTESIAN_AXIS_TYPE22.CATEGORY, position: CARTESIAN_POSITION2.BOTTOM } ], (series) => series?.direction === "horizontal" ), themeTemplate: BOX_PLOT_SERIES_THEME, groupable: true, paletteFactory: ({ takeColors, themeTemplateParameters }) => { const themeBackgroundColor = themeTemplateParameters.get(DEFAULT_BACKGROUND_COLOUR2); const backgroundFill = (Array.isArray(themeBackgroundColor) ? themeBackgroundColor[0] : themeBackgroundColor) ?? "white"; const { fills: [fill], strokes: [stroke22] } = takeColors(1); let fakeFill; try { fakeFill = Color7.mix(Color7.fromString(backgroundFill), Color7.fromString(fill), 0.3).toString(); } catch { fakeFill = fill; } return { fill: fakeFill, stroke: stroke22, backgroundFill }; } }; var import_ag_charts_community160 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community158 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community153 = (init_main4(), __toCommonJS(main_exports)); var AGGREGATION_THRESHOLD2 = 1e3; var OPEN = X_MIN2; var HIGH = Y_MAX2; var LOW = Y_MIN2; var CLOSE = X_MAX2; function aggregateOhlcData(xValues, highValues, lowValues, domain) { if (xValues.length < AGGREGATION_THRESHOLD2) return; const [d0, d1] = aggregationDomain(domain); let maxRange = maxRangeFittingPoints(xValues); let { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, maxRange); const filters = [{ maxRange, indexData }]; while (maxRange > 64) { ({ indexData, valueData, maxRange } = compactAggregationIndices(indexData, valueData, maxRange)); filters.push({ maxRange, indexData }); } filters.reverse(); return filters; } var { fixNumericExtent: fixNumericExtent3, keyProperty: keyProperty3, createDatumId: createDatumId22, SeriesNodePickMode: SeriesNodePickMode22, ChartAxisDirection: ChartAxisDirection19, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL22, valueProperty: valueProperty5, diff: diff22, animationValidation: animationValidation22, computeBarFocusBounds: computeBarFocusBounds22, visibleRangeIndices: visibleRangeIndices2, ContinuousScale: ContinuousScale4, OrdinalTimeScale: OrdinalTimeScale3, BandScale: BandScale22 } = import_ag_charts_community153._ModuleSupport; var OhlcSeriesNodeEvent = class extends import_ag_charts_community153._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.xKey = series.properties.xKey; this.openKey = series.properties.openKey; this.closeKey = series.properties.closeKey; this.highKey = series.properties.highKey; this.lowKey = series.properties.lowKey; } }; var OhlcSeriesBase = class extends import_ag_charts_community153._ModuleSupport.AbstractBarSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [SeriesNodePickMode22.AXIS_ALIGNED, SeriesNodePickMode22.EXACT_SHAPE_MATCH], directionKeys: { x: ["xKey"], y: ["lowKey", "highKey", "openKey", "closeKey"] }, directionNames: { x: ["xName"], y: ["lowName", "highName", "openName", "closeName"] }, pathsPerSeries: [] }); this.NodeEvent = OhlcSeriesNodeEvent; this.dataAggregationFilters = void 0; } async processData(dataController) { if (!this.properties.isValid() || !this.visible) return; const { xKey, openKey, closeKey, highKey, lowKey } = this.properties; const animationEnabled = !this.ctx.animationManager.isSkipped(); const xScale = this.getCategoryAxis()?.scale; const yScale = this.getValueAxis()?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const extraProps = []; if (animationEnabled) { if (this.processedData) { extraProps.push(diff22(this.id, this.processedData)); } extraProps.push(animationValidation22()); } if (openKey) { extraProps.push( valueProperty5(openKey, yScaleType, { id: `openValue`, invalidValue: void 0, missingValue: void 0 }) ); } const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, { props: [ keyProperty3(xKey, xScaleType, { id: `xValue` }), valueProperty5(closeKey, yScaleType, { id: `closeValue` }), valueProperty5(highKey, yScaleType, { id: `highValue` }), valueProperty5(lowKey, yScaleType, { id: `lowValue` }), ...isContinuousX ? [SMALLEST_KEY_INTERVAL22] : [], ...extraProps ] }); this.smallestDataInterval = processedData.reduced?.smallestKeyInterval; this.dataAggregationFilters = this.aggregateData( dataModel, processedData ); this.animationState.transition("updateData"); } aggregateData(dataModel, processedData) { const xAxis = this.axes[ChartAxisDirection19.X]; if (xAxis == null || !(ContinuousScale4.is(xAxis.scale) || OrdinalTimeScale3.is(xAxis.scale))) return; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const highValues = dataModel.resolveColumnById(this, `highValue`, processedData); const lowValues = dataModel.resolveColumnById(this, `lowValue`, processedData); const { index } = dataModel.resolveProcessedDataDefById(this, `xValue`); const domain = processedData.domain.keys[index]; return aggregateOhlcData(xValues, highValues, lowValues, domain); } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (!(processedData && dataModel)) return []; if (direction !== this.getBarDirection()) { const { index, def } = dataModel.resolveProcessedDataDefById(this, `xValue`); const keys = processedData.domain.keys[index]; if (def.type === "key" && def.valueType === "category") { return keys; } return this.padBandExtent(keys); } const yExtent = this.domainForClippedRange(ChartAxisDirection19.Y, ["highValue", "lowValue"], "xValue", true); return fixNumericExtent3(yExtent); } getSeriesRange(_direction, visibleRange) { return this.domainForVisibleRange( ChartAxisDirection19.Y, ["highValue", "lowValue"], "xValue", visibleRange, true ); } getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) { return this.countVisibleItems( "xValue", ["highValue", "lowValue"], xVisibleRange, yVisibleRange, minVisibleItems ); } createNodeData() { const { visible, dataModel, processedData } = this; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!(dataModel && processedData && xAxis && yAxis)) return; const nodeData = []; const { xKey, highKey, lowKey } = this.properties; const rawData = processedData.dataSources.get(this.id) ?? []; const xValues = dataModel.resolveKeysById(this, "xValue", processedData); const openValues = dataModel.resolveColumnById(this, "openValue", processedData); const closeValues = dataModel.resolveColumnById(this, "closeValue", processedData); const highValues = dataModel.resolveColumnById(this, "highValue", processedData); const lowValues = dataModel.resolveColumnById(this, "lowValue", processedData); const { groupScale } = this; const { barWidth, groupIndex } = this.updateGroupScale(xAxis); const groupOffset = groupScale.convert(String(groupIndex)); const effectiveBarWidth = barWidth >= 1 ? barWidth : groupScale.rawBandwidth; const applyWidthOffset = BandScale22.is(xAxis.scale); const context = { itemId: xKey, nodeData, labelData: [], scales: this.calculateScaling(), visible: this.visible }; if (!visible) return context; const handleDatum = (datumIndex, xValue, openValue, closeValue, highValue, lowValue, width2, crisp) => { const datum = rawData[datumIndex]; const xOffset = applyWidthOffset ? width2 / 2 : 0; const centerX = xAxis.scale.convert(xValue) + groupOffset + xOffset; const yOpen = yAxis.scale.convert(openValue); const yClose = yAxis.scale.convert(closeValue); const yHigh = yAxis.scale.convert(highValue); const yLow = yAxis.scale.convert(lowValue); const isRising = closeValue > openValue; const itemId = isRising ? "up" : "down"; const y = Math.min(yHigh, yLow); const height2 = Math.max(yHigh, yLow) - y; const midPoint = { x: centerX, y: y + height2 / 2 }; nodeData.push({ series: this, itemId, datum, datumIndex, xKey, xValue, openValue, closeValue, highValue, lowValue, midPoint, aggregatedValue: closeValue, isRising, centerX, width: width2, y, height: height2, yOpen, yClose, crisp }); }; const { dataAggregationFilters } = this; const xScale = xAxis.scale; const [r0, r1] = xScale.range; const range22 = r1 - r0; const xPosition = (index) => xScale.convert(xValues[index]) + groupOffset; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range22); if (dataAggregationFilter == null) { let [start2, end2] = visibleRangeIndices2(rawData.length, xAxis.range, (index) => { const x = xPosition(index); return [x, x + effectiveBarWidth]; }); if (processedData.input.count < 1e3) { start2 = 0; end2 = processedData.input.count; } for (let datumIndex = start2; datumIndex < end2; datumIndex += 1) { const xValue = xValues[datumIndex]; if (xValue == null) continue; const openValue = openValues[datumIndex]; const closeValue = closeValues[datumIndex]; const highValue = highValues[datumIndex]; const lowValue = lowValues[datumIndex]; const validLowValue = lowValue != null && lowValue <= openValue && lowValue <= closeValue; const validHighValue = highValue != null && highValue >= openValue && highValue >= closeValue; if (!validLowValue) { logger_exports2.warnOnce( `invalid low value for key [${lowKey}] in data element, low value cannot be higher than datum open or close values` ); continue; } if (!validHighValue) { logger_exports2.warnOnce( `invalid high value for key [${highKey}] in data element, high value cannot be lower than datum open or close values.` ); continue; } handleDatum(datumIndex, xValue, openValue, closeValue, highValue, lowValue, effectiveBarWidth, true); } } else { const { maxRange, indexData } = dataAggregationFilter; const [start2, end2] = visibleRangeIndices2(maxRange, xAxis.range, (index) => { const aggIndex = index * SPAN3; const openIndex = indexData[aggIndex + OPEN]; const closeIndex = indexData[aggIndex + CLOSE]; if (openIndex === -1) return; return [xPosition(openIndex), xPosition(closeIndex) + effectiveBarWidth]; }); for (let i = start2; i < end2; i += 1) { const aggIndex = i * SPAN3; const openIndex = indexData[aggIndex + OPEN]; const closeIndex = indexData[aggIndex + CLOSE]; const highIndex = indexData[aggIndex + HIGH]; const lowIndex = indexData[aggIndex + LOW]; if (openIndex === -1) continue; const midDatumIndex = (openIndex + closeIndex) / 2 | 0; const xValue = xValues[midDatumIndex]; if (xValue == null) continue; const openValue = openValues[openIndex]; const closeValue = closeValues[closeIndex]; const highValue = highValues[highIndex]; const lowValue = lowValues[lowIndex]; const width2 = Math.abs(xPosition(closeIndex) - xPosition(openIndex)) + effectiveBarWidth; handleDatum(midDatumIndex, xValue, openValue, closeValue, highValue, lowValue, width2, false); } } return context; } isVertical() { return true; } isLabelEnabled() { return false; } updateDatumSelection(opts) { const data = opts.nodeData ?? []; return opts.datumSelection.update(data); } updateLabelNodes(_opts) { } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; return labelSelection.update(labelData); } getItemBaseStyle(itemId, highlighted) { const { properties } = this; const item = properties.item[itemId]; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? item.fill, fillOpacity: highlightStyle?.fillOpacity ?? item.fillOpacity, stroke: highlightStyle?.stroke ?? item.stroke, strokeWidth: highlightStyle?.strokeWidth ?? item.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? item.strokeOpacity, lineDash: highlightStyle?.lineDash ?? item.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? item.lineDashOffset }; } getItemStyleOverrides(datumId, datum, itemId, format, highlighted) { const { id: seriesId, properties } = this; const { itemStyler } = properties; if (itemStyler == null) return; const { xKey, openKey, closeKey, highKey, lowKey } = properties; return this.cachedDatumCallback(createDatumId22(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, itemId, xKey, openKey, closeKey, highKey, lowKey, highlighted, ...format }); }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { xKey, xName, yName, openKey, openName, highKey, highName, lowKey, lowName, closeKey, closeName, legendItemName, tooltip } = properties; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const openValue = dataModel.resolveColumnById(this, `openValue`, processedData)[datumIndex]; const highValue = dataModel.resolveColumnById(this, `highValue`, processedData)[datumIndex]; const lowValue = dataModel.resolveColumnById(this, `lowValue`, processedData)[datumIndex]; const closeValue = dataModel.resolveColumnById(this, `closeValue`, processedData)[datumIndex]; if (xValue == null) return; const itemId = closeValue >= openValue ? "up" : "down"; const item = this.properties.item[itemId]; const format = this.getItemBaseStyle(itemId, false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datum, itemId, format, false)); return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), title: legendItemName, symbol: { marker: { fill: item.fill ?? item.stroke, fillOpacity: item.fillOpacity ?? item.strokeOpacity ?? 1, stroke: item.stroke, strokeWidth: item.strokeWidth ?? 1, strokeOpacity: item.strokeOpacity ?? 1, lineDash: item.lineDash ?? [0], lineDashOffset: item.lineDashOffset ?? 0 } }, data: [ { label: openName, fallbackLabel: openKey, value: yAxis.formatDatum(openValue) }, { label: highName, fallbackLabel: highKey, value: yAxis.formatDatum(highValue) }, { label: lowName, fallbackLabel: lowKey, value: yAxis.formatDatum(lowValue) }, { label: closeName, fallbackLabel: closeKey, value: yAxis.formatDatum(closeValue) } ] }, { seriesId, datum, title: yName, itemId, xKey, xName, yName, openKey, openName, highKey, highName, lowKey, lowName, closeKey, closeName, ...format } ); } getDatumId(datum) { return createDatumId22(datum.xValue); } computeFocusBounds(opts) { const nodeDatum = this.getNodeData()?.at(opts.datumIndex); if (nodeDatum == null) return; const { centerX, y, width: width2, height: height2 } = nodeDatum; const datum = { x: centerX - width2 / 2, y, width: width2, height: height2 }; return computeBarFocusBounds22(this, datum); } }; var import_ag_charts_community155 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community154 = (init_main4(), __toCommonJS(main_exports)); var { Path: Path7, ScenePathChangeDetection: ScenePathChangeDetection4, BBox: BBox10 } = import_ag_charts_community154._ModuleSupport; var OhlcBaseNode = class extends Path7 { constructor() { super(...arguments); this.centerX = 0; this.y = 0; this.width = 0; this.height = 0; this.yOpen = 0; this.yClose = 0; this.crisp = false; this.strokeAlignment = 0; } computeBBox() { const { centerX, y, width: width2, height: height2 } = this; return new BBox10(centerX - width2 / 2, y, width2, height2); } isPointInPath(x, y) { return this.getBBox().containsPoint(x, y); } distanceSquared(x, y) { return this.getBBox().distanceSquared(x, y); } get midPoint() { return { x: this.centerX, y: this.y + this.height / 2 }; } alignedCoordinates() { const { y, width: width2, height: height2, crisp, strokeAlignment } = this; let { centerX, yOpen, yClose } = this; let x0 = centerX - width2 / 2; let x1 = centerX + width2 / 2; let y0 = y; let y1 = y + height2; if (crisp && width2 > 1) { centerX = this.align(centerX); yOpen = this.align(yOpen); yClose = this.align(yClose); const halfWidth = this.align(width2 / 2); x0 = centerX - halfWidth; x1 = centerX + halfWidth; y0 = this.align(y); y1 = y0 + this.align(y0, height2); } const centerY = (y0 + y1) / 2; centerX += strokeAlignment; x0 += strokeAlignment; x1 += strokeAlignment; y0 -= strokeAlignment; y1 += strokeAlignment; yOpen += yOpen < centerY ? strokeAlignment : -strokeAlignment; yClose += yClose < centerY ? strokeAlignment : -strokeAlignment; return { centerX, x0, x1, y0, y1, yOpen, yClose }; } executeStroke(ctx, path) { const { width: width2, strokeWidth } = this; if (width2 < strokeWidth) { ctx.lineWidth = width2; } super.executeStroke(ctx, path); } }; __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "centerX", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "y", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "width", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "height", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "yOpen", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "yClose", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "crisp", 2); __decorateClass2([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "strokeAlignment", 2); var OhlcNode = class extends OhlcBaseNode { updatePath() { const { path } = this; const { centerX, x0, x1, y0, y1, yOpen, yClose } = this.alignedCoordinates(); path.clear(); path.moveTo(centerX, y0); path.lineTo(centerX, y1); if (Math.abs(x1 - x0) > 1) { path.moveTo(x0, yOpen); path.lineTo(centerX, yOpen); path.moveTo(centerX, yClose); path.lineTo(x1, yClose); } } }; var { ScenePathChangeDetection: ScenePathChangeDetection5, ExtendedPath2D: ExtendedPath2D3 } = import_ag_charts_community155._ModuleSupport; var CandlestickNode = class extends OhlcBaseNode { constructor() { super(...arguments); this.wickPath = new ExtendedPath2D3(); this.wickStroke = void 0; this.wickStrokeWidth = void 0; this.wickStrokeOpacity = void 0; } updatePath() { const { path, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, wickStroke, wickStrokeWidth, wickStrokeOpacity, wickLineDash, wickLineDashOffset, strokeAlignment } = this; const { centerX, x0, x1, y0, y1, yOpen, yClose } = this.alignedCoordinates(); this.path.clear(); this.wickPath.clear(); const needsWickPath = wickStroke != null && wickStroke !== stroke22 || wickStrokeWidth != null && wickStrokeWidth !== strokeWidth || wickStrokeOpacity != null && wickStrokeOpacity !== strokeOpacity || wickLineDash != null && wickLineDash !== lineDash || wickLineDashOffset != null && wickLineDashOffset !== lineDashOffset; const wickPath = needsWickPath ? this.wickPath : path; if (Math.abs(x1 - x0) <= 3) { wickPath.moveTo(centerX, y0); wickPath.lineTo(centerX, y1); return; } const boxTop = Math.min(yOpen, yClose); const boxBottom = Math.max(yOpen, yClose); wickPath.moveTo(centerX, y0); wickPath.lineTo(centerX, boxTop + strokeWidth / 2); wickPath.moveTo(centerX, y1); wickPath.lineTo(centerX, boxBottom - strokeWidth / 2); const boxStrokeAdjustment = strokeAlignment + strokeWidth / 2; const rectHeight = boxBottom - boxTop - 2 * boxStrokeAdjustment; if (rectHeight > 0) { path.rect( x0 + boxStrokeAdjustment, boxTop + boxStrokeAdjustment, x1 - x0 - 2 * boxStrokeAdjustment, rectHeight ); } else { const boxMid = (boxTop + boxBottom) / 2; path.moveTo(x0, boxMid); path.lineTo(x1, boxMid); } } drawPath(ctx) { super.drawPath(ctx); const { wickPath } = this; if (wickPath.isEmpty()) return; const { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, wickStroke = stroke22, wickStrokeWidth = strokeWidth, wickStrokeOpacity = strokeOpacity, wickLineDash = lineDash, wickLineDashOffset = lineDashOffset } = this; if (wickStrokeWidth === 0) return; ctx.globalAlpha *= wickStrokeOpacity; if (typeof wickStroke === "string") { ctx.strokeStyle = wickStroke; } ctx.lineWidth = wickStrokeWidth; if (wickLineDash != null) { ctx.setLineDash(wickLineDash); } ctx.lineDashOffset = wickLineDashOffset; ctx.stroke(wickPath.getPath2D()); } }; __decorateClass2([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickStroke", 2); __decorateClass2([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickStrokeWidth", 2); __decorateClass2([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickStrokeOpacity", 2); __decorateClass2([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickLineDash", 2); __decorateClass2([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickLineDashOffset", 2); var import_ag_charts_community157 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community156 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties20, Validate: Validate55, AbstractBarSeriesProperties: AbstractBarSeriesProperties22, SeriesTooltip: SeriesTooltip22, STRING: STRING25, COLOR_STRING: COLOR_STRING10, FUNCTION: FUNCTION7, LINE_DASH: LINE_DASH6, OBJECT: OBJECT24, POSITIVE_NUMBER: POSITIVE_NUMBER16, RATIO: RATIO13 } = import_ag_charts_community156._ModuleSupport; var OhlcSeriesItem = class extends BaseProperties20 { constructor() { super(...arguments); this.stroke = "#333"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate55(COLOR_STRING10) ], OhlcSeriesItem.prototype, "stroke", 2); __decorateClass2([ Validate55(POSITIVE_NUMBER16) ], OhlcSeriesItem.prototype, "strokeWidth", 2); __decorateClass2([ Validate55(RATIO13) ], OhlcSeriesItem.prototype, "strokeOpacity", 2); __decorateClass2([ Validate55(LINE_DASH6) ], OhlcSeriesItem.prototype, "lineDash", 2); __decorateClass2([ Validate55(POSITIVE_NUMBER16) ], OhlcSeriesItem.prototype, "lineDashOffset", 2); var OhlcSeriesItems = class extends BaseProperties20 { constructor() { super(...arguments); this.up = new OhlcSeriesItem(); this.down = new OhlcSeriesItem(); } }; __decorateClass2([ Validate55(OBJECT24) ], OhlcSeriesItems.prototype, "up", 2); __decorateClass2([ Validate55(OBJECT24) ], OhlcSeriesItems.prototype, "down", 2); var OhlcSeriesBaseProperties = class extends AbstractBarSeriesProperties22 { }; __decorateClass2([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "xKey", 2); __decorateClass2([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "openKey", 2); __decorateClass2([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "closeKey", 2); __decorateClass2([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "highKey", 2); __decorateClass2([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "lowKey", 2); __decorateClass2([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "xName", 2); __decorateClass2([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "yName", 2); __decorateClass2([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "openName", 2); __decorateClass2([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "closeName", 2); __decorateClass2([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "highName", 2); __decorateClass2([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "lowName", 2); var OhlcSeriesProperties = class extends OhlcSeriesBaseProperties { constructor() { super(...arguments); this.tooltip = new SeriesTooltip22(); this.item = new OhlcSeriesItems(); } }; __decorateClass2([ Validate55(OBJECT24) ], OhlcSeriesProperties.prototype, "tooltip", 2); __decorateClass2([ Validate55(OBJECT24) ], OhlcSeriesProperties.prototype, "item", 2); __decorateClass2([ Validate55(FUNCTION7, { optional: true }) ], OhlcSeriesProperties.prototype, "itemStyler", 2); var { BaseProperties: BaseProperties21, SeriesTooltip: SeriesTooltip3, Validate: Validate56, COLOR_STRING: COLOR_STRING11, FUNCTION: FUNCTION8, LINE_DASH: LINE_DASH7, OBJECT: OBJECT25, POSITIVE_NUMBER: POSITIVE_NUMBER17, RATIO: RATIO14 } = import_ag_charts_community157._ModuleSupport; var CandlestickSeriesWick = class extends BaseProperties21 { }; __decorateClass2([ Validate56(COLOR_STRING11, { optional: true }) ], CandlestickSeriesWick.prototype, "stroke", 2); __decorateClass2([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesWick.prototype, "strokeWidth", 2); __decorateClass2([ Validate56(RATIO14) ], CandlestickSeriesWick.prototype, "strokeOpacity", 2); __decorateClass2([ Validate56(LINE_DASH7, { optional: true }) ], CandlestickSeriesWick.prototype, "lineDash", 2); __decorateClass2([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesWick.prototype, "lineDashOffset", 2); var CandlestickSeriesItem = class extends BaseProperties21 { constructor() { super(...arguments); this.fill = "#c16068"; this.fillOpacity = 1; this.stroke = "#333"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.wick = new CandlestickSeriesWick(); } }; __decorateClass2([ Validate56(COLOR_STRING11, { optional: true }) ], CandlestickSeriesItem.prototype, "fill", 2); __decorateClass2([ Validate56(RATIO14) ], CandlestickSeriesItem.prototype, "fillOpacity", 2); __decorateClass2([ Validate56(COLOR_STRING11) ], CandlestickSeriesItem.prototype, "stroke", 2); __decorateClass2([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesItem.prototype, "strokeWidth", 2); __decorateClass2([ Validate56(RATIO14) ], CandlestickSeriesItem.prototype, "strokeOpacity", 2); __decorateClass2([ Validate56(LINE_DASH7) ], CandlestickSeriesItem.prototype, "lineDash", 2); __decorateClass2([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesItem.prototype, "lineDashOffset", 2); __decorateClass2([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesItem.prototype, "cornerRadius", 2); __decorateClass2([ Validate56(OBJECT25) ], CandlestickSeriesItem.prototype, "wick", 2); var CandlestickSeriesItems = class extends BaseProperties21 { constructor() { super(...arguments); this.up = new CandlestickSeriesItem(); this.down = new CandlestickSeriesItem(); } }; __decorateClass2([ Validate56(OBJECT25) ], CandlestickSeriesItems.prototype, "up", 2); __decorateClass2([ Validate56(OBJECT25) ], CandlestickSeriesItems.prototype, "down", 2); var CandlestickSeriesProperties = class extends OhlcSeriesBaseProperties { constructor() { super(...arguments); this.item = new CandlestickSeriesItems(); this.tooltip = new SeriesTooltip3(); } }; __decorateClass2([ Validate56(OBJECT25) ], CandlestickSeriesProperties.prototype, "item", 2); __decorateClass2([ Validate56(OBJECT25) ], CandlestickSeriesProperties.prototype, "tooltip", 2); __decorateClass2([ Validate56(FUNCTION8, { optional: true }) ], CandlestickSeriesProperties.prototype, "itemStyler", 2); var { createDatumId: createDatumId3 } = import_ag_charts_community158._ModuleSupport; var CandlestickSeries = class extends OhlcSeriesBase { constructor() { super(...arguments); this.properties = new CandlestickSeriesProperties(); } nodeFactory() { return new CandlestickNode(); } updateDatumNodes({ datumSelection, isHighlight }) { const { id: seriesId, properties } = this; const { xKey, highKey, lowKey, openKey, closeKey, item, itemStyler } = properties; const { up, down } = item; const { fill: upFill, fillOpacity: upFillOpacity, stroke: upStroke, strokeWidth: upStrokeWidth, strokeOpacity: upStrokeOpacity, lineDash: upLineDash, lineDashOffset: upLineDashOffset } = up; const { stroke: upWickStroke, strokeWidth: upWickStrokeWidth, strokeOpacity: upWickStrokeOpacity, lineDash: upWickLineDash, lineDashOffset: upWickLineDashOffset } = up.wick; const { fill: downFill, fillOpacity: downFillOpacity, stroke: downStroke, strokeWidth: downStrokeWidth, strokeOpacity: downStrokeOpacity, lineDash: downLineDash, lineDashOffset: downLineDashOffset } = down; const { stroke: downWickStroke, strokeWidth: downWickStrokeWidth, strokeOpacity: downWickStrokeOpacity, lineDash: downWickLineDash, lineDashOffset: downWickLineDashOffset } = down.wick; const highlightStyle = isHighlight ? properties.highlightStyle.item : void 0; datumSelection.each((node, datum) => { const { isRising, centerX, width: width2, y, height: height2, yOpen, yClose, crisp } = datum; let style; if (itemStyler != null) { const { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = isRising ? up : down; style = this.cachedDatumCallback( createDatumId3(this.getDatumId(datum), isHighlight ? "highlight" : "node"), () => itemStyler({ seriesId, itemId: datum.itemId, xKey, highKey, lowKey, openKey, closeKey, datum: datum.datum, fill, fillOpacity, strokeOpacity, stroke: stroke22, strokeWidth, lineDash, lineDashOffset, highlighted: isHighlight }) ); } node.centerX = centerX; node.width = width2; node.y = y; node.height = height2; node.yOpen = yOpen; node.yClose = yClose; node.crisp = crisp; node.fill = highlightStyle?.fill ?? style?.fill ?? (isRising ? upFill : downFill); node.fillOpacity = highlightStyle?.fillOpacity ?? style?.fillOpacity ?? (isRising ? upFillOpacity : downFillOpacity); node.stroke = highlightStyle?.stroke ?? style?.stroke ?? (isRising ? upStroke : downStroke); node.strokeWidth = highlightStyle?.strokeWidth ?? style?.strokeWidth ?? (isRising ? upStrokeWidth : downStrokeWidth); node.strokeOpacity = highlightStyle?.strokeOpacity ?? style?.strokeOpacity ?? (isRising ? upStrokeOpacity : downStrokeOpacity); node.lineDash = highlightStyle?.lineDash ?? style?.lineDash ?? (isRising ? upLineDash : downLineDash); node.lineDashOffset = highlightStyle?.lineDashOffset ?? style?.lineDashOffset ?? (isRising ? upLineDashOffset : downLineDashOffset); const styleWick = style?.wick; node.wickStroke = highlightStyle?.stroke ?? styleWick?.stroke ?? (isRising ? upWickStroke : downWickStroke); node.wickStrokeWidth = highlightStyle?.strokeWidth ?? styleWick?.strokeWidth ?? (isRising ? upWickStrokeWidth : downWickStrokeWidth); node.wickStrokeOpacity = highlightStyle?.strokeOpacity ?? styleWick?.strokeOpacity ?? (isRising ? upWickStrokeOpacity : downWickStrokeOpacity); node.wickLineDash = highlightStyle?.lineDash ?? styleWick?.lineDash ?? (isRising ? upWickLineDash : downWickLineDash); node.wickLineDashOffset = highlightStyle?.lineDashOffset ?? styleWick?.lineDashOffset ?? (isRising ? upWickLineDashOffset : downWickLineDashOffset); node.strokeAlignment = (style?.strokeWidth ?? (isRising ? upStrokeWidth : downStrokeWidth)) / 2; }); } legendItemSymbol() { const { up, down } = this.properties.item; const fill = new import_ag_charts_community158._ModuleSupport.LinearGradient( "rgb", [ { color: up.fill, offset: 0 }, { color: up.fill, offset: 0.5 }, { color: down.fill, offset: 0.5 } ], 90 ); const stroke22 = new import_ag_charts_community158._ModuleSupport.LinearGradient( "rgb", [ { color: up.stroke, offset: 0 }, { color: up.stroke, offset: 0.5 }, { color: down.stroke, offset: 0.5 } ], 90 ); return { marker: { fill, fillOpacity: up.fillOpacity, stroke: stroke22, strokeWidth: up.strokeWidth ?? 1, strokeOpacity: up.strokeOpacity ?? 1, lineDash: up.lineDash, lineDashOffset: up.lineDashOffset } }; } getLegendData(legendType) { const { id, data, visible, ctx: { legendManager } } = this; const { xKey, yName, showInLegend, legendItemName } = this.properties; if (!data?.length || !xKey || legendType !== "category") { return []; } return [ { legendType: "category", id, itemId: id, seriesId: id, enabled: visible && legendManager.getItemEnabled({ seriesId: id, itemId: id }), label: { text: legendItemName ?? yName ?? id }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend } ]; } }; CandlestickSeries.className = "CandleStickSeries"; CandlestickSeries.type = "candlestick"; var import_ag_charts_community159 = (init_main4(), __toCommonJS(main_exports)); var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE3 } = import_ag_charts_community159._ModuleSupport.ThemeConstants; var CANDLESTICK_SERIES_THEME = { series: { highlightStyle: { item: { strokeWidth: 3 } } }, animation: { enabled: false }, axes: { [CARTESIAN_AXIS_TYPE3.NUMBER]: { crosshair: { snap: false } }, [CARTESIAN_AXIS_TYPE3.ORDINAL_TIME]: { groupPaddingInner: 0, crosshair: { enabled: true } } } }; var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE4, CARTESIAN_POSITION: CARTESIAN_POSITION22 } = import_ag_charts_community160._ModuleSupport.ThemeConstants; var CandlestickModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "candlestick", moduleFactory: (ctx) => new CandlestickSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: CARTESIAN_AXIS_TYPE4.NUMBER, position: CARTESIAN_POSITION22.LEFT }, { type: CARTESIAN_AXIS_TYPE4.ORDINAL_TIME, position: CARTESIAN_POSITION22.BOTTOM } ], themeTemplate: CANDLESTICK_SERIES_THEME, groupable: false, paletteFactory: ({ takeColors, colorsCount, userPalette, palette }) => { if (userPalette === "user-indexed") { const { fills, strokes } = takeColors(colorsCount); return { item: { up: { fill: "transparent", stroke: strokes[0] }, down: { fill: fills[0], stroke: strokes[0] } } }; } return { item: { up: palette.up, down: palette.down } }; } }; var import_ag_charts_community165 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community164 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community161 = (init_main4(), __toCommonJS(main_exports)); function computeNodeGraph(nodes, links, includeCircularReferences) { if (!includeCircularReferences) { links = removeCircularLinks(links); } const nodeGraph = /* @__PURE__ */ new Map(); for (const datum of nodes) { nodeGraph.set(datum.id, { datum, linksBefore: [], linksAfter: [], maxPathLengthBefore: -1, maxPathLengthAfter: -1 }); } let maxPathLength = 0; nodeGraph.forEach((node, id) => { maxPathLength = Math.max( maxPathLength, computePathLength(nodeGraph, links, node, id, -1, []) + computePathLength(nodeGraph, links, node, id, 1, []) + 1 ); }); return { links, nodeGraph, maxPathLength }; } function findCircularLinks(links, link, into, stack) { const stackIndex = stack.indexOf(link); if (stackIndex !== -1) { for (let i = stackIndex; i < stack.length; i += 1) { into.add(stack[i]); } return; } stack.push(link); const { toNode } = link; for (const next of links) { if (next.fromNode === toNode) { findCircularLinks(links, next, into, stack); } } stack.pop(); } function removeCircularLinks(links) { const circularLinks = /* @__PURE__ */ new Set(); for (const link of links) { findCircularLinks(links, link, circularLinks, []); } if (circularLinks.size !== 0) { logger_exports2.warnOnce("Some links formed circular references. These will be removed from the output."); } return circularLinks.size === 0 ? links : links.filter((link) => !circularLinks.has(link)); } function computePathLength(nodeGraph, links, node, id, direction, stack) { if (stack.includes(id)) { return Infinity; } let maxPathLength = direction === -1 ? node.maxPathLengthBefore : node.maxPathLengthAfter; if (maxPathLength === -1) { maxPathLength = 0; const connectedLinks = direction === -1 ? node.linksBefore : node.linksAfter; for (const link of links) { const { fromNode, toNode } = link; const linkId = direction === -1 ? toNode.id : fromNode.id; const nextNodeId = direction === -1 ? fromNode.id : toNode.id; const nextNode = id === linkId ? nodeGraph.get(nextNodeId) : void 0; if (nextNode == null) continue; connectedLinks.push({ node: nextNode, link }); stack?.push(id); maxPathLength = Math.max( maxPathLength, computePathLength(nodeGraph, links, nextNode, nextNodeId, direction, stack) + 1 ); stack?.pop(); } if (direction === -1) { node.maxPathLengthBefore = maxPathLength; } else { node.maxPathLengthAfter = maxPathLength; } } return maxPathLength; } var { Series: Series2, DataController: DataController2, Validate: Validate57, ARRAY: ARRAY6, keyProperty: keyProperty4, valueProperty: valueProperty6, Selection: Selection4, Group: Group9, TransformableText: TransformableText2 } = import_ag_charts_community161._ModuleSupport; var FlowProportionSeriesNodeEvent = class extends import_ag_charts_community161._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); const { datumIndex } = datum; const nodeDatum = series.contextNodeData?.nodeData.find( (d) => d.datumIndex.type === datumIndex.type && d.datumIndex.index === datumIndex.index ); this.size = nodeDatum?.size; this.label = nodeDatum?.type === 1 ? nodeDatum?.label : void 0; } }; var FlowProportionSeries = class extends Series2 { constructor() { super(...arguments); this.NodeEvent = FlowProportionSeriesNodeEvent; this._chartNodes = void 0; this.nodeCount = 0; this.linkCount = 0; this.linksDataModel = void 0; this.linksProcessedData = void 0; this.nodesDataModel = void 0; this.nodesProcessedData = void 0; this.processedNodes = /* @__PURE__ */ new Map(); this.linkGroup = this.contentGroup.appendChild(new Group9({ name: "linkGroup" })); this.nodeGroup = this.contentGroup.appendChild(new Group9({ name: "nodeGroup" })); this.focusLinkGroup = this.highlightNode.appendChild(new Group9({ name: "linkGroup" })); this.focusNodeGroup = this.highlightNode.appendChild(new Group9({ name: "nodeGroup" })); this.highlightLinkGroup = this.highlightNode.appendChild(new Group9({ name: "linkGroup" })); this.highlightNodeGroup = this.highlightNode.appendChild(new Group9({ name: "nodeGroup" })); this.labelSelection = Selection4.select( this.labelGroup, TransformableText2 ); this.linkSelection = Selection4.select( this.linkGroup, () => this.linkFactory() ); this.nodeSelection = Selection4.select( this.nodeGroup, () => this.nodeFactory() ); this.focusLinkSelection = Selection4.select( this.focusLinkGroup, () => this.linkFactory() ); this.focusNodeSelection = Selection4.select( this.focusNodeGroup, () => this.nodeFactory() ); this.highlightLinkSelection = Selection4.select( this.highlightLinkGroup, () => this.linkFactory() ); this.highlightNodeSelection = Selection4.select( this.highlightNodeGroup, () => this.nodeFactory() ); } get nodes() { return this.properties.nodes ?? this._chartNodes; } setChartNodes(nodes) { this._chartNodes = nodes; if (this.nodes === nodes) { this.nodeDataRefresh = true; } } async processData(dataController) { const { data, nodes } = this; if (data == null || !this.properties.isValid()) { return; } const { fromKey, toKey, sizeKey, idKey, labelKey } = this.properties; const nodesDataController = new DataController2("standalone", dataController.suppressFieldDotNotation); const nodesDataModelPromise = nodes != null ? nodesDataController.request(this.id, nodes, { props: [ keyProperty4(idKey, void 0, { id: "idValue", includeProperty: false }), ...labelKey != null ? [valueProperty6(labelKey, void 0, { id: "labelValue", includeProperty: false })] : [] ], groupByKeys: true }) : null; const linksDataModelPromise = dataController.request(this.id, data, { props: [ valueProperty6(fromKey, void 0, { id: "fromValue", includeProperty: false }), valueProperty6(toKey, void 0, { id: "toValue", includeProperty: false }), ...sizeKey != null ? [valueProperty6(sizeKey, void 0, { id: "sizeValue", includeProperty: false, missingValue: 0 })] : [] ], groupByKeys: false }); if (nodes != null) { nodesDataController.execute(); } const [nodesDataModel, linksDataModel] = await Promise.all([nodesDataModelPromise, linksDataModelPromise]); this.nodesDataModel = nodesDataModel?.dataModel; this.nodesProcessedData = nodesDataModel?.processedData; this.linksDataModel = linksDataModel?.dataModel; this.linksProcessedData = linksDataModel?.processedData; const processedNodes = /* @__PURE__ */ new Map(); if (nodesDataModel == null) { const fromIdValues = linksDataModel.dataModel.resolveColumnById( this, "fromValue", linksDataModel.processedData ); const toIdValues = linksDataModel.dataModel.resolveColumnById( this, "toValue", linksDataModel.processedData ); const createImplicitNode = (id) => { const datumIndex = processedNodes.size; const label = id; return { series: this, itemId: void 0, datum: {}, // Must be a referential object for tooltips datumIndex: { type: 1, index: datumIndex }, type: 1, index: datumIndex, linksBefore: [], linksAfter: [], id, size: 0, label }; }; linksDataModel.processedData.dataSources.get(this.id)?.forEach((_datum, datumIndex) => { const fromId = fromIdValues[datumIndex]; const toId = toIdValues[datumIndex]; if (fromId == null || toId == null) return; if (!processedNodes.has(fromId)) { processedNodes.set(fromId, createImplicitNode(fromId)); } if (!processedNodes.has(toId)) { processedNodes.set(toId, createImplicitNode(toId)); } }); } else { const nodeIdValues = nodesDataModel.dataModel.resolveColumnById( this, "idValue", nodesDataModel.processedData ); const labelValues = labelKey != null ? nodesDataModel.dataModel.resolveColumnById( this, "labelValue", nodesDataModel.processedData ) : void 0; nodesDataModel.processedData.dataSources.get(this.id)?.forEach((datum, datumIndex) => { const id = nodeIdValues[datumIndex]; const label = labelValues?.[datumIndex]; processedNodes.set(id, { series: this, itemId: void 0, datum, datumIndex: { type: 1, index: datumIndex }, type: 1, index: datumIndex, linksBefore: [], linksAfter: [], id, size: 0, label }); }); } this.processedNodes = processedNodes; } getNodeGraph(createNode, createLink, { includeCircularReferences }) { const { linksDataModel, linksProcessedData } = this; if (linksDataModel == null || linksProcessedData == null) { const { links: links2, nodeGraph: nodeGraph2, maxPathLength: maxPathLength2 } = computeNodeGraph( (/* @__PURE__ */ new Map()).values(), [], includeCircularReferences ); this.nodeCount = 0; this.linkCount = 0; return { nodeGraph: nodeGraph2, links: links2, maxPathLength: maxPathLength2 }; } const { sizeKey } = this.properties; const fromIdValues = linksDataModel.resolveColumnById(this, "fromValue", linksProcessedData); const toIdValues = linksDataModel.resolveColumnById(this, "toValue", linksProcessedData); const sizeValues = sizeKey != null ? linksDataModel.resolveColumnById(this, "sizeValue", linksProcessedData) : void 0; const nodesById = /* @__PURE__ */ new Map(); this.processedNodes.forEach((datum) => { const node = createNode(datum); nodesById.set(datum.id, node); }); const baseLinks = []; linksProcessedData.dataSources.get(this.id)?.forEach((datum, datumIndex) => { const fromId = fromIdValues[datumIndex]; const toId = toIdValues[datumIndex]; const size = sizeValues != null ? sizeValues[datumIndex] : 1; const fromNode = nodesById.get(fromId); const toNode = nodesById.get(toId); if (size <= 0 || fromNode == null || toNode == null) return; const link = createLink({ series: this, itemId: void 0, datum, datumIndex: { type: 0, index: datumIndex }, type: 0, index: datumIndex, fromNode, toNode, size }); baseLinks.push(link); }); const { links, nodeGraph, maxPathLength } = computeNodeGraph( nodesById.values(), baseLinks, includeCircularReferences ); nodeGraph.forEach((node) => { node.datum.linksBefore = node.linksBefore.map((linkedNode) => linkedNode.link); node.datum.linksAfter = node.linksAfter.map((linkedNode) => linkedNode.link); }); this.nodeCount = nodeGraph.size; this.linkCount = links.length; return { nodeGraph, links, maxPathLength }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } update(opts) { const { seriesRect } = opts; const newNodeDataDependencies = { seriesRectWidth: seriesRect?.width ?? 0, seriesRectHeight: seriesRect?.height ?? 0 }; if (this._nodeDataDependencies == null || this._nodeDataDependencies.seriesRectWidth !== newNodeDataDependencies.seriesRectWidth || this._nodeDataDependencies.seriesRectHeight !== newNodeDataDependencies.seriesRectHeight) { this._nodeDataDependencies = newNodeDataDependencies; } this.updateSelections(); const nodeData = this.contextNodeData?.nodeData ?? []; const labelData = this.contextNodeData?.labelData ?? []; let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); if (highlightedDatum?.series === this && highlightedDatum.type == null) { const { itemId } = highlightedDatum; highlightedDatum = itemId != null ? nodeData.find((node) => node.type === 1 && node.id === itemId) : void 0; } else if (highlightedDatum?.series !== this) { highlightedDatum = void 0; } this.contentGroup.visible = this.visible; this.contentGroup.opacity = highlightedDatum != null ? this.properties.highlightStyle.series.dimOpacity ?? 1 : 1; this.labelSelection = this.updateLabelSelection({ labelData, labelSelection: this.labelSelection }); this.updateLabelNodes({ labelSelection: this.labelSelection }); this.linkSelection = this.updateLinkSelection({ nodeData: nodeData.filter( (d) => d.type === 0 /* Link */ ), datumSelection: this.linkSelection }); this.updateLinkNodes({ datumSelection: this.linkSelection, isHighlight: false }); this.nodeSelection = this.updateNodeSelection({ nodeData: nodeData.filter( (d) => d.type === 1 /* Node */ ), datumSelection: this.nodeSelection }); this.updateNodeNodes({ datumSelection: this.nodeSelection, isHighlight: false }); let focusLinkSelection; let focusNodeSelection; let highlightLinkSelection; let highlightNodeSelection; if (highlightedDatum?.type === 1) { focusLinkSelection = nodeData.filter((node) => { return node.type === 0 && (node.toNode === highlightedDatum || node.fromNode === highlightedDatum); }); focusNodeSelection = focusLinkSelection.map((link) => { return link.fromNode === highlightedDatum ? link.toNode : link.fromNode; }); focusNodeSelection.push(highlightedDatum); highlightLinkSelection = []; highlightNodeSelection = [highlightedDatum]; } else if (highlightedDatum?.type === 0) { focusLinkSelection = [highlightedDatum]; focusNodeSelection = [highlightedDatum.fromNode, highlightedDatum.toNode]; highlightLinkSelection = [highlightedDatum]; highlightNodeSelection = []; } else { focusLinkSelection = []; focusNodeSelection = []; highlightLinkSelection = []; highlightNodeSelection = []; } this.focusLinkSelection = this.updateLinkSelection({ nodeData: focusLinkSelection, datumSelection: this.focusLinkSelection }); this.updateLinkNodes({ datumSelection: this.focusLinkSelection, isHighlight: false }); this.focusNodeSelection = this.updateNodeSelection({ nodeData: focusNodeSelection, datumSelection: this.focusNodeSelection }); this.updateNodeNodes({ datumSelection: this.focusNodeSelection, isHighlight: false }); this.highlightLinkSelection = this.updateLinkSelection({ nodeData: highlightLinkSelection, datumSelection: this.highlightLinkSelection }); this.updateLinkNodes({ datumSelection: this.highlightLinkSelection, isHighlight: true }); this.highlightNodeSelection = this.updateNodeSelection({ nodeData: highlightNodeSelection, datumSelection: this.highlightNodeSelection }); this.updateNodeNodes({ datumSelection: this.highlightNodeSelection, isHighlight: true }); } resetAnimation(_chartAnimationPhase) { } getSeriesDomain(_direction) { return []; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } legendItemSymbol(_type, nodeIndex, format = {}) { const { fills, strokes } = this.properties; const { fill = fills[nodeIndex % fills.length], fillOpacity = 1, stroke: stroke22 = strokes[nodeIndex % strokes.length], strokeWidth = 0, strokeOpacity = 1, lineDash = [0], lineDashOffset = 0 } = format; return { marker: { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (legendType !== "category") return []; const { showInLegend } = this.properties; return Array.from( this.processedNodes.values(), ({ id, label }, nodeIndex) => ({ legendType: "category", id: this.id, itemId: id, seriesId: this.id, enabled: true, label: { text: label ?? id }, symbol: this.legendItemSymbol(1, nodeIndex), hideInLegend: !showInLegend, isFixed: true }) ); } pickNodeClosestDatum({ x, y }) { let minDistanceSquared = Infinity; let minDatum; this.linkSelection.each((node, datum) => { const distanceSquared2 = node.containsPoint(x, y) ? 0 : Infinity; if (distanceSquared2 < minDistanceSquared) { minDistanceSquared = distanceSquared2; minDatum = datum; } }); this.nodeSelection.each((node, datum) => { const distanceSquared2 = node.distanceSquared(x, y); if (distanceSquared2 < minDistanceSquared) { minDistanceSquared = distanceSquared2; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } getDatumAriaText(datum, description) { if (datum.type === 0) { return this.ctx.localeManager.t("ariaAnnounceFlowProportionLink", { index: datum.index + 1, count: this.linkCount, from: datum.fromNode.id, to: datum.toNode.id, size: datum.size, sizeName: this.properties.sizeName ?? this.properties.sizeKey }); } else if (datum.type === 1) { return this.ctx.localeManager.t("ariaAnnounceFlowProportionNode", { index: datum.index + 1, count: this.nodeCount, description }); } } pickFocus(opts) { const { datumIndexDelta: childDelta, otherIndexDelta: depthDelta } = opts; const currentNodeDatum = this.contextNodeData?.nodeData[opts.datumIndex - opts.datumIndexDelta]; let nextNodeDatum = currentNodeDatum; if (depthDelta !== 0 || childDelta === 0) return; if (currentNodeDatum?.type === 0) { const allLinks = Array.from(this.linkSelection, (link) => link.datum); const selfIndex = allLinks.indexOf(currentNodeDatum); const nextIndex = selfIndex + childDelta; if (nextIndex >= 0 && nextIndex < allLinks.length) { nextNodeDatum = allLinks[nextIndex]; } else if (nextIndex > 0) { nextNodeDatum = allLinks[allLinks.length - 1]; } else { const allNodes = Array.from(this.nodeSelection, (node) => node.datum); nextNodeDatum = allNodes[allNodes.length - 1]; } } else if (currentNodeDatum?.type === 1) { const allNodes = Array.from(this.nodeSelection, (node) => node.datum); const selfIndex = allNodes.indexOf(currentNodeDatum); const nextIndex = selfIndex + childDelta; if (nextIndex >= 0 && nextIndex < allNodes.length) { nextNodeDatum = allNodes[nextIndex]; } else if (nextIndex < 0) { nextNodeDatum = allNodes[0]; } else { const allLinks = Array.from(this.linkSelection, (link) => link.datum); nextNodeDatum = allLinks[0]; } } if (nextNodeDatum == null) return; const nodeDatum = nextNodeDatum.type === 1 ? Array.from(this.nodeSelection).find((n) => n.datum === nextNodeDatum) : Array.from(this.linkSelection).find((n) => n.datum === nextNodeDatum); if (nodeDatum == null) return; const bounds = this.computeFocusBounds(nodeDatum.node); if (bounds == null) return; return { datum: nodeDatum.datum, datumIndex: this.contextNodeData?.nodeData.indexOf(nodeDatum.datum) ?? 0, otherIndex: 0, bounds, clipFocusBox: true }; } }; __decorateClass2([ Validate57(ARRAY6, { optional: true, property: "nodes" }) ], FlowProportionSeries.prototype, "_chartNodes", 2); var import_ag_charts_community162 = (init_main4(), __toCommonJS(main_exports)); var { BBox: BBox11, Path: Path8, ScenePathChangeDetection: ScenePathChangeDetection6 } = import_ag_charts_community162._ModuleSupport; function bezierControlPoints({ radius, startAngle, endAngle, tension }) { const cp0x = radius * Math.cos(startAngle); const cp0y = radius * Math.sin(startAngle); const cp3x = radius * Math.cos(endAngle); const cp3y = radius * Math.sin(endAngle); const cp1x = cp0x * tension; const cp1y = cp0y * tension; const cp2x = cp3x * tension; const cp2y = cp3y * tension; return { x: [cp0x, cp1x, cp2x, cp3x], y: [cp0y, cp1y, cp2y, cp3y] }; } var ChordLink = class extends Path8 { constructor() { super(...arguments); this.centerX = 0; this.centerY = 0; this.radius = 0; this.startAngle1 = 0; this.endAngle1 = 0; this.startAngle2 = 0; this.endAngle2 = 0; this.tension = 1; } computeBBox() { const { centerX, centerY, radius, startAngle1, endAngle1, startAngle2, endAngle2, tension } = this; const outer = bezierControlPoints({ radius, startAngle: startAngle1, endAngle: endAngle2, tension }); const inner = bezierControlPoints({ radius, startAngle: startAngle2, endAngle: endAngle1, tension }); const x = Math.min(...outer.x, ...inner.x); const width2 = Math.max(...outer.x, ...inner.x) - x; const y = Math.min(...outer.y, ...inner.y); const height2 = Math.max(...outer.y, ...inner.y) - y; return new BBox11(centerX + x, centerY + y, width2, height2); } tensionedCurveTo(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y) { const { path, tension } = this; const scale2 = 1 - tension; path.cubicCurveTo( (cp1x - cp0x) * scale2 + cp0x, (cp1y - cp0y) * scale2 + cp0y, (cp2x - cp3x) * scale2 + cp3x, (cp2y - cp3y) * scale2 + cp3y, cp3x, cp3y ); } updatePath() { const { path, centerX, centerY, radius } = this; let { startAngle1, endAngle1, startAngle2, endAngle2 } = this; if (startAngle1 > startAngle2) { [startAngle1, startAngle2] = [startAngle2, startAngle1]; [endAngle1, endAngle2] = [endAngle2, endAngle1]; } path.clear(); const startX = centerX + radius * Math.cos(startAngle1); const startY = centerY + radius * Math.sin(startAngle1); path.moveTo(startX, startY); this.tensionedCurveTo( startX, startY, centerX, centerY, centerX, centerY, centerX + radius * Math.cos(endAngle2), centerY + radius * Math.sin(endAngle2) ); path.arc(centerX, centerY, radius, endAngle2, startAngle2, true); this.tensionedCurveTo( centerX + radius * Math.cos(startAngle2), centerY + radius * Math.sin(startAngle2), centerX, centerY, centerX, centerY, centerX + radius * Math.cos(endAngle1), centerY + radius * Math.sin(endAngle1) ); path.arc(centerX, centerY, radius, endAngle1, startAngle1, true); path.closePath(); } }; __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "centerX", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "centerY", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "radius", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "startAngle1", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "endAngle1", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "startAngle2", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "endAngle2", 2); __decorateClass2([ ScenePathChangeDetection6() ], ChordLink.prototype, "tension", 2); var import_ag_charts_community163 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties222, SeriesTooltip: SeriesTooltip4, SeriesProperties: SeriesProperties2, ARRAY: ARRAY7, COLOR_STRING: COLOR_STRING12, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY22, FUNCTION: FUNCTION9, LINE_DASH: LINE_DASH8, OBJECT: OBJECT26, POSITIVE_NUMBER: POSITIVE_NUMBER18, RATIO: RATIO15, STRING: STRING26, Validate: Validate58, Label: Label3 } = import_ag_charts_community163._ModuleSupport; var ChordSeriesLabelProperties = class extends Label3 { constructor() { super(...arguments); this.spacing = 1; this.maxWidth = 1; } }; __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLabelProperties.prototype, "spacing", 2); __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLabelProperties.prototype, "maxWidth", 2); var ChordSeriesLinkProperties = class extends BaseProperties222 { constructor() { super(...arguments); this.fill = void 0; this.fillOpacity = 1; this.stroke = void 0; this.strokeOpacity = 1; this.strokeWidth = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.tension = 0; } }; __decorateClass2([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesLinkProperties.prototype, "fill", 2); __decorateClass2([ Validate58(RATIO15) ], ChordSeriesLinkProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesLinkProperties.prototype, "stroke", 2); __decorateClass2([ Validate58(RATIO15) ], ChordSeriesLinkProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLinkProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate58(LINE_DASH8) ], ChordSeriesLinkProperties.prototype, "lineDash", 2); __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLinkProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate58(RATIO15) ], ChordSeriesLinkProperties.prototype, "tension", 2); __decorateClass2([ Validate58(FUNCTION9, { optional: true }) ], ChordSeriesLinkProperties.prototype, "itemStyler", 2); var ChordSeriesNodeProperties = class extends BaseProperties222 { constructor() { super(...arguments); this.spacing = 1; this.width = 1; this.fill = void 0; this.fillOpacity = 1; this.stroke = void 0; this.strokeOpacity = 1; this.strokeWidth = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "spacing", 2); __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "width", 2); __decorateClass2([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesNodeProperties.prototype, "fill", 2); __decorateClass2([ Validate58(RATIO15) ], ChordSeriesNodeProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesNodeProperties.prototype, "stroke", 2); __decorateClass2([ Validate58(RATIO15) ], ChordSeriesNodeProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate58(LINE_DASH8) ], ChordSeriesNodeProperties.prototype, "lineDash", 2); __decorateClass2([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate58(FUNCTION9, { optional: true }) ], ChordSeriesNodeProperties.prototype, "itemStyler", 2); var ChordSeriesProperties = class extends SeriesProperties2 { constructor() { super(...arguments); this.idKey = ""; this.idName = void 0; this.labelKey = void 0; this.labelName = void 0; this.sizeKey = void 0; this.sizeName = void 0; this.nodes = void 0; this.fills = []; this.strokes = []; this.label = new ChordSeriesLabelProperties(); this.link = new ChordSeriesLinkProperties(); this.node = new ChordSeriesNodeProperties(); this.tooltip = new SeriesTooltip4(); } }; __decorateClass2([ Validate58(STRING26) ], ChordSeriesProperties.prototype, "fromKey", 2); __decorateClass2([ Validate58(STRING26) ], ChordSeriesProperties.prototype, "toKey", 2); __decorateClass2([ Validate58(STRING26) ], ChordSeriesProperties.prototype, "idKey", 2); __decorateClass2([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "idName", 2); __decorateClass2([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "labelName", 2); __decorateClass2([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "sizeKey", 2); __decorateClass2([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "sizeName", 2); __decorateClass2([ Validate58(ARRAY7, { optional: true }) ], ChordSeriesProperties.prototype, "nodes", 2); __decorateClass2([ Validate58(COLOR_STRING_ARRAY22) ], ChordSeriesProperties.prototype, "fills", 2); __decorateClass2([ Validate58(COLOR_STRING_ARRAY22) ], ChordSeriesProperties.prototype, "strokes", 2); __decorateClass2([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "link", 2); __decorateClass2([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "node", 2); __decorateClass2([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "tooltip", 2); var { SeriesNodePickMode: SeriesNodePickMode3, CachedTextMeasurerPool: CachedTextMeasurerPool3, TextWrapper: TextWrapper4, TextUtils: TextUtils4, createDatumId: createDatumId4, angleBetween: angleBetween22, normalizeAngle360: normalizeAngle3605, isBetweenAngles: isBetweenAngles22, Sector: Sector3, evaluateBezier: evaluateBezier2, applyShapeStyle: applyShapeStyle2 } = import_ag_charts_community164._ModuleSupport; var nodeMidAngle = (node) => node.startAngle + angleBetween22(node.startAngle, node.endAngle) / 2; var ChordSeries = class extends FlowProportionSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [SeriesNodePickMode3.NEAREST_NODE, SeriesNodePickMode3.EXACT_SHAPE_MATCH] }); this.properties = new ChordSeriesProperties(); } isLabelEnabled() { return (this.properties.labelKey != null || this.nodes == null) && this.properties.label.enabled; } linkFactory() { return new ChordLink(); } nodeFactory() { return new Sector3(); } createNodeData() { const { id: seriesId, _nodeDataDependencies: { seriesRectWidth, seriesRectHeight } = { seriesRectWidth: 0, seriesRectHeight: 0 } } = this; const { fromKey, toKey, sizeKey, label: { spacing: labelSpacing, maxWidth: labelMaxWidth, fontSize }, node: { width: nodeWidth, spacing: nodeSpacing } } = this.properties; const centerX = seriesRectWidth / 2; const centerY = seriesRectHeight / 2; let labelData = []; const { nodeGraph, links } = this.getNodeGraph( (node) => ({ ...node, centerX, centerY, innerRadius: NaN, outerRadius: NaN, startAngle: NaN, endAngle: NaN }), (link) => ({ ...link, centerX, centerY, radius: NaN, startAngle1: NaN, endAngle1: NaN, startAngle2: NaN, endAngle2: NaN }), { includeCircularReferences: true } ); let totalSize = 0; nodeGraph.forEach(({ datum: node, linksBefore, linksAfter }, id) => { const size = linksBefore.reduce((acc, { link }) => acc + link.size, 0) + linksAfter.reduce((acc, { link }) => acc + link.size, 0); if (size === 0) { nodeGraph.delete(id); } else { node.size = size; totalSize += node.size; const label = this.getLabelText(this.properties.label, { datum: node.datum, value: node.label, fromKey, toKey, sizeKey, size: node.size }); node.label = String(label); } }); let labelInset = 0; if (this.isLabelEnabled()) { const canvasFont = this.properties.label.getFont(); let maxMeasuredLabelWidth = 0; nodeGraph.forEach(({ datum: node }) => { const { id, label } = node; if (label == null) return; const text22 = TextWrapper4.wrapText(label, { maxWidth: labelMaxWidth, font: this.properties.label, textWrap: "never" }); const { width: width2 } = CachedTextMeasurerPool3.measureText(text22, { font: canvasFont, textAlign: "left", textBaseline: "middle" }); maxMeasuredLabelWidth = Math.max(width2, maxMeasuredLabelWidth); labelData.push({ id, text: text22, centerX, centerY, angle: NaN, radius: NaN }); }); labelInset = maxMeasuredLabelWidth + labelSpacing; } const nodeCount = nodeGraph.size; let radius = Math.min(seriesRectWidth, seriesRectHeight) / 2 - nodeWidth - labelInset; let spacingSweep = nodeSpacing / radius; if (labelInset !== 0 && (nodeCount * spacingSweep >= 1.5 * Math.PI || radius <= 0)) { labelData = []; radius = Math.min(seriesRectWidth, seriesRectHeight) / 2 - nodeWidth; spacingSweep = nodeSpacing / radius; } if (nodeCount * spacingSweep >= 2 * Math.PI || radius <= 0) { logger_exports2.warnOnce("There was insufficient space to display the Chord Series."); return; } const innerRadius = radius; const outerRadius = radius + nodeWidth; const sizeScale = Math.max((2 * Math.PI - nodeCount * spacingSweep) / totalSize, 0); let nodeAngle = 0; nodeGraph.forEach(({ datum: node }) => { node.innerRadius = innerRadius; node.outerRadius = outerRadius; node.startAngle = nodeAngle; node.endAngle = nodeAngle + node.size * sizeScale; nodeAngle = node.endAngle + spacingSweep; const midR = (node.innerRadius + node.outerRadius) / 2; const midAngle = nodeMidAngle(node); node.midPoint = { x: node.centerX + midR * Math.cos(midAngle), y: node.centerY + midR * Math.sin(midAngle) }; }); const nodeData = []; nodeGraph.forEach(({ datum: node, linksBefore, linksAfter }) => { const midAngle = nodeMidAngle(node); const combinedLinks = [ ...linksBefore.map((l) => ({ link: l.link, distance: angleBetween22(nodeMidAngle(l.node.datum), midAngle), after: false })), ...linksAfter.map((l) => ({ link: l.link, distance: angleBetween22(nodeMidAngle(l.node.datum), midAngle), after: true })) ]; let linkAngle = node.startAngle; combinedLinks.toSorted((a, b) => a.distance - b.distance).forEach(({ link, after }) => { const linkSweep = link.size * sizeScale; if (after) { link.startAngle1 = linkAngle; link.endAngle1 = linkAngle + linkSweep; } else { link.startAngle2 = linkAngle; link.endAngle2 = linkAngle + linkSweep; } linkAngle += link.size * sizeScale; }); nodeData.push(node); }); const { tension } = this.properties.link; links.forEach((link) => { link.radius = radius; const outer = bezierControlPoints({ radius, startAngle: link.startAngle1, endAngle: link.endAngle2, tension }); const inner = bezierControlPoints({ radius, startAngle: link.startAngle2, endAngle: link.endAngle1, tension }); const outerX = evaluateBezier2(...outer.x, 0.5); const outerY = evaluateBezier2(...outer.y, 0.5); const innerX = evaluateBezier2(...inner.x, 0.5); const innerY = evaluateBezier2(...inner.y, 0.5); link.midPoint = { x: link.centerX + (outerX + innerX) / 2, y: link.centerY + (outerY + innerY) / 2 }; nodeData.push(link); }); labelData.forEach((label) => { const node = nodeGraph.get(label.id)?.datum; if (node == null) return; label.radius = outerRadius + labelSpacing; label.angle = normalizeAngle3605(node.startAngle + angleBetween22(node.startAngle, node.endAngle) / 2); }); labelData.sort((a, b) => a.angle - b.angle); let minAngle = Infinity; let maxAngle = -Infinity; labelData = labelData.filter((label) => { const labelHeight = TextUtils4.getLineHeight(fontSize); const da = Math.atan2(labelHeight / 2, label.radius); const a0 = label.angle - da; const a1 = label.angle + da; if (isBetweenAngles22(minAngle, a0, a1)) return false; if (isBetweenAngles22(maxAngle, a0, a1)) return false; minAngle = Math.min(a0, minAngle); maxAngle = Math.max(a1, maxAngle); return true; }); return { itemId: seriesId, nodeData, labelData }; } updateLabelSelection(opts) { const labels = this.isLabelEnabled() ? opts.labelData : []; return opts.labelSelection.update(labels); } updateLabelNodes(opts) { const { labelSelection } = opts; const { color: fill, fontStyle, fontWeight, fontSize, fontFamily } = this.properties.label; labelSelection.each((label, { text: text22, centerX, centerY, radius, angle: angle2 }) => { label.visible = true; label.translationX = centerX + radius * Math.cos(angle2); label.translationY = centerY + radius * Math.sin(angle2); label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textBaseline = "middle"; if (Math.cos(angle2) >= 0) { label.textAlign = "left"; label.rotation = angle2; } else { label.textAlign = "right"; label.rotation = angle2 - Math.PI; } }); } updateNodeSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId4([datum.type, datum.id])); } getBaseNodeStyle(highlighted) { const { properties } = this; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = properties.node; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? fill, fillOpacity: highlightStyle?.fillOpacity ?? fillOpacity, stroke: highlightStyle?.stroke ?? stroke22, strokeOpacity: highlightStyle?.strokeOpacity ?? strokeOpacity, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.node.strokeWidth), lineDash: highlightStyle?.lineDash ?? lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? lineDashOffset }; } getNodeStyleOverrides(datumId, datum, datumIndex, size, label, format, highlighted) { const { id: seriesId, properties } = this; const { fills, strokes } = properties; const { itemStyler } = properties.node; const fill = format.fill ?? fills[datumIndex % fills.length]; const stroke22 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId4(datumId, highlighted ? "highlight" : "node"), () => { const { fillOpacity = 1, strokeOpacity = 1, strokeWidth = 0, lineDash = [], lineDashOffset = 0 } = format; return itemStyler({ seriesId, datum, highlighted, label, size, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateNodeNodes(opts) { const { datumSelection, isHighlight } = opts; const format = this.getBaseNodeStyle(isHighlight); datumSelection.each((sector, datum) => { const { datumIndex, size, label } = datum; const overrides = this.getNodeStyleOverrides( String(datumIndex), datum, datumIndex.index, size, label, format, isHighlight ); sector.centerX = datum.centerX; sector.centerY = datum.centerY; sector.innerRadius = datum.innerRadius; sector.outerRadius = datum.outerRadius; sector.startAngle = datum.startAngle; sector.endAngle = datum.endAngle; sector.fill = overrides.fill ?? format?.fill; sector.fillOpacity = overrides.fillOpacity ?? format?.fillOpacity; sector.stroke = overrides.stroke ?? format?.stroke; sector.strokeOpacity = overrides.strokeOpacity ?? format?.strokeOpacity; sector.strokeWidth = overrides.strokeWidth ?? format?.strokeWidth; sector.lineDash = overrides.lineDash ?? format?.lineDash; sector.lineDashOffset = overrides.lineDashOffset ?? format?.lineDashOffset; sector.inset = sector.strokeWidth / 2; }); } updateLinkSelection(opts) { return opts.datumSelection.update( opts.nodeData, void 0, (datum) => createDatumId4([datum.type, datum.index, datum.fromNode.id, datum.toNode.id]) ); } getBaseLinkStyle(highlighted) { const { properties } = this; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset, tension } = properties.link; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? fill, fillOpacity: highlightStyle?.fillOpacity ?? fillOpacity, stroke: highlightStyle?.stroke ?? stroke22, strokeOpacity: highlightStyle?.strokeOpacity ?? strokeOpacity, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.link.strokeWidth), lineDash: highlightStyle?.lineDash ?? lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? lineDashOffset, tension }; } getLinkStyleOverrides(datumId, datum, fromNodeDatumIndex, format, highlighted) { const { id: seriesId, properties } = this; const { fills, strokes } = properties; const { itemStyler } = properties.link; const fill = format.fill ?? fills[fromNodeDatumIndex % fills.length]; const stroke22 = format.stroke ?? strokes[fromNodeDatumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId4(datumId, highlighted ? "highlight" : "node"), () => { const { fillOpacity = 1, strokeOpacity = 1, strokeWidth = 0, lineDash = [], lineDashOffset = 0, tension } = format; return itemStyler({ seriesId, datum, highlighted, tension, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateLinkNodes(opts) { const { datumSelection, isHighlight } = opts; const style = this.getBaseLinkStyle(isHighlight); datumSelection.each((link, datum) => { const { datumIndex } = datum; const fromNodeDatumIndex = datum.fromNode.datumIndex; const overrides = this.getLinkStyleOverrides( String(datumIndex), datum, fromNodeDatumIndex.index, style, isHighlight ); link.centerX = datum.centerX; link.centerY = datum.centerY; link.radius = datum.radius; link.startAngle1 = datum.startAngle1; link.endAngle1 = datum.endAngle1; link.startAngle2 = datum.startAngle2; link.endAngle2 = datum.endAngle2; applyShapeStyle2(link, style, overrides); link.tension = overrides?.tension ?? style.tension; }); } getTooltipContent(seriesDatum) { const { id: seriesId, linksProcessedData, nodesProcessedData, properties } = this; const { fromKey, toKey, sizeKey, sizeName, tooltip } = properties; const { datumIndex } = seriesDatum; const nodeIndex = seriesDatum.type === 0 ? seriesDatum.fromNode.index : seriesDatum.index; const title = seriesDatum.type === 0 ? `${seriesDatum.fromNode.label} - ${seriesDatum.toNode.label}` : seriesDatum.label; const datum = datumIndex.type === 0 ? linksProcessedData?.dataSources.get(this.id)?.[datumIndex.index] : nodesProcessedData?.dataSources.get(this.id)?.[datumIndex.index]; const size = seriesDatum.size; let format; if (seriesDatum.type === 0) { const fromNodeDatumIndex = seriesDatum.fromNode.datumIndex; const linkFormat = this.getBaseLinkStyle(false); Object.assign( linkFormat, this.getLinkStyleOverrides(String(datumIndex), datum, fromNodeDatumIndex.index, linkFormat, false) ); format = linkFormat; } else { const label = seriesDatum.label; const nodeFormat = this.getBaseNodeStyle(false); Object.assign( nodeFormat, this.getNodeStyleOverrides(String(datumIndex), datum, datumIndex.index, size, label, nodeFormat, false) ); format = nodeFormat; } return tooltip.formatTooltip( { title, symbol: this.legendItemSymbol(seriesDatum.type, nodeIndex, format), data: sizeKey != null ? [{ label: sizeName, fallbackLabel: sizeKey, value: String(size) }] : [] }, { seriesId, datum, title, fromKey, toKey, sizeKey, sizeName, size, ...format } ); } computeFocusBounds(node) { return node; } }; ChordSeries.className = "ChordSeries"; ChordSeries.type = "chord"; var ChordModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["flow-proportion"], solo: true, identifier: "chord", tooltipDefaults: { range: "exact" }, moduleFactory: (ctx) => new ChordSeries(ctx), themeTemplate: { series: { highlightStyle: { series: { dimOpacity: 0.2 } }, label: { fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, spacing: 5, maxWidth: 100 }, node: { spacing: 8, width: 10, strokeWidth: 0 }, link: { fillOpacity: 0.5, strokeWidth: 0, tension: 0.4 } }, legend: { enabled: false, toggleSeries: false } }, paletteFactory({ takeColors, colorsCount }) { const { fills, strokes } = takeColors(colorsCount); return { fills, strokes }; } }; var import_ag_charts_community173 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community166 = (init_main4(), __toCommonJS(main_exports)); var { ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE5, CARTESIAN_POSITION: CARTESIAN_POSITION3 }, ThemeSymbols: { DEFAULT_SHADOW_COLOUR: DEFAULT_SHADOW_COLOUR2 } } = import_ag_charts_community166._ModuleSupport; function funnelSeriesAxes(series) { const { placement, ...categoryLabel } = series?.stageLabel ?? {}; return series?.direction !== "horizontal" ? [ { type: CARTESIAN_AXIS_TYPE5.CATEGORY, position: placement === "after" ? CARTESIAN_POSITION3.RIGHT : CARTESIAN_POSITION3.LEFT, label: categoryLabel }, { type: CARTESIAN_AXIS_TYPE5.NUMBER, position: CARTESIAN_POSITION3.BOTTOM } ] : [ { type: CARTESIAN_AXIS_TYPE5.NUMBER, position: CARTESIAN_POSITION3.LEFT }, { type: CARTESIAN_AXIS_TYPE5.CATEGORY, position: placement === "before" ? CARTESIAN_POSITION3.TOP : CARTESIAN_POSITION3.BOTTOM, label: categoryLabel } ]; } var FUNNEL_SERIES_THEME = { series: { direction: "vertical", strokeWidth: 0, spacingRatio: 0.25, label: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" } }, dropOff: { enabled: true, fillOpacity: 0.2, strokeWidth: 0 }, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR2, xOffset: 3, yOffset: 3, blur: 5 } }, axes: { [CARTESIAN_AXIS_TYPE5.NUMBER]: { nice: false, gridLine: { enabled: false }, crosshair: { enabled: false }, label: { enabled: false, formatter(params) { return Math.abs(params.value).toFixed(params.fractionDigits ?? 0); } } }, [CARTESIAN_AXIS_TYPE5.CATEGORY]: { line: { enabled: false } } } }; var import_ag_charts_community171 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community169 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community167 = (init_main4(), __toCommonJS(main_exports)); var { lineDistanceSquared: lineDistanceSquared2, BBox: BBox12, Path: Path9, ScenePathChangeDetection: ScenePathChangeDetection7 } = import_ag_charts_community167._ModuleSupport; var delta3 = 1e-6; function pointsEq2([ax, ay], [bx, by]) { return Math.abs(ax - bx) <= delta3 && Math.abs(ay - by) <= delta3; } var FunnelConnector = class extends Path9 { constructor() { super(...arguments); this.x0 = 0; this.y0 = 0; this.x1 = 0; this.y1 = 0; this.x2 = 0; this.y2 = 0; this.x3 = 0; this.y3 = 0; } get midPoint() { const { x0, y0, x1, y1, x2, y2, x3, y3 } = this; return { x: (x0 + x1 + x2 + x3) / 4, y: (y0 + y1 + y2 + y3) / 4 }; } distanceSquared(x, y) { if (this.containsPoint(x, y)) return 0; const { x0, y0, x1, y1, x2, y2, x3, y3 } = this; return Math.min( lineDistanceSquared2(x, y, x0, y0, x1, y1, Infinity), lineDistanceSquared2(x, y, x1, y1, x2, y2, Infinity), lineDistanceSquared2(x, y, x2, y2, x3, y3, Infinity), lineDistanceSquared2(x, y, x3, y3, x0, y0, Infinity) ); } computeBBox() { const { x0, y0, x1, y1, x2, y2, x3, y3 } = this; const x = Math.min(x0, x1, x2, x3); const width2 = Math.max(x0, x1, x2, x3) - x; const y = Math.min(y0, y1, y2, y3); const height2 = Math.max(y0, y1, y2, y3) - y; return new BBox12(x, y, width2, height2); } updatePath() { const { path, x0, y0, x1, y1, x2, y2, x3, y3 } = this; const points = [ [x0, y0], [x1, y1], [x2, y2], [x3, y3] ]; path.clear(); let start2; let current; points.forEach((p) => { if (start2 != null && pointsEq2(start2, p) || current != null && pointsEq2(current, p)) { return; } const [x, y] = p; if (start2 == null) { path.moveTo(x, y); } else { path.lineTo(x, y); } start2 ?? (start2 = p); current = p; }); path.closePath(); } }; __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x0", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y0", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x1", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y1", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x2", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y2", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x3", 2); __decorateClass2([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y3", 2); var import_ag_charts_community168 = (init_main4(), __toCommonJS(main_exports)); var { NODE_UPDATE_STATE_TO_PHASE_MAPPING: NODE_UPDATE_STATE_TO_PHASE_MAPPING2 } = import_ag_charts_community168._ModuleSupport; function connectorStartingPosition(datum, _prevDatum, isVertical, _mode) { const { x0, y0, x1, y1, x2, y2, x3, y3, opacity } = datum; if (isVertical) { return { x0: (x0 + x3) / 2, y0: (y0 + y3) / 2, x1: (x1 + x2) / 2, y1: (y1 + y2) / 2, x2: (x1 + x2) / 2, y2: (y1 + y2) / 2, x3: (x0 + x3) / 2, y3: (y0 + y3) / 2, opacity }; } else { return { x0: (x0 + x1) / 2, y0: (y0 + y1) / 2, x1: (x0 + x1) / 2, y1: (y0 + y1) / 2, x2: (x2 + x3) / 2, y2: (y2 + y3) / 2, x3: (x2 + x3) / 2, y3: (y2 + y3) / 2, opacity }; } } function prepareConnectorAnimationFunctions(isVertical, mode) { const isRemoved = (datum) => datum == null; const fromFn = (connector, datum, status) => { if (status === "updated" && isRemoved(datum)) { status = "removed"; } else if (status === "updated" && isRemoved(connector.previousDatum)) { status = "added"; } let source; if (status === "added" && connector.previousDatum == null && mode === "fade") { source = { ...resetConnectorSelectionsFn(connector, datum), opacity: 0 }; } else if (status === "unknown" || status === "added") { source = connectorStartingPosition(datum, connector.previousDatum, isVertical, mode); } else { source = { x0: connector.x0, y0: connector.y0, x1: connector.x1, y1: connector.y1, x2: connector.x2, y2: connector.y2, x3: connector.x3, y3: connector.y3, opacity: connector.opacity }; } const phase = NODE_UPDATE_STATE_TO_PHASE_MAPPING2[status]; return { ...source, phase }; }; const toFn = (connector, datum, status) => { let source; if (status === "removed" && connector.datum == null && mode === "fade") { source = { ...resetConnectorSelectionsFn(connector, datum), opacity: 0 }; } else if (status === "removed" || isRemoved(datum)) { source = connectorStartingPosition(datum, connector.previousDatum, isVertical, mode); } else { source = resetConnectorSelectionsFn(connector, datum); } return source; }; return { fromFn, toFn }; } function resetConnectorSelectionsFn(_node, datum) { const { x0, y0, x1, y1, x2, y2, x3, y3, opacity } = datum; return { x0, y0, x1, y1, x2, y2, x3, y3, opacity }; } var { SeriesNodePickMode: SeriesNodePickMode4, SeriesZIndexMap: SeriesZIndexMap2, valueProperty: valueProperty7, keyProperty: keyProperty5, ChartAxisDirection: ChartAxisDirection20, updateLabelNode: updateLabelNode2, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL3, LARGEST_KEY_INTERVAL: LARGEST_KEY_INTERVAL2, diff: diff3, fixNumericExtent: fixNumericExtent4, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation2, resetMotion: resetMotion2, resetLabelFn: resetLabelFn2, animationValidation: animationValidation3, computeBarFocusBounds: computeBarFocusBounds3, ContinuousScale: ContinuousScale5, Group: Group10, Selection: Selection5, PointerEvents: PointerEvents2, motion: motion22, checkCrisp: checkCrisp2, createDatumId: createDatumId5 } = import_ag_charts_community169._ModuleSupport; var FunnelSeriesNodeEvent = class extends import_ag_charts_community169._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.xKey = series.properties.stageKey; this.yKey = series.properties.valueKey; } }; var BaseFunnelSeries = class extends import_ag_charts_community169._ModuleSupport.AbstractBarSeries { constructor({ moduleCtx, animationResetFns }) { super({ moduleCtx, pickModes: [SeriesNodePickMode4.AXIS_ALIGNED, SeriesNodePickMode4.EXACT_SHAPE_MATCH], hasHighlightedLabels: true, directionKeys: { x: ["stageKey"], y: ["valueKey"] }, directionNames: { x: [], y: [] }, datumSelectionGarbageCollection: false, animationResetFns: { datum: animationResetFns.datum, label: resetLabelFn2 } }); this.NodeEvent = FunnelSeriesNodeEvent; this.connectorNodeGroup = this.contentGroup.appendChild( new Group10({ name: `${this.id}-series-connectorNodes`, zIndex: SeriesZIndexMap2.BACKGROUND }) ); this.connectorSelection = Selection5.select( this.connectorNodeGroup, () => this.connectionFactory() ); this.connectorNodeGroup.pointerEvents = PointerEvents2.None; } get pickModeAxis() { return "main-category"; } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.connectorNodeGroup.zIndex = [SeriesZIndexMap2.BACKGROUND, index]; return true; } isVertical() { return !super.isVertical(); } connectionFactory() { return new FunnelConnector(); } async processData(dataController) { if (!this.properties.isValid()) { return; } const { stageKey, valueKey } = this.properties; const { visible, id: seriesId } = this; const validation = (_value, _datum, index) => visible && this.ctx.legendManager.getItemEnabled({ seriesId, itemId: index }); const xScale = this.getCategoryAxis()?.scale; const yScale = this.getValueAxis()?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const extraProps = []; if (!this.ctx.animationManager.isSkipped()) { if (this.processedData) { extraProps.push(diff3(this.id, this.processedData)); } extraProps.push(animationValidation3()); } const visibleProps = this.visible ? {} : { forceValue: 0 }; const { processedData } = await this.requestDataModel(dataController, this.data, { props: [ keyProperty5(stageKey, xScaleType, { id: "xValue" }), valueProperty7(valueKey, yScaleType, { id: `yValue`, ...visibleProps, validation, invalidValue: 0 }), ...isContinuousX ? [SMALLEST_KEY_INTERVAL3, LARGEST_KEY_INTERVAL2] : [], ...extraProps ], groupByKeys: false }); this.smallestDataInterval = processedData.reduced?.smallestKeyInterval; this.largestDataInterval = processedData.reduced?.largestKeyInterval; this.animationState.transition("updateData"); } getSeriesDomain(direction) { const { processedData, dataModel, id: seriesId, ctx: { legendManager } } = this; if (!processedData || !dataModel) return []; const { keys: [keys] } = processedData.domain; if (direction === this.getCategoryDirection()) { const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`); if (keyDef?.def.type === "key" && keyDef?.def.valueType === "category") { if (!this.hasData) return []; return keys.filter((_key, index) => legendManager.getItemEnabled({ seriesId, itemId: index })); } return this.padBandExtent(keys); } else { const yExtent = this.domainForClippedRange(ChartAxisDirection20.Y, ["yValue"], "xValue", true); const maxExtent = Math.max(...yExtent); const fixedYExtent = [-maxExtent, maxExtent]; return fixNumericExtent4(fixedYExtent); } } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } createNodeData() { const { hasData, data, dataModel, groupScale, processedData, id: seriesId, ctx: { legendManager } } = this; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!(hasData && data && xAxis && yAxis && dataModel && processedData?.type === "ungrouped")) { return; } const xScale = xAxis.scale; const yScale = yAxis.scale; const barAlongX = this.getBarDirection() === ChartAxisDirection20.X; const { stageKey, valueKey } = this.properties; const { strokeWidth } = this.barStyle(); const itemId = `${valueKey}`; const context = { itemId, nodeData: [], labelData: [], connectorData: [], scales: this.calculateScaling(), visible: this.visible }; const isVisible = this.visible; if (!isVisible) return context; const xValues = dataModel.resolveKeysById(this, "xValue", processedData); const yValues = dataModel.resolveColumnById(this, `yValue`, processedData); const { barWidth, groupIndex } = this.updateGroupScale(xAxis); const barOffset = ContinuousScale5.is(xScale) ? barWidth * -0.5 : 0; const crisp = checkCrisp2( xAxis?.scale, xAxis?.visibleRange, this.smallestDataInterval, this.largestDataInterval ); let previousConnection; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const visible = isVisible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }); const xDatum = xValues[datumIndex]; if (xDatum == null) return; const x = Math.round(xScale.convert(xDatum)) + groupScale.convert(String(groupIndex)) + barOffset; const yDatum = yValues[datumIndex]; const yNegative = Math.round(yScale.convert(-yDatum)); const yPositive = Math.round(yScale.convert(yDatum)); const barHeight = Math.max(strokeWidth, Math.abs(yPositive - yNegative)); const rect = { x: barAlongX ? Math.min(yPositive, yNegative) : x, y: barAlongX ? x : Math.min(yPositive, yNegative), width: barAlongX ? barHeight : barWidth, height: barAlongX ? barWidth : barHeight }; const nodeMidPoint = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }; const labelData = this.createLabelData({ datumIndex, rect, barAlongX, yDatum, datum, visible }); const nodeDatum = { index: datumIndex, series: this, itemId, datum, datumIndex, xValue: xDatum, yValue: yDatum, xKey: stageKey, yKey: valueKey, x: rect.x, y: rect.y, width: rect.width, height: rect.height, midPoint: nodeMidPoint, strokeWidth, crisp, label: labelData, visible }; context.nodeData.push(nodeDatum); if (labelData != null) { context.labelData.push(labelData); } if (previousConnection != null) { const prevRect = previousConnection.rect; const startNodeDatum = previousConnection.nodeDatum; const startDatumIndex = previousConnection.datumIndex; if (barAlongX) { context.connectorData.push({ datum: startNodeDatum, datumIndex: startDatumIndex, x0: prevRect.x, y0: prevRect.y + prevRect.height, x1: prevRect.x + prevRect.width, y1: prevRect.y + prevRect.height, x2: rect.x + rect.width, y2: rect.y, x3: rect.x, y3: rect.y, opacity: 1 }); } else { context.connectorData.push({ datum: startNodeDatum, datumIndex: startDatumIndex, x0: prevRect.x + prevRect.width, y0: prevRect.y, x1: rect.x, y1: rect.y, x2: rect.x, y2: rect.y + rect.height, x3: prevRect.x + prevRect.width, y3: prevRect.y + prevRect.height, opacity: 1 }); } } if (visible) { previousConnection = { itemId, rect, nodeDatum, datumIndex }; } }); return context; } updateNodes(highlightedItems, seriesHighlighted, anySeriesItemEnabled) { super.updateNodes(highlightedItems, seriesHighlighted, anySeriesItemEnabled); const { connectorSelection } = this; const connectorData = this.contextNodeData?.connectorData ?? []; this.connectorSelection = this.updateConnectorSelection({ connectorSelection, connectorData }); this.updateConnectorNodes({ connectorSelection }); } updateDatumSelection(opts) { const { nodeData, datumSelection } = opts; const data = nodeData ?? []; return datumSelection.update(data, void 0, (datum) => this.getDatumId(datum)); } updateConnectorSelection(opts) { const { connectorData, connectorSelection } = opts; return connectorSelection.update( this.connectorEnabled() ? connectorData : [], void 0, (connector) => this.getDatumId(connector.datum) ); } updateConnectorNodes(opts) { const { fills, strokes } = this.properties; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.connectorStyle(); opts.connectorSelection.each((connector, datum) => { const { datumIndex } = datum; connector.setProperties(resetConnectorSelectionsFn(connector, datum)); connector.fill = fill ?? fills[datumIndex % fills.length]; connector.fillOpacity = fillOpacity; connector.stroke = stroke22 ?? strokes[datumIndex % strokes.length]; connector.strokeOpacity = strokeOpacity; connector.strokeWidth = strokeWidth; connector.lineDash = lineDash; connector.lineDashOffset = lineDashOffset; }); } getHighlightLabelData(labelData, highlightedItem) { const labelItems = labelData.filter((ld) => ld.datum === highlightedItem.datum); return labelItems.length > 0 ? labelItems : void 0; } updateLabelSelection(opts) { const labelData = this.properties.label.enabled ? opts.labelData : []; return opts.labelSelection.update(labelData, (text22) => { text22.pointerEvents = PointerEvents2.None; }); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode2(textNode, this.properties.label, datum); }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { stageKey, valueKey, tooltip } = properties; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, "xValue", processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex]; if (xValue == null) return; return tooltip.formatTooltip( { symbol: this.legendItemSymbol(datumIndex), data: [{ label: xAxis.formatDatum(xValue), value: yAxis.formatDatum(yValue) }] }, { seriesId, datum, title: stageKey, stageKey, valueKey, ...this.tooltipStyle(datum, datumIndex) } ); } resetAllAnimation(data) { super.resetAllAnimation(data); resetMotion2([this.connectorSelection], resetConnectorSelectionsFn); } animateEmptyUpdateReady({ labelSelection }) { const { connectorSelection } = this; const isVertical = this.isVertical(); const mode = "normal"; const connectorFns = prepareConnectorAnimationFunctions(isVertical, mode); motion22.fromToMotion(this.id, "connectors", this.ctx.animationManager, [connectorSelection], connectorFns); seriesLabelFadeInAnimation2(this, "labels", this.ctx.animationManager, labelSelection); } animateWaitingUpdateReady(data) { const { labelSelection: labelSelections } = data; this.ctx.animationManager.stopByAnimationGroupId(this.id); seriesLabelFadeInAnimation2(this, "labels", this.ctx.animationManager, labelSelections); } getDatumId(datum) { return createDatumId5(datum.xValue); } isLabelEnabled() { return this.properties.label.enabled; } computeFocusBounds({ datumIndex }) { return computeBarFocusBounds3(this, this.contextNodeData?.nodeData[datumIndex]); } legendItemSymbol(datumIndex) { const { strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.barStyle(); const { fills, strokes } = this.properties; const fill = fills[datumIndex % fills.length] ?? "black"; const stroke22 = strokes[datumIndex % strokes.length] ?? "black"; return { marker: { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } }; } getLegendData(legendType) { const { id: seriesId, processedData, dataModel, ctx: { legendManager }, visible } = this; if (!dataModel || !processedData || legendType !== "category" || !this.properties.isValid()) { return []; } const { showInLegend } = this.properties; const xValues = dataModel.resolveKeysById(this, "xValue", processedData); return (processedData.dataSources.get(this.id) ?? []).map((datum, datumIndex) => { const stageValue = xValues[datumIndex]; if (stageValue == null) return; return { legendType: "category", id: seriesId, datum, itemId: datumIndex, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }), label: { text: String(stageValue) }, symbol: this.legendItemSymbol(datumIndex), skipAnimations: true, hideInLegend: !showInLegend }; }).filter((datum) => datum != null); } }; var import_ag_charts_community170 = (init_main4(), __toCommonJS(main_exports)); var { Label: Label4, AbstractBarSeriesProperties: AbstractBarSeriesProperties3, SeriesTooltip: SeriesTooltip5, AxisLabel: AxisLabel22, Validate: Validate59, UNION: UNION11, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY3, LINE_DASH: LINE_DASH9, OBJECT: OBJECT27, POSITIVE_NUMBER: POSITIVE_NUMBER19, RATIO: RATIO16, STRING: STRING27 } = import_ag_charts_community170._ModuleSupport; var ConeFunnelSeriesLabel = class extends Label4 { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass2([ Validate59(UNION11(["before", "middle", "after"], "a placement")) ], ConeFunnelSeriesLabel.prototype, "placement", 2); __decorateClass2([ Validate59(POSITIVE_NUMBER19) ], ConeFunnelSeriesLabel.prototype, "spacing", 2); var ConeFunnelSeriesStageLabel = class extends AxisLabel22 { }; __decorateClass2([ Validate59(UNION11(["before", "after"], "a placement")) ], ConeFunnelSeriesStageLabel.prototype, "placement", 2); var ConeFunnelProperties = class extends AbstractBarSeriesProperties3 { constructor() { super(...arguments); this.fills = []; this.fillOpacity = 1; this.strokes = []; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.label = new ConeFunnelSeriesLabel(); this.stageLabel = new ConeFunnelSeriesStageLabel(); this.tooltip = new SeriesTooltip5(); } }; __decorateClass2([ Validate59(STRING27) ], ConeFunnelProperties.prototype, "stageKey", 2); __decorateClass2([ Validate59(STRING27) ], ConeFunnelProperties.prototype, "valueKey", 2); __decorateClass2([ Validate59(COLOR_STRING_ARRAY3) ], ConeFunnelProperties.prototype, "fills", 2); __decorateClass2([ Validate59(RATIO16) ], ConeFunnelProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate59(COLOR_STRING_ARRAY3) ], ConeFunnelProperties.prototype, "strokes", 2); __decorateClass2([ Validate59(POSITIVE_NUMBER19) ], ConeFunnelProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate59(RATIO16) ], ConeFunnelProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate59(LINE_DASH9) ], ConeFunnelProperties.prototype, "lineDash", 2); __decorateClass2([ Validate59(POSITIVE_NUMBER19) ], ConeFunnelProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate59(OBJECT27) ], ConeFunnelProperties.prototype, "label", 2); __decorateClass2([ Validate59(OBJECT27) ], ConeFunnelProperties.prototype, "stageLabel", 2); __decorateClass2([ Validate59(OBJECT27) ], ConeFunnelProperties.prototype, "tooltip", 2); function resetLineSelectionsFn(_node, { x, y, width: width2, height: height2, opacity }) { return { x1: x, y1: y, x2: x + width2, y2: y + height2, opacity }; } var { formatValue: formatValue2, Line: Line5 } = import_ag_charts_community171._ModuleSupport; var ConeFunnelSeries = class extends BaseFunnelSeries { constructor(moduleCtx) { super({ moduleCtx, animationResetFns: { datum: resetLineSelectionsFn } }); this.properties = new ConeFunnelProperties(); } get hasData() { const { id: seriesId, ctx: { legendManager } } = this; const visibleItems = this.data?.reduce( (accum, _, datumIndex) => accum + (legendManager.getItemEnabled({ seriesId, itemId: datumIndex }) ? 1 : 0), 0 ); return visibleItems != null && visibleItems > 1; } getBandScalePadding() { return { inner: 1, outer: 0 }; } connectorEnabled() { return true; } barStyle() { return { fillOpacity: 1, strokeOpacity: 1, strokeWidth: 0, lineDash: [], lineDashOffset: 0 }; } connectorStyle() { const { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties; return { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset }; } nodeFactory() { return new Line5(); } createLabelData({ datumIndex, rect, barAlongX, yDatum, datum, visible }) { const { stageKey, valueKey, label } = this.properties; const { spacing, placement } = label; let x; let y; let textAlign; let textBaseline; if (barAlongX) { x = rect.x + rect.width / 2; textAlign = "center"; switch (placement) { case "before": y = rect.y - spacing; textBaseline = "bottom"; break; case "after": y = rect.y + rect.height + spacing; textBaseline = "top"; break; default: y = rect.y + rect.height / 2; textBaseline = "middle"; } } else { y = rect.y + rect.height / 2; textBaseline = "middle"; switch (placement) { case "before": x = rect.x - spacing; textAlign = "right"; break; case "after": x = rect.x + rect.width + spacing; textAlign = "left"; break; default: x = rect.x + rect.width / 2; textAlign = "center"; } } return { x, y, textAlign, textBaseline, text: this.getLabelText( label, { itemId: valueKey, value: yDatum, datum, stageKey, valueKey }, (value) => formatValue2(value, 0) ), itemId: valueKey, datum, datumIndex, series: this, visible }; } updateDatumNodes(opts) { const highlightStyle = opts.isHighlight ? this.properties.highlightStyle.item : void 0; opts.datumSelection.each((line, datum) => { line.setProperties(resetLineSelectionsFn(line, datum)); line.stroke = highlightStyle?.stroke; line.strokeWidth = highlightStyle?.strokeWidth ?? 0; line.strokeOpacity = highlightStyle?.strokeOpacity ?? 1; line.lineDash = highlightStyle?.lineDash; line.lineDashOffset = highlightStyle?.lineDashOffset ?? 0; }); } tooltipStyle(_datum, datumIndex) { const { fills, strokes } = this.properties; const fill = fills[datumIndex % fills.length] ?? "black"; const stroke22 = strokes[datumIndex % strokes.length] ?? "black"; const { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.barStyle(); return { fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }; } }; ConeFunnelSeries.className = "ConeFunnelSeries"; ConeFunnelSeries.type = "cone-funnel"; var import_ag_charts_community172 = (init_main4(), __toCommonJS(main_exports)); var { ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE6 } } = import_ag_charts_community172._ModuleSupport; var CONE_FUNNEL_SERIES_THEME = { series: { direction: "vertical", strokeWidth: 0, label: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, placement: "before", spacing: 4 } }, seriesArea: { padding: { top: 20, bottom: 20 } }, axes: { [CARTESIAN_AXIS_TYPE6.NUMBER]: { nice: false, gridLine: { enabled: false }, crosshair: { enabled: false }, label: { enabled: false, formatter(params) { return Math.abs(params.value).toFixed(params.fractionDigits ?? 0); } } }, [CARTESIAN_AXIS_TYPE6.CATEGORY]: { line: { enabled: false } } } }; var ConeFunnelModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "cone-funnel", moduleFactory: (ctx) => new ConeFunnelSeries(ctx), solo: true, tooltipDefaults: { range: "nearest" }, defaultAxes: funnelSeriesAxes, themeTemplate: CONE_FUNNEL_SERIES_THEME, paletteFactory: ({ userPalette, themeTemplateParameters, takeColors, colorsCount }) => { const { fills: userFills } = takeColors(colorsCount); const defaultFills = themeTemplateParameters.get( import_ag_charts_community173._ModuleSupport.ThemeSymbols.DEFAULT_FUNNEL_SERIES_COLOR_RANGE ); const fills = userPalette === "inbuilt" ? defaultFills : [userFills[0], userFills[1]]; return { fills, strokes: fills.slice(0) }; } }; var import_ag_charts_community175 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community174 = (init_main4(), __toCommonJS(main_exports)); var { Label: Label5, DropShadow: DropShadow2, AbstractBarSeriesProperties: AbstractBarSeriesProperties4, BaseProperties: BaseProperties23, SeriesTooltip: SeriesTooltip6, AxisLabel: AxisLabel3, Validate: Validate60, UNION: UNION12, BOOLEAN: BOOLEAN27, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY4, COLOR_STRING: COLOR_STRING13, FUNCTION: FUNCTION10, LINE_DASH: LINE_DASH10, OBJECT: OBJECT28, POSITIVE_NUMBER: POSITIVE_NUMBER20, RATIO: RATIO17, STRING: STRING28 } = import_ag_charts_community174._ModuleSupport; var FunnelSeriesLabel = class extends Label5 { }; var FunnelSeriesStageLabel = class extends AxisLabel3 { }; __decorateClass2([ Validate60(UNION12(["before", "after"], "a placement")) ], FunnelSeriesStageLabel.prototype, "placement", 2); var FunnelDropOff = class extends BaseProperties23 { constructor() { super(...arguments); this.enabled = true; this.fillOpacity = 1; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate60(BOOLEAN27) ], FunnelDropOff.prototype, "enabled", 2); __decorateClass2([ Validate60(COLOR_STRING13, { optional: true }) ], FunnelDropOff.prototype, "fill", 2); __decorateClass2([ Validate60(RATIO17) ], FunnelDropOff.prototype, "fillOpacity", 2); __decorateClass2([ Validate60(COLOR_STRING13, { optional: true }) ], FunnelDropOff.prototype, "stroke", 2); __decorateClass2([ Validate60(POSITIVE_NUMBER20) ], FunnelDropOff.prototype, "strokeWidth", 2); __decorateClass2([ Validate60(RATIO17) ], FunnelDropOff.prototype, "strokeOpacity", 2); __decorateClass2([ Validate60(LINE_DASH10) ], FunnelDropOff.prototype, "lineDash", 2); __decorateClass2([ Validate60(POSITIVE_NUMBER20) ], FunnelDropOff.prototype, "lineDashOffset", 2); var FunnelProperties = class extends AbstractBarSeriesProperties4 { constructor() { super(...arguments); this.fills = []; this.fillOpacity = 1; this.strokes = []; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.spacingRatio = 0; this.dropOff = new FunnelDropOff(); this.shadow = new DropShadow2().set({ enabled: false }); this.label = new FunnelSeriesLabel(); this.stageLabel = new FunnelSeriesStageLabel(); this.tooltip = new SeriesTooltip6(); } }; __decorateClass2([ Validate60(STRING28) ], FunnelProperties.prototype, "stageKey", 2); __decorateClass2([ Validate60(STRING28) ], FunnelProperties.prototype, "valueKey", 2); __decorateClass2([ Validate60(COLOR_STRING_ARRAY4) ], FunnelProperties.prototype, "fills", 2); __decorateClass2([ Validate60(RATIO17) ], FunnelProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate60(COLOR_STRING_ARRAY4) ], FunnelProperties.prototype, "strokes", 2); __decorateClass2([ Validate60(POSITIVE_NUMBER20) ], FunnelProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate60(RATIO17) ], FunnelProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate60(LINE_DASH10) ], FunnelProperties.prototype, "lineDash", 2); __decorateClass2([ Validate60(POSITIVE_NUMBER20) ], FunnelProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate60(RATIO17) ], FunnelProperties.prototype, "spacingRatio", 2); __decorateClass2([ Validate60(FUNCTION10, { optional: true }) ], FunnelProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate60(OBJECT28) ], FunnelProperties.prototype, "dropOff", 2); __decorateClass2([ Validate60(OBJECT28) ], FunnelProperties.prototype, "shadow", 2); __decorateClass2([ Validate60(OBJECT28) ], FunnelProperties.prototype, "label", 2); __decorateClass2([ Validate60(OBJECT28) ], FunnelProperties.prototype, "stageLabel", 2); __decorateClass2([ Validate60(OBJECT28) ], FunnelProperties.prototype, "tooltip", 2); var { ChartAxisDirection: ChartAxisDirection21, resetBarSelectionsFn: resetBarSelectionsFn2, prepareBarAnimationFunctions: prepareBarAnimationFunctions2, midpointStartingBarPosition: midpointStartingBarPosition2, createDatumId: createDatumId6, formatValue: formatValue22, Rect: Rect4, motion: motion3, applyShapeStyle: applyShapeStyle22 } = import_ag_charts_community175._ModuleSupport; var FunnelSeries = class extends BaseFunnelSeries { constructor(moduleCtx) { super({ moduleCtx, animationResetFns: { datum: resetBarSelectionsFn2 } }); this.properties = new FunnelProperties(); } getBandScalePadding() { return { inner: this.properties.spacingRatio, outer: 0 }; } connectorEnabled() { return this.properties.dropOff.enabled; } barStyle() { const { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties; return { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset }; } connectorStyle() { const { fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.dropOff; return { fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }; } nodeFactory() { return new Rect4(); } createLabelData({ datumIndex, rect, yDatum, datum, visible }) { const { valueKey, stageKey, label } = this.properties; return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2, textAlign: "center", textBaseline: "middle", text: this.getLabelText( label, { itemId: stageKey, value: yDatum, datum, valueKey, stageKey }, (value) => formatValue22(value, 0) ), itemId: stageKey, datum, datumIndex, series: this, visible }; } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset }; } getItemStyleOverrides(datumId, datum, datumIndex, format, highlighted) { const { id: seriesId, properties } = this; const { stageKey, valueKey, fills, strokes, itemStyler } = properties; const fill = format.fill ?? fills[datumIndex % fills.length] ?? "black"; const stroke22 = format.stroke ?? strokes[datumIndex % strokes.length] ?? "black"; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId6(datumId, highlighted ? "highlight" : "node"), () => { const { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = format; return itemStyler({ seriesId, datum, highlighted, stageKey, valueKey, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateDatumNodes(opts) { const { shadow } = this.properties; const { datumSelection, isHighlight } = opts; const categoryAlongX = this.getCategoryDirection() === ChartAxisDirection21.X; const style = this.getItemBaseStyle(isHighlight); datumSelection.each((rect, datum) => { const { datumIndex } = datum; const overrides = this.getItemStyleOverrides( String(datum.datumIndex), datum.datum, datumIndex, style, isHighlight ); applyShapeStyle22(rect, style, overrides); rect.visible = categoryAlongX ? datum.width > 0 : datum.height > 0; rect.crisp = datum.crisp; rect.fillShadow = shadow; }); } tooltipStyle(datum, datumIndex) { const style = this.getItemBaseStyle(false); Object.assign(style, this.getItemStyleOverrides(String(datumIndex), datum, datumIndex, style, false)); return style; } animateEmptyUpdateReady(params) { super.animateEmptyUpdateReady(params); const { datumSelection } = params; const isVertical = this.isVertical(); const mode = "normal"; const barFns = prepareBarAnimationFunctions2(midpointStartingBarPosition2(isVertical, mode)); motion3.fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], barFns); } animateWaitingUpdateReady(data) { super.animateWaitingUpdateReady(data); const { datumSelection: datumSelections } = data; const { processedData } = this; const dataDiff = processedData?.reduced?.diff?.[this.id]; const fns = prepareBarAnimationFunctions2(midpointStartingBarPosition2(this.isVertical(), "fade")); motion3.fromToMotion( this.id, "datums", this.ctx.animationManager, [datumSelections], fns, (_, datum) => datum.xValue, dataDiff ); } }; FunnelSeries.className = "FunnelSeries"; FunnelSeries.type = "funnel"; var FunnelModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "funnel", moduleFactory: (ctx) => new FunnelSeries(ctx), solo: true, tooltipDefaults: { range: "exact" }, defaultAxes: funnelSeriesAxes, themeTemplate: FUNNEL_SERIES_THEME, paletteFactory: ({ takeColors }) => { const { fills, strokes } = takeColors(1); return { fills, strokes }; } }; var import_ag_charts_community181 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community179 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community176 = (init_main4(), __toCommonJS(main_exports)); var { CachedTextMeasurerPool: CachedTextMeasurerPool4, TextUtils: TextUtils5, TextWrapper: TextWrapper5 } = import_ag_charts_community176._ModuleSupport; function generateLabelSecondaryLabelFontSizeCandidates(label, secondaryLabel) { const { fontSize: labelFontSize, minimumFontSize: labelMinimumFontSize = labelFontSize } = label; const { fontSize: secondaryLabelFontSize, minimumFontSize: secondaryLabelMinimumFontSize = secondaryLabelFontSize } = secondaryLabel; const labelTracks = labelFontSize - labelMinimumFontSize; const secondaryLabelTracks = secondaryLabelFontSize - secondaryLabelMinimumFontSize; let currentLabelFontSize = label.fontSize; let currentSecondaryLabelFontSize = secondaryLabel.fontSize; const out = [{ labelFontSize, secondaryLabelFontSize }]; while (currentLabelFontSize > labelMinimumFontSize || currentSecondaryLabelFontSize > secondaryLabelMinimumFontSize) { const labelProgress = labelTracks > 0 ? (currentLabelFontSize - labelMinimumFontSize) / labelTracks : -1; const secondaryLabelProgress = secondaryLabelTracks > 0 ? (currentSecondaryLabelFontSize - secondaryLabelMinimumFontSize) / secondaryLabelTracks : -1; if (labelProgress > secondaryLabelProgress) { currentLabelFontSize--; } else { currentSecondaryLabelFontSize--; } out.push({ labelFontSize: currentLabelFontSize, secondaryLabelFontSize: currentSecondaryLabelFontSize }); } out.reverse(); return out; } function getLineHeight(labelProps, fontSize) { if (labelProps.lineHeight != null && labelProps.fontSize != null) { return labelProps.lineHeight * fontSize / labelProps.fontSize; } else { return TextUtils5.getLineHeight(fontSize); } } function formatStackedLabels(labelValue, labelProps, secondaryLabelValue, secondaryLabelProps, { padding }, sizeFittingHeight) { const { spacing = 0 } = labelProps; const widthAdjust = 2 * padding; const heightAdjust = 2 * padding + spacing; const minimumHeight = (labelProps.minimumFontSize ?? labelProps.fontSize) + (secondaryLabelProps.minimumFontSize ?? secondaryLabelProps.fontSize); if (minimumHeight > sizeFittingHeight(minimumHeight + heightAdjust, false).height - heightAdjust) return; const fontSizeCandidates = generateLabelSecondaryLabelFontSizeCandidates(labelProps, secondaryLabelProps); const labelTextSizeProps = { fontFamily: labelProps.fontFamily, fontSize: labelProps.fontSize, fontStyle: labelProps.fontStyle, fontWeight: labelProps.fontWeight }; const secondaryLabelTextSizeProps = { fontFamily: secondaryLabelProps.fontFamily, fontSize: secondaryLabelProps.fontSize, fontStyle: secondaryLabelProps.fontStyle, fontWeight: secondaryLabelProps.fontWeight }; let label; let secondaryLabel; return findMaxValue(0, fontSizeCandidates.length - 1, (index) => { const { labelFontSize, secondaryLabelFontSize } = fontSizeCandidates[index]; const allowTruncation = index === 0; const labelLineHeight = getLineHeight(labelProps, labelFontSize); const secondaryLabelLineHeight = getLineHeight(secondaryLabelProps, secondaryLabelFontSize); const sizeFitting = sizeFittingHeight( labelLineHeight + secondaryLabelLineHeight + heightAdjust, allowTruncation ); const availableWidth = sizeFitting.width - widthAdjust; const availableHeight = sizeFitting.height - heightAdjust; if (labelLineHeight + secondaryLabelLineHeight > availableHeight) return; if (label == null || label.fontSize !== labelFontSize) { labelTextSizeProps.fontSize = labelFontSize; label = wrapLabel( labelProps, labelValue, availableWidth, availableHeight, labelTextSizeProps, labelProps.wrapping, allowTruncation ? labelProps.overflowStrategy : "hide" ); } if (label == null || label.width > availableWidth || label.height > availableHeight) return; if (secondaryLabel == null || secondaryLabel.fontSize !== secondaryLabelFontSize) { secondaryLabelTextSizeProps.fontSize = secondaryLabelFontSize; secondaryLabel = wrapLabel( secondaryLabelProps, secondaryLabelValue, availableWidth, availableHeight, secondaryLabelTextSizeProps, secondaryLabelProps.wrapping, allowTruncation ? secondaryLabelProps.overflowStrategy : "hide" ); } if (secondaryLabel == null) return; const totalLabelHeight = label.height + secondaryLabel.height; if (secondaryLabel.width > availableWidth || totalLabelHeight > availableHeight) return; return { width: Math.max(label.width, secondaryLabel.width), height: totalLabelHeight + spacing, meta: sizeFitting.meta, label, secondaryLabel }; }); } function formatSingleLabel(value, props, { padding }, sizeFittingHeight) { const sizeAdjust = 2 * padding; const minimumFontSize = Math.min(props.minimumFontSize ?? props.fontSize, props.fontSize); const textSizeProps = { fontFamily: props.fontFamily, fontSize: props.fontSize, fontStyle: props.fontStyle, fontWeight: props.fontWeight }; return findMaxValue(minimumFontSize, props.fontSize, (fontSize) => { const lineHeight = getLineHeight(props, fontSize); const allowTruncation = fontSize === minimumFontSize; const sizeFitting = sizeFittingHeight(lineHeight + sizeAdjust, allowTruncation); const availableWidth = sizeFitting.width - sizeAdjust; const availableHeight = sizeFitting.height - sizeAdjust; if (lineHeight > availableHeight) return; textSizeProps.fontSize = fontSize; const lines = TextWrapper5.wrapLines(value, { maxWidth: availableWidth, maxHeight: availableHeight, font: textSizeProps, textWrap: props.wrapping, overflow: (allowTruncation ? props.overflowStrategy : void 0) ?? "hide" }); if (!lines.length) return; const clippedLabel = clipLines(lines, { lineHeight, font: textSizeProps, maxWidth: availableWidth, maxHeight: availableHeight }); if (!clippedLabel) return; return [{ fontSize, lineHeight, ...clippedLabel }, sizeFitting.meta]; }); } function hasInvalidFontSize(label) { return label?.minimumFontSize != null && label?.fontSize != null && label?.minimumFontSize > label?.fontSize; } function formatLabels(baseLabelValue, labelProps, baseSecondaryLabelValue, secondaryLabelProps, layoutParams, sizeFittingHeight) { const labelValue = labelProps.enabled ? baseLabelValue : void 0; const secondaryLabelValue = secondaryLabelProps.enabled ? baseSecondaryLabelValue : void 0; if (hasInvalidFontSize(labelProps) || hasInvalidFontSize(secondaryLabelProps)) { logger_exports2.warnOnce(`minimumFontSize should be set to a value less than or equal to the font size`); } let value; if (labelValue != null && secondaryLabelValue != null) { value = formatStackedLabels( labelValue, labelProps, secondaryLabelValue, secondaryLabelProps, layoutParams, sizeFittingHeight ); } let labelMeta; if (value == null && labelValue != null) { labelMeta = formatSingleLabel(labelValue, labelProps, layoutParams, sizeFittingHeight); } if (labelMeta != null) { const [label, meta] = labelMeta; value = { width: label.width, height: label.height, meta, label, secondaryLabel: void 0 }; } let secondaryLabelMeta; if (value == null && labelValue == null && secondaryLabelValue != null) { secondaryLabelMeta = formatSingleLabel( secondaryLabelValue, secondaryLabelProps, layoutParams, sizeFittingHeight ); } if (secondaryLabelMeta != null) { const [secondaryLabel, meta] = secondaryLabelMeta; value = { width: secondaryLabel.width, height: secondaryLabel.height, meta, label: void 0, secondaryLabel }; } return value; } function wrapLabel(props, text22, maxWidth, maxHeight, font22, textWrap, overflow) { const lines = TextWrapper5.wrapLines(text22, { maxWidth, maxHeight, font: font22, textWrap, overflow }); if (!lines.length) return; const lineHeight = getLineHeight(props, font22.fontSize); const { width: width2 } = CachedTextMeasurerPool4.measureLines(lines, { font: font22 }); return { width: width2, lineHeight, text: lines.join("\n"), height: lines.length * lineHeight, fontSize: font22.fontSize }; } function clipLines(lines, { font: font22, lineHeight = TextUtils5.defaultLineHeight, maxWidth, maxHeight = Infinity }) { let height2 = lineHeight * lines.length; while (height2 > maxHeight) { if (lines.length === 1) return; lines.pop(); lines[lines.length - 1] = TextWrapper5.appendEllipsis(lines.at(-1)); height2 = lineHeight * lines.length; } const metrics = CachedTextMeasurerPool4.measureLines(lines, { font: font22 }); let text22, width2; if (metrics.width > maxWidth) { const clippedLines = []; width2 = 0; for (const line of metrics.lineMetrics) { if (line.width > maxWidth) { if (!clippedLines.length) return; break; } clippedLines.push(line.text); width2 = Math.max(width2, line.width); } text22 = TextWrapper5.appendEllipsis(clippedLines.join("\n")); } else { text22 = lines.join("\n"); width2 = metrics.width; } return { text: text22, width: width2, height: height2 }; } var import_ag_charts_community178 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community177 = (init_main4(), __toCommonJS(main_exports)); var { Validate: Validate61, NUMBER: NUMBER14, POSITIVE_NUMBER: POSITIVE_NUMBER21, TEXT_WRAP: TEXT_WRAP2, OVERFLOW_STRATEGY: OVERFLOW_STRATEGY2 } = import_ag_charts_community177._ModuleSupport; var BaseAutoSizedLabel = class extends import_ag_charts_community177._ModuleSupport.Label { constructor() { super(...arguments); this.wrapping = "on-space"; this.overflowStrategy = "ellipsis"; } }; __decorateClass2([ Validate61(TEXT_WRAP2) ], BaseAutoSizedLabel.prototype, "wrapping", 2); __decorateClass2([ Validate61(OVERFLOW_STRATEGY2) ], BaseAutoSizedLabel.prototype, "overflowStrategy", 2); __decorateClass2([ Validate61(POSITIVE_NUMBER21, { optional: true }) ], BaseAutoSizedLabel.prototype, "lineHeight", 2); __decorateClass2([ Validate61(POSITIVE_NUMBER21, { optional: true }) ], BaseAutoSizedLabel.prototype, "minimumFontSize", 2); var AutoSizedLabel = class extends BaseAutoSizedLabel { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass2([ Validate61(NUMBER14) ], AutoSizedLabel.prototype, "spacing", 2); var AutoSizedSecondaryLabel = class extends BaseAutoSizedLabel { }; var { CartesianSeriesProperties: CartesianSeriesProperties2, SeriesTooltip: SeriesTooltip7, Validate: Validate62, AND: AND5, ARRAY: ARRAY8, COLOR_STRING: COLOR_STRING14, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY5, FUNCTION: FUNCTION11, OBJECT: OBJECT29, POSITIVE_NUMBER: POSITIVE_NUMBER222, RATIO: RATIO18, STRING: STRING29, TEXT_ALIGN: TEXT_ALIGN22, VERTICAL_ALIGN: VERTICAL_ALIGN2 } = import_ag_charts_community178._ModuleSupport; var HeatmapSeriesProperties = class extends CartesianSeriesProperties2 { constructor() { super(...arguments); this.colorRange = ["black", "black"]; this.stroke = "black"; this.strokeOpacity = 1; this.strokeWidth = 0; this.textAlign = "center"; this.verticalAlign = "middle"; this.itemPadding = 0; this.label = new AutoSizedLabel(); this.tooltip = new SeriesTooltip7(); } }; __decorateClass2([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "title", 2); __decorateClass2([ Validate62(STRING29) ], HeatmapSeriesProperties.prototype, "xKey", 2); __decorateClass2([ Validate62(STRING29) ], HeatmapSeriesProperties.prototype, "yKey", 2); __decorateClass2([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "colorKey", 2); __decorateClass2([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "xName", 2); __decorateClass2([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "yName", 2); __decorateClass2([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "colorName", 2); __decorateClass2([ Validate62(AND5(COLOR_STRING_ARRAY5, ARRAY8.restrict({ minLength: 1 }))) ], HeatmapSeriesProperties.prototype, "colorRange", 2); __decorateClass2([ Validate62(COLOR_STRING14, { optional: true }) ], HeatmapSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate62(RATIO18) ], HeatmapSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate62(POSITIVE_NUMBER222, { optional: true }) ], HeatmapSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate62(TEXT_ALIGN22) ], HeatmapSeriesProperties.prototype, "textAlign", 2); __decorateClass2([ Validate62(VERTICAL_ALIGN2) ], HeatmapSeriesProperties.prototype, "verticalAlign", 2); __decorateClass2([ Validate62(POSITIVE_NUMBER222) ], HeatmapSeriesProperties.prototype, "itemPadding", 2); __decorateClass2([ Validate62(FUNCTION11, { optional: true }) ], HeatmapSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate62(OBJECT29) ], HeatmapSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate62(OBJECT29) ], HeatmapSeriesProperties.prototype, "tooltip", 2); var { SeriesNodePickMode: SeriesNodePickMode5, computeBarFocusBounds: computeBarFocusBounds4, getMissCount: getMissCount2, valueProperty: valueProperty8, ChartAxisDirection: ChartAxisDirection222, DEFAULT_CARTESIAN_DIRECTION_KEYS: DEFAULT_CARTESIAN_DIRECTION_KEYS2, DEFAULT_CARTESIAN_DIRECTION_NAMES: DEFAULT_CARTESIAN_DIRECTION_NAMES2, createDatumId: createDatumId7, ColorScale: ColorScale2, Rect: Rect5, PointerEvents: PointerEvents22, applyShapeStyle: applyShapeStyle3 } = import_ag_charts_community179._ModuleSupport; var HeatmapSeriesNodeEvent = class extends import_ag_charts_community179._ModuleSupport.CartesianSeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.colorKey = series.properties.colorKey; } }; var textAlignFactors = { left: -0.5, center: 0, right: -0.5 }; var verticalAlignFactors = { top: -0.5, middle: 0, bottom: -0.5 }; var HeatmapSeries = class extends import_ag_charts_community179._ModuleSupport.CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS2, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES2, pickModes: [SeriesNodePickMode5.NEAREST_NODE, SeriesNodePickMode5.EXACT_SHAPE_MATCH], pathsPerSeries: [], hasMarkers: false, hasHighlightedLabels: true }); this.properties = new HeatmapSeriesProperties(); this.NodeEvent = HeatmapSeriesNodeEvent; this.colorScale = new ColorScale2(); } async processData(dataController) { const xAxis = this.axes[ChartAxisDirection222.X]; const yAxis = this.axes[ChartAxisDirection222.Y]; if (!xAxis || !yAxis || !this.properties.isValid() || !this.data?.length) { return; } const { xKey, yKey, colorRange, colorKey } = this.properties; const xScale = this.axes[ChartAxisDirection222.X]?.scale; const yScale = this.axes[ChartAxisDirection222.Y]?.scale; const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const colorScaleType = this.colorScale.type; const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, { props: [ valueProperty8(xKey, xScaleType, { id: "xValue" }), valueProperty8(yKey, yScaleType, { id: "yValue" }), ...colorKey ? [valueProperty8(colorKey, colorScaleType, { id: "colorValue" })] : [] ] }); if (this.isColorScaleValid()) { const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); this.colorScale.domain = processedData.domain.values[colorKeyIdx]; this.colorScale.range = colorRange; this.colorScale.update(); } } isColorScaleValid() { const { colorKey } = this.properties; if (!colorKey) { return false; } const { dataModel, processedData } = this; if (!dataModel || !processedData) { return false; } const colorDataIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); const dataCount = processedData.input.count; const missCount = getMissCount2(this, processedData.defs.values[colorDataIdx].missing); const colorDataMissing = dataCount === 0 || dataCount === missCount; return !colorDataMissing; } xCoordinateRange(xValue, pixelSize) { const xScale = this.axes[ChartAxisDirection222.X].scale; const xOffset = pixelSize * (xScale.bandwidth ?? 0) / 2; const x = xScale.convert(xValue) + xOffset; const width2 = pixelSize * (xScale.bandwidth ?? 10); return [x, x + width2]; } yCoordinateRange(yValues, pixelSize) { const yScale = this.axes[ChartAxisDirection222.Y].scale; const yOffset = pixelSize * (yScale.bandwidth ?? 0) / 2; const y = yScale.convert(yValues[0]) + yOffset; const height2 = pixelSize * (yScale.bandwidth ?? 10); return [y, y + height2]; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!dataModel || !processedData) return []; if (direction === ChartAxisDirection222.X) { return dataModel.getDomain(this, `xValue`, "value", processedData); } else { return dataModel.getDomain(this, `yValue`, "value", processedData); } } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } createNodeData() { const { data, visible, axes, dataModel, processedData } = this; const xAxis = axes[ChartAxisDirection222.X]; const yAxis = axes[ChartAxisDirection222.Y]; if (!(data && dataModel && processedData && visible && xAxis && yAxis)) return; if (xAxis.type !== "category" || yAxis.type !== "category") { logger_exports2.warnOnce( `Heatmap series expected axes to have "category" type, but received "${xAxis.type}" and "${yAxis.type}" instead.` ); return; } const { xKey, xName, yKey, yName, colorKey, colorName, textAlign, verticalAlign, itemPadding, label } = this.properties; const xValues = dataModel.resolveColumnById(this, `xValue`, processedData); const yValues = dataModel.resolveColumnById(this, `yValue`, processedData); const colorValues = colorKey ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0; const xScale = xAxis.scale; const yScale = yAxis.scale; const xOffset = (xScale.bandwidth ?? 0) / 2; const yOffset = (yScale.bandwidth ?? 0) / 2; const nodeData = []; const labelData = []; const width2 = xScale.bandwidth ?? 10; const height2 = yScale.bandwidth ?? 10; const textAlignFactor = (width2 - 2 * itemPadding) * textAlignFactors[textAlign]; const verticalAlignFactor = (height2 - 2 * itemPadding) * verticalAlignFactors[verticalAlign]; const sizeFittingHeight = () => ({ width: width2, height: height2, meta: null }); const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const xDatum = xValues[datumIndex]; const yDatum = yValues[datumIndex]; const x = xScale.convert(xDatum) + xOffset; const y = yScale.convert(yDatum) + yOffset; const colorValue = colorValues?.[datumIndex]; const labelText = colorValue == null ? void 0 : this.getLabelText(label, { value: colorValue, datum, colorKey, colorName, xKey, yKey, xName, yName }); const labels = formatLabels( labelText, this.properties.label, void 0, this.properties.label, { padding: itemPadding }, sizeFittingHeight ); const point = { x, y, size: 0 }; nodeData.push({ series: this, itemId: yKey, datumIndex, yKey, xKey, xValue: xDatum, yValue: yDatum, colorValue, datum, point, width: width2, height: height2, midPoint: { x, y }, missing: colorValue == null }); if (labels?.label != null) { const { text: text22, fontSize, lineHeight, height: labelHeight } = labels.label; const { fontStyle, fontFamily, fontWeight, color } = this.properties.label; const lx = point.x + textAlignFactor * (width2 - 2 * itemPadding); const ly = point.y + verticalAlignFactor * (height2 - 2 * itemPadding) - (labels.height - labelHeight) * 0.5; labelData.push({ series: this, itemId: yKey, datum, datumIndex, text: text22, fontSize, lineHeight, fontStyle, fontFamily, fontWeight, color, textAlign, verticalAlign, x: lx, y: ly }); } }); return { itemId: this.properties.yKey ?? this.id, nodeData, labelData, scales: this.calculateScaling(), visible: this.visible }; } nodeFactory() { return new Rect5(); } update(params) { this.ctx.animationManager.skipCurrentBatch(); return super.update(params); } updateDatumSelection(opts) { const { nodeData, datumSelection } = opts; const data = nodeData ?? []; return datumSelection.update(data); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill, fillOpacity: highlightStyle?.fillOpacity ?? 1, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity }; } getItemStyleOverrides(datumId, datum, colorValue, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yKey, colorRange, itemStyler } = properties; const fill = this.isColorScaleValid() && colorValue != null ? this.colorScale.convert(colorValue) : colorRange[0]; let overrides = format.fill == null ? { fill } : void 0; if (itemStyler != null) { overrides ?? (overrides = {}); const itemStyle = this.cachedDatumCallback( createDatumId7(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, xKey, yKey, highlighted, fill, ...format }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateDatumNodes(opts) { const { isHighlight: isDatumHighlighted } = opts; const xAxis = this.axes[ChartAxisDirection222.X]; const [visibleMin, visibleMax] = xAxis?.visibleRange ?? []; const isZoomed = visibleMin !== 0 || visibleMax !== 1; const crisp = !isZoomed; const style = this.getItemBaseStyle(isDatumHighlighted); opts.datumSelection.each((rect, nodeDatum) => { const { datumIndex, colorValue, datum, point, width: width2, height: height2 } = nodeDatum; const overrides = this.getItemStyleOverrides( String(datumIndex), datum, colorValue, style, isDatumHighlighted ); rect.crisp = crisp; rect.x = Math.floor(point.x - width2 / 2); rect.y = Math.floor(point.y - height2 / 2); rect.width = Math.ceil(width2); rect.height = Math.ceil(height2); applyShapeStyle3(rect, style, overrides); }); } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; const { enabled } = this.properties.label; const data = enabled ? labelData : []; return labelSelection.update(data); } updateLabelNodes(opts) { opts.labelSelection.each((text22, datum) => { text22.text = datum.text; text22.fontSize = datum.fontSize; text22.lineHeight = datum.lineHeight; text22.fontStyle = datum.fontStyle; text22.fontFamily = datum.fontFamily; text22.fontWeight = datum.fontWeight; text22.fill = datum.color; text22.textAlign = datum.textAlign; text22.textBaseline = datum.verticalAlign; text22.x = datum.x; text22.y = datum.y; text22.pointerEvents = PointerEvents22.None; }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties, colorScale } = this; const { xKey, xName, yKey, yName, colorKey, colorName, colorRange, title, legendItemName, tooltip } = properties; const xAxis = axes[ChartAxisDirection222.X]; const yAxis = axes[ChartAxisDirection222.Y]; if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex]; const colorValue = colorKey != null && this.isColorScaleValid() ? dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex] : void 0; if (xValue == null) return; const data = []; let fill; if (colorValue == null) { fill = colorRange[0]; } else { fill = colorScale.convert(colorValue); data.push({ label: colorName, fallbackLabel: colorKey, value: String(colorValue) }); } data.push( { label: xName, fallbackLabel: xKey, value: xAxis.formatDatum(xValue) }, { label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(yValue) } ); const symbol = fill != null ? { marker: { shape: "square", fill, fillOpacity: 1, stroke: void 0, strokeWidth: 0, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0 } } : void 0; const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datum, colorValue, format, false)); return tooltip.formatTooltip( { title: title ?? legendItemName, symbol, data }, { seriesId, datum, title, xKey, xName, yKey, yName, colorKey, colorName, ...format } ); } getLegendData(legendType) { if (legendType !== "gradient" || !this.properties.isValid() || !this.isColorScaleValid() || !this.dataModel) { return []; } return [ { legendType: "gradient", enabled: this.visible, seriesId: this.id, colorName: this.properties.colorName, colorDomain: this.processedData.domain.values[this.dataModel.resolveProcessedDataIndexById(this, "colorValue")], colorRange: this.properties.colorRange } ]; } isLabelEnabled() { return this.properties.label.enabled && Boolean(this.properties.colorKey); } getBandScalePadding() { return { inner: 0, outer: 0 }; } computeFocusBounds({ datumIndex }) { const datum = this.contextNodeData?.nodeData[datumIndex]; if (datum === void 0) return void 0; const { width: width2, height: height2, midPoint } = datum; const focusRect = { x: midPoint.x - width2 / 2, y: midPoint.y - height2 / 2, width: width2, height: height2 }; return computeBarFocusBounds4(this, focusRect); } }; HeatmapSeries.className = "HeatmapSeries"; HeatmapSeries.type = "heatmap"; var import_ag_charts_community180 = (init_main4(), __toCommonJS(main_exports)); var HEATMAP_SERIES_THEME = { series: { label: { enabled: false, color: { $ref: "textColor" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, wrapping: "on-space", overflowStrategy: "ellipsis" }, itemPadding: 3 }, gradientLegend: { enabled: true } }; var { ThemeSymbols: { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE2, DEFAULT_BACKGROUND_COLOUR: DEFAULT_BACKGROUND_COLOUR22 }, ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE7, CARTESIAN_POSITION: CARTESIAN_POSITION4 } } = import_ag_charts_community181._ModuleSupport; var HeatmapModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "heatmap", moduleFactory: (ctx) => new HeatmapSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: [ { type: CARTESIAN_AXIS_TYPE7.CATEGORY, position: CARTESIAN_POSITION4.LEFT }, { type: CARTESIAN_AXIS_TYPE7.CATEGORY, position: CARTESIAN_POSITION4.BOTTOM } ], themeTemplate: HEATMAP_SERIES_THEME, paletteFactory: ({ takeColors, colorsCount, userPalette, themeTemplateParameters }) => { const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE2); const defaultBackgroundColor = themeTemplateParameters.get(DEFAULT_BACKGROUND_COLOUR22); const backgroundFill = (Array.isArray(defaultBackgroundColor) ? defaultBackgroundColor[0] : defaultBackgroundColor) ?? "white"; const { fills, strokes } = takeColors(colorsCount); return { stroke: userPalette === "inbuilt" ? backgroundFill : strokes[0], colorRange: userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]] }; } }; var import_ag_charts_community184 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community183 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community182 = (init_main4(), __toCommonJS(main_exports)); var AGGREGATION_THRESHOLD3 = 1e3; var MAX_POINTS = 10; function aggregationContainsIndex(xValues, d0, d1, indexData, maxRange, datumIndex) { const xValue = xValues[datumIndex]; if (xValue == null) return false; const xRatio = xRatioForDatumIndex(xValue, d0, d1); const aggIndex = aggregationIndexForXRatio(xRatio, maxRange); return datumIndex === indexData[aggIndex + X_MIN2] || datumIndex === indexData[aggIndex + X_MAX2] || datumIndex === indexData[aggIndex + Y_MIN2] || datumIndex === indexData[aggIndex + Y_MAX2]; } function aggregateLineData(xValues, yValues, domain) { if (xValues.length < AGGREGATION_THRESHOLD3) return; const [d0, d1] = aggregationDomain(domain); let maxRange = maxRangeFittingPoints(xValues, MAX_POINTS); const { indexData, valueData } = createAggregationIndices(xValues, yValues, yValues, d0, d1, maxRange); let indices = []; for (let datumIndex = 0; datumIndex < xValues.length; datumIndex += 1) { if (aggregationContainsIndex(xValues, d0, d1, indexData, maxRange, datumIndex)) { indices.push(datumIndex); } } const filters = [{ maxRange, indices }]; while (indices.length > MAX_POINTS && maxRange > 64) { ({ maxRange } = compactAggregationIndices(indexData, valueData, maxRange, { inPlace: true })); indices = indices.filter(aggregationContainsIndex.bind(null, xValues, d0, d1, indexData, maxRange)); filters.push({ maxRange, indices }); } filters.reverse(); return filters; } var { ChartAxisDirection: ChartAxisDirection23, ContinuousScale: ContinuousScale6, OrdinalTimeScale: OrdinalTimeScale4 } = import_ag_charts_community183._ModuleSupport; var LineSeries2 = class extends import_ag_charts_community183._ModuleSupport.LineSeries { aggregateData(dataModel, processedData) { const xAxis = this.axes[ChartAxisDirection23.X]; if (xAxis == null || !(ContinuousScale6.is(xAxis.scale) || OrdinalTimeScale4.is(xAxis.scale))) return; const xValues = dataModel.resolveColumnById(this, `xValue`, processedData); const yValues = dataModel.resolveColumnById(this, `yValueRaw`, processedData); const domain = dataModel.getDomain(this, `xValue`, "value", processedData); return aggregateLineData(xValues, yValues, domain); } }; var { LineSeriesModule: LineSeriesModule2 } = import_ag_charts_community184._ModuleSupport; var LineModule = { ...LineSeriesModule2, type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "line", moduleFactory: (ctx) => new LineSeries2(ctx) }; var import_ag_charts_community193 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community185 = (init_main4(), __toCommonJS(main_exports)); var { ColorScale: ColorScale22 } = import_ag_charts_community185._ModuleSupport; function defaultColorStops(colors) { if (colors == null) return []; const colorScale = new ColorScale22(); colorScale.domain = [0, 1]; colorScale.range = colors; const stopCount = 5; return Array.from({ length: 5 }, (_, i) => { return colorScale.convert(i / (stopCount - 1)); }); } var import_ag_charts_community192 = (init_main4(), __toCommonJS(main_exports)); var DatumUnion = class { *[Symbol.iterator]() { const { node, datum } = this; if (node && datum) yield { node, datum }; } nodes() { return this.node ? [this.node] : []; } update(datumSelection, group, ctor, nodeUpdater) { const nodes = datumSelection.nodes(); if (nodes.length === 0) { this.node?.remove(); this.node = void 0; } else { if (this.node === void 0) { this.node = new ctor(); this.node.fillOpacity = 0; this.node.strokeOpacity = 0; group.appendChild(this.node); } const first2 = nodes[0]; const last = nodes.toReversed().find((n) => n.datum.datum.value > n.datum.datum.segmentStart) ?? nodes[nodes.length - 1]; this.node.datum = this.datum = first2.datum; nodeUpdater(this.node, first2, last); } } }; var fadeInFns = { fromFn: () => ({ opacity: 0, phase: "initial" }), toFn: () => ({ opacity: 1 }) }; function formatLabel(value, axis) { if (value == null) return ""; if (axis == null) return String(value); const [min, max] = axis.scale.domain; const minLog10 = min !== 0 ? Math.ceil(Math.log10(Math.abs(min))) : 0; const maxLog10 = max !== 0 ? Math.ceil(Math.log10(Math.abs(max))) : 0; const dp = Math.max(2 - Math.max(minLog10, maxLog10), 0); return value.toFixed(dp); } function getLabelText(series, datum, valueOverride) { if (datum.text != null) return datum.text; const value = valueOverride ?? datum.value; const labelFormat = datum?.formatter?.({ seriesId: series.id, datum: void 0, value }); if (labelFormat != null) return String(labelFormat); } var import_ag_charts_community186 = (init_main4(), __toCommonJS(main_exports)); function lineMarker({ path, x, y, size }) { path.moveTo(x, y - size / 2); path.lineTo(x, y + size / 2); } var import_ag_charts_community187 = (init_main4(), __toCommonJS(main_exports)); var { clamp: clamp8 } = import_ag_charts_community187._ModuleSupport; function pickGaugeNearestDatum(self, point) { const it = iterate2(self.datumUnion.nodes(), self.targetSelection.nodes()); return self.pickNodeNearestDistantObject(point, it); } function pickGaugeFocus(self, opts) { const others = [ { data: self.contextNodeData?.nodeData, selection: self.datumUnion }, { data: self.contextNodeData?.targetData, selection: self.targetSelection } ].filter((v) => v.data && v.data.length > 0); const otherIndex = clamp8(0, opts.otherIndex + opts.otherIndexDelta, others.length - 1); if (others.length === 0) return; const { data, selection } = others[otherIndex]; if (data == null || data.length === 0) return; const datumIndex = clamp8(0, opts.datumIndex, data.length - 1); const datum = data[datumIndex]; for (const node of selection) { if (node.datum === datum) { const bounds = node.node; return { bounds, clipFocusBox: true, datum, datumIndex, otherIndex }; } } } var import_ag_charts_community188 = (init_main4(), __toCommonJS(main_exports)); var { MARKER_SHAPE: MARKER_SHAPE2, UNION: UNION13, OR: OR5 } = import_ag_charts_community188._ModuleSupport; var FILL_MODE = UNION13(["continuous", "discrete"], "a fill mode"); var TARGET_MARKER_SHAPE = OR5(MARKER_SHAPE2, UNION13(["line"], "a marker shape")); var CORNER_MODE = UNION13(["container", "item"], "a corner mode"); function parseUnknownGaugeNodeDatum(nodeDatum) { let value; let text22; if (typeof nodeDatum.value === "number") value = nodeDatum.value; if (typeof nodeDatum.text === "string") text22 = nodeDatum.text; return { value, text: text22 }; } var import_ag_charts_community190 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community189 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties24, Validate: Validate63, OBJECT: OBJECT30, BOOLEAN: BOOLEAN28, NUMBER: NUMBER15, NUMBER_ARRAY: NUMBER_ARRAY2 } = import_ag_charts_community189._ModuleSupport; var GaugeSegmentationIntervalProperties = class extends BaseProperties24 { getSegments(scale2, maxTicks) { const { values, step, count } = this; const d0 = Math.min(...scale2.domain); const d1 = Math.max(...scale2.domain); let ticks; if (values != null) { const segments = values.filter((v) => v > d0 && v < d1).sort((a, b) => a - b); ticks = [d0, ...segments, d1]; } else if (step != null) { const segments = []; for (let i = d0; i < d1; i += step) { segments.push(i); } segments.push(d1); ticks = segments; } else if (count != null) { const segments = count + 1; ticks = Array.from({ length: segments + 1 }, (_, i) => i / segments * (d1 - d0) + d0); } else { const segments = scale2.ticks({ nice: true, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity })?.filter((v) => v > d0 && v < d1); ticks = segments != null ? [d0, ...segments, d1] : void 0; } if (ticks != null && ticks.length > maxTicks) { logger_exports2.warnOnce( `the configured segmentation results in more than 1 item per pixel, ignoring. Supply a segmentation configuration that results in larger segments or omit this configuration` ); ticks = void 0; } ticks ?? (ticks = [d0, d1]); return ticks; } }; __decorateClass2([ Validate63(NUMBER_ARRAY2, { optional: true }) ], GaugeSegmentationIntervalProperties.prototype, "values", 2); __decorateClass2([ Validate63(NUMBER15, { optional: true }) ], GaugeSegmentationIntervalProperties.prototype, "step", 2); __decorateClass2([ Validate63(NUMBER15, { optional: true }) ], GaugeSegmentationIntervalProperties.prototype, "count", 2); var GaugeSegmentationProperties = class extends BaseProperties24 { constructor() { super(...arguments); this.enabled = false; this.interval = new GaugeSegmentationIntervalProperties(); this.spacing = 0; } }; __decorateClass2([ Validate63(BOOLEAN28) ], GaugeSegmentationProperties.prototype, "enabled", 2); __decorateClass2([ Validate63(OBJECT30) ], GaugeSegmentationProperties.prototype, "interval", 2); __decorateClass2([ Validate63(NUMBER15) ], GaugeSegmentationProperties.prototype, "spacing", 2); var { BaseProperties: BaseProperties25, SeriesTooltip: SeriesTooltip8, SeriesProperties: SeriesProperties22, PropertiesArray: PropertiesArray6, Validate: Validate64, BOOLEAN: BOOLEAN29, COLOR_STRING: COLOR_STRING15, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY6, FUNCTION: FUNCTION12, LINE_DASH: LINE_DASH11, NUMBER: NUMBER16, OBJECT_ARRAY: OBJECT_ARRAY2, OBJECT: OBJECT31, POSITIVE_NUMBER: POSITIVE_NUMBER23, RATIO: RATIO19, STRING: STRING30, UNION: UNION14, Label: Label6 } = import_ag_charts_community190._ModuleSupport; var TARGET_PLACEMENT = UNION14(["before", "after", "middle"], "a placement"); var LABEL_PLACEMENT2 = UNION14( [ "inside-start", "outside-start", "inside-end", "outside-end", "inside-center", "bar-inside", "bar-inside-end", "bar-outside-end", "bar-end" ], "an placement" ); var DIRECTION2 = UNION14(["horizontal", "vertical"], "an orientation"); var LinearGaugeDefaultTargetLabelProperties = class extends Label6 { }; __decorateClass2([ Validate64(NUMBER16, { optional: true }) ], LinearGaugeDefaultTargetLabelProperties.prototype, "spacing", 2); var LinearGaugeTargetProperties = class extends BaseProperties25 { constructor() { super(...arguments); this.value = 0; this.label = new LinearGaugeDefaultTargetLabelProperties(); } }; __decorateClass2([ Validate64(STRING30, { optional: true }) ], LinearGaugeTargetProperties.prototype, "text", 2); __decorateClass2([ Validate64(NUMBER16) ], LinearGaugeTargetProperties.prototype, "value", 2); __decorateClass2([ Validate64(TARGET_MARKER_SHAPE, { optional: true }) ], LinearGaugeTargetProperties.prototype, "shape", 2); __decorateClass2([ Validate64(TARGET_PLACEMENT, { optional: true }) ], LinearGaugeTargetProperties.prototype, "placement", 2); __decorateClass2([ Validate64(NUMBER16, { optional: true }) ], LinearGaugeTargetProperties.prototype, "spacing", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeTargetProperties.prototype, "size", 2); __decorateClass2([ Validate64(NUMBER16, { optional: true }) ], LinearGaugeTargetProperties.prototype, "rotation", 2); __decorateClass2([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeTargetProperties.prototype, "fill", 2); __decorateClass2([ Validate64(RATIO19, { optional: true }) ], LinearGaugeTargetProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeTargetProperties.prototype, "stroke", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeTargetProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate64(RATIO19, { optional: true }) ], LinearGaugeTargetProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate64(LINE_DASH11, { optional: true }) ], LinearGaugeTargetProperties.prototype, "lineDash", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeTargetProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeTargetProperties.prototype, "label", 2); var LinearGaugeBarProperties = class extends BaseProperties25 { constructor() { super(...arguments); this.enabled = true; this.thicknessRatio = 1; this.fills = new PropertiesArray6(import_ag_charts_community190._ModuleSupport.StopProperties); this.fillMode = "continuous"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 0; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate64(BOOLEAN29) ], LinearGaugeBarProperties.prototype, "enabled", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeBarProperties.prototype, "thickness", 2); __decorateClass2([ Validate64(RATIO19) ], LinearGaugeBarProperties.prototype, "thicknessRatio", 2); __decorateClass2([ Validate64(OBJECT_ARRAY2) ], LinearGaugeBarProperties.prototype, "fills", 2); __decorateClass2([ Validate64(FILL_MODE) ], LinearGaugeBarProperties.prototype, "fillMode", 2); __decorateClass2([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeBarProperties.prototype, "fill", 2); __decorateClass2([ Validate64(RATIO19) ], LinearGaugeBarProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate64(COLOR_STRING15) ], LinearGaugeBarProperties.prototype, "stroke", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeBarProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate64(RATIO19) ], LinearGaugeBarProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate64(LINE_DASH11) ], LinearGaugeBarProperties.prototype, "lineDash", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeBarProperties.prototype, "lineDashOffset", 2); var LinearGaugeScaleProperties = class extends BaseProperties25 { constructor() { super(...arguments); this.fills = new PropertiesArray6(import_ag_charts_community190._ModuleSupport.StopProperties); this.fillMode = "continuous"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 0; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.defaultFill = "black"; } }; __decorateClass2([ Validate64(OBJECT_ARRAY2) ], LinearGaugeScaleProperties.prototype, "fills", 2); __decorateClass2([ Validate64(FILL_MODE) ], LinearGaugeScaleProperties.prototype, "fillMode", 2); __decorateClass2([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeScaleProperties.prototype, "fill", 2); __decorateClass2([ Validate64(RATIO19) ], LinearGaugeScaleProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate64(COLOR_STRING15) ], LinearGaugeScaleProperties.prototype, "stroke", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeScaleProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate64(RATIO19) ], LinearGaugeScaleProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate64(LINE_DASH11) ], LinearGaugeScaleProperties.prototype, "lineDash", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeScaleProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate64(COLOR_STRING15) ], LinearGaugeScaleProperties.prototype, "defaultFill", 2); var LinearGaugeLabelProperties = class extends AutoSizedLabel { constructor() { super(...arguments); this.placement = "inside-center"; this.avoidCollisions = true; } }; __decorateClass2([ Validate64(STRING30, { optional: true }) ], LinearGaugeLabelProperties.prototype, "text", 2); __decorateClass2([ Validate64(LABEL_PLACEMENT2) ], LinearGaugeLabelProperties.prototype, "placement", 2); __decorateClass2([ Validate64(BOOLEAN29) ], LinearGaugeLabelProperties.prototype, "avoidCollisions", 2); var LinearGaugeSeriesProperties = class extends SeriesProperties22 { constructor() { super(...arguments); this.value = 0; this.segmentation = new GaugeSegmentationProperties(); this.defaultColorRange = []; this.targets = new PropertiesArray6(LinearGaugeTargetProperties); this.defaultTarget = new LinearGaugeTargetProperties(); this.direction = "vertical"; this.thickness = 1; this.cornerRadius = 0; this.cornerMode = "container"; this.margin = 0; this.scale = new LinearGaugeScaleProperties(); this.bar = new LinearGaugeBarProperties(); this.label = new LinearGaugeLabelProperties(); this.tooltip = new SeriesTooltip8(); } }; __decorateClass2([ Validate64(NUMBER16) ], LinearGaugeSeriesProperties.prototype, "value", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "segmentation", 2); __decorateClass2([ Validate64(COLOR_STRING_ARRAY6) ], LinearGaugeSeriesProperties.prototype, "defaultColorRange", 2); __decorateClass2([ Validate64(OBJECT_ARRAY2) ], LinearGaugeSeriesProperties.prototype, "targets", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "defaultTarget", 2); __decorateClass2([ Validate64(DIRECTION2) ], LinearGaugeSeriesProperties.prototype, "direction", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeSeriesProperties.prototype, "thickness", 2); __decorateClass2([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeSeriesProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate64(CORNER_MODE) ], LinearGaugeSeriesProperties.prototype, "cornerMode", 2); __decorateClass2([ Validate64(NUMBER16) ], LinearGaugeSeriesProperties.prototype, "margin", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "scale", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "bar", 2); __decorateClass2([ Validate64(FUNCTION12, { optional: true }) ], LinearGaugeSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "tooltip", 2); var import_ag_charts_community191 = (init_main4(), __toCommonJS(main_exports)); var { CachedTextMeasurerPool: CachedTextMeasurerPool5, BBox: BBox13 } = import_ag_charts_community191._ModuleSupport; function datumRect(datum) { const { x0, y0, x1, y1, horizontalInset, verticalInset } = datum; const x = Math.min(x0, x1) + horizontalInset; const y = Math.min(y0, y1) + verticalInset; const width2 = Math.max(Math.abs(x1 - x0) - 2 * horizontalInset, 0); const height2 = Math.max(Math.abs(y1 - y0) - 2 * verticalInset, 0); return { x, y, width: width2, height: height2 }; } function clipBBoxVisibility(datum, clipBBox) { if (clipBBox == null) return true; const rect = datumRect(datum); const delta4 = 1e-6; const x0 = rect.x + delta4; const y0 = rect.y + delta4; const x1 = rect.x + rect.width - delta4; const y1 = rect.y + rect.height - delta4; const clipX0 = clipBBox.x; const clipX1 = clipBBox.x + clipBBox.width; const clipY0 = clipBBox.y; const clipY1 = clipBBox.y + clipBBox.height; return Math.max(x0, clipX0) <= Math.min(x1, clipX1) && Math.max(y0, clipY0) <= Math.min(y1, clipY1); } function hasClipBBox(datum) { const { clipX0, clipX1, clipY0, clipY1 } = datum; return clipX0 != null && clipX1 != null || clipY0 != null && clipY1 != null; } function computeClipBBox(datum) { if (!hasClipBBox(datum)) return; const { x0, y0, x1, y1 } = datum; const { x, y, width: width2, height: height2 } = datumRect(datum); let { clipX0, clipX1, clipY0, clipY1 } = datum; if (clipX0 == null || clipX1 == null) { clipX0 = x0; clipX1 = x1; } if (clipY0 == null || clipY1 == null) { clipY0 = y0; clipY1 = y1; } const clipX = Math.min(clipX0, clipX1); const clipY = Math.min(clipY0, clipY1); const clipWidth = Math.abs(clipX1 - clipX0); const clipHeight = Math.abs(clipY1 - clipY0); clipX0 = Math.max(x, clipX); clipY0 = Math.max(y, clipY); clipX1 = Math.min(x + width2, clipX + clipWidth); clipY1 = Math.min(y + height2, clipY + clipHeight); return new BBox13( Math.min(clipX0, clipX1), Math.min(clipY0, clipY1), Math.abs(clipX1 - clipX0), Math.abs(clipY1 - clipY0) ); } function prepareLinearGaugeSeriesAnimationFunctions(initialLoad, horizontal) { const phase = initialLoad ? "initial" : "update"; const node = { fromFn(sect, datum) { const previousDatum = sect.previousDatum; let { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1 } = previousDatum ?? datum; const { horizontalInset, verticalInset } = datum; const previousHadClipBBox = previousDatum != null && hasClipBBox(previousDatum); const nextHasClipBBox = hasClipBBox(datum); if (previousHadClipBBox && nextHasClipBBox) { } else if (!previousHadClipBBox && nextHasClipBBox) { ({ x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1 } = datum); if (initialLoad) { if (horizontal) { clipX1 = datum.clipX0; } else { clipY1 = datum.clipY0; } } } else if (previousHadClipBBox && !nextHasClipBBox) { ({ x0, y0, x1, y1 } = datum); clipX0 = void 0; clipY0 = void 0; clipX1 = void 0; clipY1 = void 0; } else if (initialLoad) { if (horizontal) { x1 = x0; } else { y1 = y0; } } return { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1, horizontalInset, verticalInset, phase }; }, toFn(_sect, datum) { const { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1, horizontalInset, verticalInset } = datum; return { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1, horizontalInset, verticalInset }; }, applyFn(rect, params) { rect.setProperties(resetLinearGaugeSeriesResetRectFunction(rect, params)); } }; return { node }; } function resetLinearGaugeSeriesResetRectFunction(_node, datum) { const { x, y, width: width2, height: height2 } = datumRect(datum); const clipBBox = computeClipBBox(datum); const visible = clipBBoxVisibility(datum, clipBBox); return { x, y, width: width2, height: height2, clipBBox, visible }; } var horizontalTextAligns = { [ "Before" /* Before */ ]: "right", [ "Center" /* Center */ ]: "center", [ "After" /* After */ ]: "left" }; var verticalTextBaselines = { [ "Before" /* Before */ ]: "top", [ "Center" /* Center */ ]: "middle", [ "After" /* After */ ]: "bottom" }; var horizontalAlignFactors = { [ "Before" /* Before */ ]: -1, [ "Center" /* Center */ ]: -0.5, [ "After" /* After */ ]: 0 }; var verticalAlignFactors2 = { [ "Before" /* Before */ ]: 0, [ "Center" /* Center */ ]: -0.5, [ "After" /* After */ ]: -1 }; function formatLinearGaugeLabels(series, selection, opts, bboxes, datumOverrides) { const { scale: scale2, bar } = bboxes; const { padding, horizontal } = opts; selection.each((label, labelDatum) => { const labelText = getLabelText(series, labelDatum, datumOverrides?.label); const sizeFittingHeight = () => ({ width: scale2.width, height: scale2.height, meta: null }); let layout; const sizeToFit = labelDatum.avoidCollisions && labelDatum.placement !== "outside-start" && labelDatum.placement !== "outside-end"; if (labelText == null) { return; } else if (sizeToFit) { const labelMeta = formatSingleLabel(labelText, labelDatum, { padding }, sizeFittingHeight); layout = labelMeta?.[0]; } else { const font22 = { fontSize: labelDatum.fontSize, fontStyle: labelDatum.fontStyle, fontWeight: labelDatum.fontWeight, fontFamily: labelDatum.fontFamily, lineHeight: labelDatum.lineHeight }; const { width: width2, height: height2 } = CachedTextMeasurerPool5.measureText(labelText, { font: font22 }); layout = { text: labelText, fontSize: labelDatum.fontSize, lineHeight: getLineHeight(labelDatum, labelDatum.fontSize), width: width2, height: height2 }; } if (layout == null) { label.visible = false; return; } const scale0 = horizontal ? scale2.x : scale2.y + scale2.height; const scale1 = horizontal ? scale2.x + scale2.width : scale2.y; const bar0 = horizontal ? bar.x : bar.y + bar.height; const bar1 = horizontal ? bar.x + bar.width : bar.y; const offset4 = labelDatum.spacing * (horizontal ? 1 : -1); let bounds0; let bounds1; let s; let align2; switch (labelDatum.placement) { case "outside-start": bounds0 = -Infinity; bounds1 = Infinity; s = scale0 - offset4; align2 = "Before"; break; case "outside-end": bounds0 = -Infinity; bounds1 = Infinity; s = scale1 + offset4; align2 = "After"; break; case "inside-start": bounds0 = scale0; bounds1 = bar1; s = scale0 + offset4; align2 = "After"; break; case "inside-end": bounds0 = bar1; bounds1 = scale1; s = scale1 - offset4; align2 = "Before"; break; case "inside-center": bounds0 = scale0; bounds1 = scale1; s = (scale0 + scale1) / 2; align2 = "Center"; break; case "bar-inside": bounds0 = bar0; bounds1 = bar1; s = (bar0 + bar1) / 2; align2 = "Center"; break; case "bar-inside-end": bounds0 = bar0; bounds1 = bar1; s = bar1 - offset4; align2 = "Before"; break; case "bar-outside-end": bounds0 = bar1; bounds1 = scale1; s = bar1 + offset4; align2 = "After"; break; case "bar-end": bounds0 = -Infinity; bounds1 = Infinity; s = bar1; align2 = "Center"; break; } const x = horizontal ? s : scale2.x + scale2.width / 2; const y = horizontal ? scale2.y + scale2.height / 2 : s; let s0; let s1; if (horizontal) { s0 = x + horizontalAlignFactors[align2] * layout.width; s1 = s0 + layout.width; } else { s0 = y + verticalAlignFactors2[align2] * layout.height; s1 = s0 + layout.height; } const inside = Math.min(s0, s1) >= Math.min(bounds0, bounds1) && Math.max(s0, s1) <= Math.max(bounds0, bounds1); if (labelDatum.avoidCollisions && !inside) { label.visible = false; return; } label.visible = true; label.text = layout.text; label.fontSize = layout.fontSize; label.lineHeight = layout.lineHeight; label.textAlign = horizontal ? horizontalTextAligns[align2] : "center"; label.textBaseline = horizontal ? "middle" : verticalTextBaselines[align2]; label.x = x; label.y = y; }); } var { fromToMotion: fromToMotion2, resetMotion: resetMotion22, SeriesNodePickMode: SeriesNodePickMode6, StateMachine: StateMachine12, createDatumId: createDatumId8, ChartAxisDirection: ChartAxisDirection24, CachedTextMeasurerPool: CachedTextMeasurerPool6, toRadians: toRadians5, BBox: BBox14, Group: Group11, PointerEvents: PointerEvents3, Selection: Selection6, Rect: Rect6, Text: Text22, LinearGradient: LinearGradient22, Marker: Marker22, easing, getColorStops: getColorStops2 } = import_ag_charts_community192._ModuleSupport; var horizontalTargetPlacementRotation = { before: 180, middle: 0, after: 0 }; var verticalTargetPlacementRotation = { before: 90, middle: 0, after: -90 }; var LinearGaugeSeries = class extends import_ag_charts_community192._ModuleSupport.Series { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode6.EXACT_SHAPE_MATCH, SeriesNodePickMode6.NEAREST_NODE] }); this.canHaveAxes = true; this.properties = new LinearGaugeSeriesProperties(); this.originX = 0; this.originY = 0; this.scaleGroup = this.contentGroup.appendChild(new Group11({ name: "scaleGroup" })); this.itemGroup = this.contentGroup.appendChild(new Group11({ name: "itemGroup" })); this.itemTargetGroup = this.contentGroup.appendChild(new Group11({ name: "itemTargetGroup" })); this.itemTargetLabelGroup = this.contentGroup.appendChild(new Group11({ name: "itemTargetLabelGroup" })); this.itemLabelGroup = this.contentGroup.appendChild(new Group11({ name: "itemLabelGroup" })); this.highlightTargetGroup = this.highlightGroup.appendChild( new Group11({ name: "itemTargetLabelGroup" }) ); this.scaleSelection = Selection6.select( this.scaleGroup, () => this.nodeFactory() ); this.datumSelection = Selection6.select( this.itemGroup, () => this.nodeFactory() ); this.targetSelection = Selection6.select( this.itemTargetGroup, () => this.markerFactory() ); this.targetLabelSelection = Selection6.select(this.itemTargetLabelGroup, Text22); this.labelSelection = Selection6.select( this.itemLabelGroup, Text22 ); this.highlightTargetSelection = Selection6.select(this.highlightTargetGroup, () => this.markerFactory()); this.datumUnion = new DatumUnion(); this.animationState = new StateMachine12("empty", { empty: { update: { target: "ready", action: () => this.animateEmptyUpdateReady() }, reset: "empty", skip: "ready" }, ready: { updateData: "waiting", clear: "clearing", resize: () => this.animateReadyResize(), reset: "empty", skip: "ready" }, waiting: { update: { target: "ready", action: () => this.animateWaitingUpdateReady() }, reset: "empty", skip: "ready" }, clearing: { update: { target: "empty" }, reset: "empty", skip: "ready" } }); this.scaleGroup.pointerEvents = PointerEvents3.None; } get horizontal() { return this.properties.direction === "horizontal"; } get thickness() { return this.properties.thickness; } computeInset(direction, ticks) { const { label } = this.properties; let factor; switch (label.placement) { case "outside-start": factor = 1; break; case "outside-end": factor = -1; break; default: return 0; } const lines = label.text?.split("\n"); let size; if (direction === ChartAxisDirection24.Y) { size = getLineHeight(label, label.fontSize) * (lines?.length ?? 1); } else { const font22 = label.getFont(); const linesOrTicks = lines ?? ticks.map((tick) => getLabelText(this, this.labelDatum(label, tick)) ?? ""); size = linesOrTicks.reduce((accum, text22) => { const { width: width2 } = CachedTextMeasurerPool6.measureText(text22, { font: font22 }); return Math.max(accum, width2); }, 0); } return factor * (label.spacing + size); } get hasData() { return true; } nodeFactory() { const rect = new Rect6(); rect.crisp = true; return rect; } markerFactory() { return new Marker22(); } processData() { this.nodeDataRefresh = true; this.animationState.transition("updateData"); } formatLabel(value) { const { axes, horizontal } = this; const mainAxis = horizontal ? axes[ChartAxisDirection24.X] : axes[ChartAxisDirection24.Y]; return formatLabel(value, mainAxis); } createLinearGradient(fills, fillMode) { const { properties, originX, originY, horizontal, axes } = this; const { thickness, defaultColorRange } = properties; const mainAxis = horizontal ? axes[ChartAxisDirection24.X] : axes[ChartAxisDirection24.Y]; const { domain, range: range22 } = mainAxis.scale; const length2 = range22[1] - range22[0]; const stops = getColorStops2(fills, defaultColorRange, domain, fillMode); return new LinearGradient22( "oklch", stops, horizontal ? 90 : 0, new BBox14(originX, originY, horizontal ? length2 : thickness, horizontal ? thickness : length2) ); } getTargets() { const { properties } = this; const defaultTarget = properties.defaultTarget; return Array.from(properties.targets).map((target) => { const { text: text22 = defaultTarget.text, value = defaultTarget.value ?? 0, shape = defaultTarget.shape ?? "triangle", rotation = defaultTarget.rotation ?? 0, strokeWidth = defaultTarget.strokeWidth ?? 0, placement = defaultTarget.placement ?? "middle", spacing = defaultTarget.spacing ?? 0, size = defaultTarget.size ?? 0, fill = defaultTarget.fill ?? "black", fillOpacity = defaultTarget.fillOpacity ?? 1, stroke: stroke22 = defaultTarget.stroke ?? "black", strokeOpacity = defaultTarget.strokeOpacity ?? 1, lineDash = defaultTarget.lineDash ?? [0], lineDashOffset = defaultTarget.lineDashOffset ?? 0 } = target; const { enabled: labelEnabled = defaultTarget.label.enabled, color: labelColor = defaultTarget.label.color ?? "black", fontStyle: labelFontStyle = defaultTarget.label.fontStyle ?? "normal", fontWeight: labelFontWeight = defaultTarget.label.fontWeight ?? "normal", fontSize: labelFontSize = defaultTarget.label.fontSize, fontFamily: labelFontFamily = defaultTarget.label.fontFamily, spacing: labelSpacing = defaultTarget.label.spacing ?? 0 } = target.label; return { text: text22, value, shape, placement, spacing, size, rotation, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, label: { enabled: labelEnabled, color: labelColor, fontStyle: labelFontStyle, fontWeight: labelFontWeight, fontSize: labelFontSize, fontFamily: labelFontFamily, spacing: labelSpacing } }; }); } getTargetPoint(target) { const xAxis = this.axes[ChartAxisDirection24.X]; const yAxis = this.axes[ChartAxisDirection24.Y]; if (xAxis == null || yAxis == null) return { x: 0, y: 0 }; const { properties, originX, originY, horizontal } = this; const { thickness } = properties; const { value, placement, spacing, size } = target; const mainAxis = horizontal ? xAxis : yAxis; const mainOffset = mainAxis.scale.convert(value) - mainAxis.scale.range[0]; let crossOffset; switch (placement) { case "before": crossOffset = -(spacing + size / 2); break; case "after": crossOffset = thickness + spacing + size / 2; break; default: crossOffset = thickness / 2; break; } return { x: originX + xAxis.range[0] + (horizontal ? mainOffset : crossOffset), y: originY + yAxis.range[0] + (horizontal ? crossOffset : mainOffset) }; } getTargetLabel(target) { const { size, placement, label } = target; const { spacing, color: fill, fontStyle, fontWeight, fontSize, fontFamily } = label; const lineHeight = void 0; const offset4 = size / 2 + spacing; let textAlign; let textBaseline; let offsetX = 0; let offsetY = 0; if (this.horizontal) { textAlign = "center"; if (placement === "after") { textBaseline = "top"; offsetY = offset4; } else { textBaseline = "bottom"; offsetY = -offset4; } } else { textBaseline = "middle"; if (placement === "before") { textAlign = "right"; offsetX = -offset4; } else { textAlign = "left"; offsetX = offset4; } } return { offsetX, offsetY, fill, textAlign, textBaseline, fontStyle, fontWeight, fontSize, fontFamily, lineHeight }; } labelDatum(label, value) { const { placement, avoidCollisions, spacing, text: text22, color: fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, wrapping, overflowStrategy, formatter = (params) => this.formatLabel(params.value) } = label; return { placement, avoidCollisions, spacing, text: text22, value, fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, wrapping, overflowStrategy, formatter }; } createNodeData() { const { id: seriesId, properties, originX, originY, horizontal } = this; if (!properties.isValid()) return; const { value, segmentation, thickness, cornerRadius, cornerMode, bar, scale: scale2, label } = properties; const targets = this.getTargets(); const xAxis = this.axes[ChartAxisDirection24.X]; const yAxis = this.axes[ChartAxisDirection24.Y]; if (xAxis == null || yAxis == null) return; const mainAxis = horizontal ? xAxis : yAxis; const xScale = xAxis.scale; const yScale = yAxis.scale; const mainAxisScale = mainAxis.scale; let { domain } = mainAxis.scale; if (mainAxis.isReversed()) { domain = domain.slice().reverse(); } const nodeData = []; const targetData = []; const labelData = []; const scaleData = []; const [m0, m1] = mainAxisScale.range; const mainAxisSize = Math.abs(m1 - m0); let [x0, x1] = xAxis.range; if (xAxis.isReversed()) { [x1, x0] = [x0, x1]; } let [y0, y1] = yAxis.range; if (yAxis.isReversed()) { [y1, y0] = [y0, y1]; } const containerX = horizontal ? xScale.convert(value) : x1; const containerY = horizontal ? y1 : yScale.convert(value); const inset = segmentation.enabled ? segmentation.spacing / 2 : 0; const horizontalInset = horizontal ? inset : 0; const verticalInset = horizontal ? 0 : inset; const barThickness = Math.min(bar.thickness ?? Math.round(bar.thicknessRatio * thickness), thickness); const barInset = -(thickness - barThickness) / 2; const barXInset = horizontal ? 0 : barInset; const barYInset = horizontal ? barInset : 0; const cornersOnAllItems = cornerMode === "item"; const maxTicks = Math.ceil(mainAxisSize); let segments = segmentation.enabled ? segmentation.interval.getSegments(mainAxisScale, maxTicks) : void 0; const barFill = bar.fill ?? this.createLinearGradient(bar.fills, bar.fillMode); const scaleFill = scale2.fill ?? (bar.enabled && scale2.fills.length === 0 ? scale2.defaultFill : void 0) ?? this.createLinearGradient(scale2.fills, scale2.fillMode); if (segments == null && cornersOnAllItems) { const segmentStart = Math.min(...domain); const segmentEnd = Math.max(...domain); const datum = { value, segmentStart, segmentEnd }; if (bar.enabled) { const barAppliedCornerRadius = Math.min(cornerRadius, barThickness / 2, mainAxisSize / 2); const barCornerInset = barAppliedCornerRadius * (mainAxis.isReversed() ? -1 : 1); const barCornerXInset = horizontal ? barCornerInset : 0; const barCornerYInset = horizontal ? 0 : barCornerInset; nodeData.push({ series: this, itemId: `value`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, x0: originX + x0 - barCornerXInset - barXInset, y0: originY + y0 - barCornerYInset - barYInset, x1: originX + containerX + barCornerXInset + barXInset, y1: originY + containerY + barCornerYInset + barYInset, clipX0: void 0, clipY0: void 0, clipX1: void 0, clipY1: void 0, topLeftCornerRadius: cornerRadius, topRightCornerRadius: cornerRadius, bottomRightCornerRadius: cornerRadius, bottomLeftCornerRadius: cornerRadius, fill: barFill, horizontalInset, verticalInset }); } const scaleAppliedCornerRadius = Math.min(cornerRadius, thickness / 2, mainAxisSize / 2); const scaleCornerInset = scaleAppliedCornerRadius * (mainAxis.isReversed() ? -1 : 1); const scaleCornerXInset = horizontal ? scaleCornerInset : 0; const scaleCornerYInset = horizontal ? 0 : scaleCornerInset; scaleData.push({ series: this, itemId: `scale`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, x0: originX + x0 - scaleCornerXInset, y0: originY + y0 - scaleCornerYInset, x1: originX + x1 + scaleCornerXInset, y1: originY + y1 + scaleCornerYInset, clipX0: void 0, clipY0: void 0, clipX1: void 0, clipY1: void 0, topLeftCornerRadius: cornerRadius, topRightCornerRadius: cornerRadius, bottomRightCornerRadius: cornerRadius, bottomLeftCornerRadius: cornerRadius, fill: scaleFill, horizontalInset, verticalInset }); } else { segments ?? (segments = domain); const clipX0 = originX + x0 - barXInset; const clipY0 = originY + y0 - barYInset; const clipX1 = originX + containerX + barXInset; const clipY1 = originY + containerY + barYInset; for (let i = 0; i < segments.length - 1; i += 1) { const segmentStart = segments[i + 0]; const segmentEnd = segments[i + 1]; const datum = { value, segmentStart, segmentEnd }; const isStart = i === 0; const isEnd = i === segments.length - 2; const itemStart = mainAxisScale.convert(segmentStart); const itemEnd = mainAxisScale.convert(segmentEnd); const startCornerRadius = cornersOnAllItems || isStart ? cornerRadius : 0; const endCornerRadius = cornersOnAllItems || isEnd ? cornerRadius : 0; const topLeftCornerRadius = horizontal ? startCornerRadius : endCornerRadius; const topRightCornerRadius = endCornerRadius; const bottomRightCornerRadius = horizontal ? endCornerRadius : startCornerRadius; const bottomLeftCornerRadius = startCornerRadius; if (bar.enabled) { nodeData.push({ series: this, itemId: `value-${i}`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, x0: originX + (horizontal ? itemStart : x0), y0: originY + (horizontal ? y0 : itemStart), x1: originX + (horizontal ? itemEnd : x1), y1: originY + (horizontal ? y1 : itemEnd), clipX0, clipY0, clipX1, clipY1, topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, fill: barFill, horizontalInset, verticalInset }); } scaleData.push({ series: this, itemId: `scale-${i}`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, x0: originX + (horizontal ? itemStart : x0), y0: originY + (horizontal ? y0 : itemStart), x1: originX + (horizontal ? itemEnd : x1), y1: originY + (horizontal ? y1 : itemEnd), clipX0: void 0, clipY0: void 0, clipX1: void 0, clipY1: void 0, topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, fill: scaleFill, horizontalInset, verticalInset }); } } if (label.enabled) { labelData.push(this.labelDatum(label, value)); } const targetPlacementRotation2 = horizontal ? horizontalTargetPlacementRotation : verticalTargetPlacementRotation; for (let i = 0; i < targets.length; i += 1) { const target = targets[i]; const { value: targetValue, text: text22, shape, size, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = target; const targetPoint = this.getTargetPoint(target); const targetRotation = toRadians5(target.rotation + targetPlacementRotation2[target.placement]); targetData.push({ series: this, itemId: `target-${i}`, midPoint: targetPoint, datum: { value: targetValue }, datumIndex: { type: 1, index: i }, type: 1, value: targetValue, text: text22, x: targetPoint.x, y: targetPoint.y, shape, size, rotation: targetRotation, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset, label: this.getTargetLabel(target) }); } return { itemId: seriesId, nodeData, targetData, labelData, scaleData }; } updateSelections(resize) { if (this.nodeDataRefresh || resize) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } highlightDatum(node) { if (node != null && node.series === this && node.type === 1) { return node; } } update({ seriesRect }) { const { datumSelection, labelSelection, targetSelection, targetLabelSelection, scaleSelection, highlightTargetSelection } = this; const resize = this.checkResize(seriesRect); this.updateSelections(resize); this.contentGroup.visible = this.visible; this.contentGroup.opacity = this.getOpacity(); const nodeData = this.contextNodeData?.nodeData ?? []; const labelData = this.contextNodeData?.labelData ?? []; const targetData = this.contextNodeData?.targetData ?? []; const scaleData = this.contextNodeData?.scaleData ?? []; const highlightTargetDatum = this.highlightDatum(this.ctx.highlightManager.getActiveHighlight()); this.scaleSelection = this.updateScaleSelection({ scaleData, scaleSelection }); this.updateScaleNodes({ scaleSelection }); this.targetSelection = this.updateTargetSelection({ targetData, targetSelection }); this.updateTargetNodes({ targetSelection, isHighlight: false }); this.targetLabelSelection = this.updateTargetLabelSelection({ targetData, targetLabelSelection }); this.updateTargetLabelNodes({ targetLabelSelection }); this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection }); this.labelSelection = this.updateLabelSelection({ labelData, labelSelection }); this.updateLabelNodes({ labelSelection }); this.highlightTargetSelection = this.updateTargetSelection({ targetData: highlightTargetDatum != null ? [highlightTargetDatum] : [], targetSelection: highlightTargetSelection }); this.updateTargetNodes({ targetSelection: highlightTargetSelection, isHighlight: true }); if (resize) { this.animationState.transition("resize"); } this.animationState.transition("update"); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => { return createDatumId8(opts.nodeData.length, datum.itemId); }); } updateDatumNodes(opts) { const { datumSelection } = opts; const { ctx, properties } = this; const { bar } = properties; const { fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = bar; const strokeWidth = this.getStrokeWidth(bar.strokeWidth); const animationDisabled = ctx.animationManager.isSkipped(); datumSelection.each((rect, datum) => { const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, fill } = datum; rect.fill = fill; rect.fillOpacity = fillOpacity; rect.stroke = stroke22; rect.strokeOpacity = strokeOpacity; rect.strokeWidth = strokeWidth; rect.lineDash = lineDash; rect.lineDashOffset = lineDashOffset; rect.topLeftCornerRadius = topLeftCornerRadius; rect.topRightCornerRadius = topRightCornerRadius; rect.bottomRightCornerRadius = bottomRightCornerRadius; rect.bottomLeftCornerRadius = bottomLeftCornerRadius; rect.pointerEvents = this.properties.bar.enabled ? import_ag_charts_community192._ModuleSupport.PointerEvents.All : import_ag_charts_community192._ModuleSupport.PointerEvents.None; if (animationDisabled || rect.previousDatum == null) { rect.setProperties(resetLinearGaugeSeriesResetRectFunction(rect, datum)); } }); this.datumUnion.update(datumSelection, this.itemGroup, import_ag_charts_community192._ModuleSupport.Rect, (node, first2, last) => { node.pointerEvents = import_ag_charts_community192._ModuleSupport.PointerEvents.None; node.clipBBox ?? (node.clipBBox = new BBox14(NaN, NaN, NaN, NaN)); node.x = first2.x; node.y = first2.y; node.clipBBox.x = first2.clipBBox?.x ?? first2.x; node.clipBBox.y = first2.clipBBox?.y ?? first2.y; if (this.properties.direction === "horizontal") { node.height = node.clipBBox.height = last.height; node.width = last === first2 ? last.width : last.x + last.width; node.clipBBox.width = node.width - (last.width - (last.clipBBox?.width ?? last.width)); node.topLeftCornerRadius = first2.topLeftCornerRadius; node.bottomLeftCornerRadius = first2.bottomLeftCornerRadius; node.topRightCornerRadius = last.topRightCornerRadius; node.bottomRightCornerRadius = last.bottomRightCornerRadius; } else { node.width = node.clipBBox.width = last.width; node.height = last === first2 ? last.height : last.x + last.height; node.clipBBox.height = node.height - (last.height - (last.clipBBox?.height ?? last.height)); node.topLeftCornerRadius = first2.topLeftCornerRadius; node.topRightCornerRadius = first2.topRightCornerRadius; node.bottomLeftCornerRadius = last.bottomLeftCornerRadius; node.bottomRightCornerRadius = last.bottomRightCornerRadius; } }); } updateScaleSelection(opts) { return opts.scaleSelection.update(opts.scaleData, void 0, (datum) => { return createDatumId8(opts.scaleData.length, datum.itemId); }); } updateScaleNodes(opts) { const { scaleSelection } = opts; const { scale: scale2 } = this.properties; const { fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = scale2; scaleSelection.each((rect, datum) => { const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, fill } = datum; rect.fill = fill; rect.fillOpacity = fillOpacity; rect.stroke = stroke22; rect.strokeOpacity = strokeOpacity; rect.strokeWidth = strokeWidth; rect.lineDash = lineDash; rect.lineDashOffset = lineDashOffset; rect.topLeftCornerRadius = topLeftCornerRadius; rect.topRightCornerRadius = topRightCornerRadius; rect.bottomRightCornerRadius = bottomRightCornerRadius; rect.bottomLeftCornerRadius = bottomLeftCornerRadius; rect.setProperties(resetLinearGaugeSeriesResetRectFunction(rect, datum)); }); } updateTargetSelection(opts) { return opts.targetSelection.update(opts.targetData, void 0, (target) => target.itemId); } updateTargetNodes(opts) { const { targetSelection, isHighlight } = opts; const highlightStyle = isHighlight ? this.properties.highlightStyle.item : void 0; targetSelection.each((target, datum) => { const { x, y, shape, size, rotation, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = datum; target.size = size; target.shape = shape === "line" ? lineMarker : shape; target.fill = highlightStyle?.fill ?? fill; target.fillOpacity = highlightStyle?.fillOpacity ?? fillOpacity; target.stroke = highlightStyle?.stroke ?? stroke22; target.strokeOpacity = highlightStyle?.strokeOpacity ?? strokeOpacity; target.strokeWidth = highlightStyle?.strokeWidth ?? strokeWidth; target.lineDash = highlightStyle?.lineDash ?? lineDash; target.lineDashOffset = highlightStyle?.lineDashOffset ?? lineDashOffset; target.translationX = x; target.translationY = y; target.rotation = rotation; }); } updateTargetLabelSelection(opts) { return opts.targetLabelSelection.update(opts.targetData); } updateTargetLabelNodes(opts) { const { targetLabelSelection } = opts; targetLabelSelection.each((label, target) => { const { x, y, text: text22 } = target; const { offsetX, offsetY, fill, fontStyle, fontWeight, fontSize, fontFamily, textAlign, textBaseline } = target.label; label.visible = true; label.x = x + offsetX; label.y = y + offsetY; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textAlign = textAlign; label.textBaseline = textBaseline; }); } updateLabelSelection(opts) { return opts.labelSelection.update(opts.labelData, void 0, (_datum) => "primary"); } updateLabelNodes(opts) { const { labelSelection } = opts; const animationDisabled = this.ctx.animationManager.isSkipped(); labelSelection.each((label, datum) => { label.fill = datum.fill; label.fontStyle = datum.fontStyle; label.fontWeight = datum.fontWeight; label.fontFamily = datum.fontFamily; }); if (animationDisabled || this.labelsHaveExplicitText()) { this.formatLabelText(); } } labelsHaveExplicitText() { for (const { datum } of this.labelSelection) { if (datum.text == null) { return false; } } return true; } formatLabelText(datum) { const { labelSelection, horizontal, axes } = this; const xAxis = axes[ChartAxisDirection24.X]; const yAxis = axes[ChartAxisDirection24.Y]; if (xAxis == null || yAxis == null) return; const [x0, x1] = xAxis.range; const [y0, y1] = yAxis.range; const x = this.originX + Math.min(x0, x1); const y = this.originY + Math.min(y0, y1); const width2 = Math.abs(x1 - x0); const height2 = Math.abs(y1 - y0); const value = datum?.label ?? this.properties.value; let barBBox; if (horizontal) { const xValue = xAxis.scale.convert(value); barBBox = new BBox14(x, y, xValue - x, height2); } else { const yValue = yAxis.scale.convert(value); barBBox = new BBox14(x, yValue, width2, height2 - yValue); } const bboxes = { scale: new BBox14(x, y, width2, height2), bar: barBBox }; const { margin: padding } = this.properties; formatLinearGaugeLabels(this, labelSelection, { padding, horizontal }, bboxes, datum); } resetAllAnimation() { this.ctx.animationManager.stopByAnimationGroupId(this.id); resetMotion22([this.datumSelection], resetLinearGaugeSeriesResetRectFunction); this.formatLabelText(); } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } else if (phase === "ready") { this.animationState.transition("skip"); } } animateLabelText(params = {}) { const { animationManager } = this.ctx; let labelFrom = 0; let labelTo = 0; this.labelSelection.each((label, datum) => { label.opacity = 1; labelFrom = label.previousDatum?.value ?? params.from ?? datum.value; labelTo = datum.value; }); if (this.labelsHaveExplicitText()) { } else if (labelFrom === labelTo) { this.formatLabelText({ label: labelTo }); } else { const animationId = `${this.id}_labels`; animationManager.animate({ id: animationId, groupId: "label", from: { label: labelFrom }, to: { label: labelTo }, phase: params.phase ?? "update", ease: easing.easeOut, onUpdate: (datum) => this.formatLabelText(datum) }); } } animateEmptyUpdateReady() { const { animationManager } = this.ctx; const { node } = prepareLinearGaugeSeriesAnimationFunctions(true, this.horizontal); fromToMotion2(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId); fromToMotion2(this.id, "label", animationManager, [this.labelSelection], fadeInFns, () => "primary"); this.animateLabelText({ from: 0, phase: "initial" }); } animateWaitingUpdateReady() { const { animationManager } = this.ctx; const { node } = prepareLinearGaugeSeriesAnimationFunctions(false, this.horizontal); fromToMotion2(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId); this.animateLabelText(); } animateReadyResize() { this.resetAllAnimation(); } getSeriesDomain() { return [0, 1]; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } getLegendData() { return []; } getTooltipContent(nodeDatum) { const { id: seriesId, properties } = this; const { tooltip } = properties; if (!properties.isValid()) return; const { value = properties.value, text: text22 = properties.label.text } = parseUnknownGaugeNodeDatum(nodeDatum); return tooltip.formatTooltip( { data: [{ label: text22, fallbackLabel: "Value", value: this.formatLabel(value) }] }, { seriesId, title: void 0, datum: void 0, value } ); } pickNodeClosestDatum(point) { return pickGaugeNearestDatum(this, point); } pickFocus(opts) { return pickGaugeFocus(this, opts); } getCaptionText() { return this.formatLabel(this.properties.value); } }; LinearGaugeSeries.className = "LinearGaugeSeries"; LinearGaugeSeries.type = "linear-gauge"; var { ThemeSymbols: { DEFAULT_HIERARCHY_FILLS: DEFAULT_HIERARCHY_FILLS2, DEFAULT_GAUGE_SERIES_COLOR_RANGE: DEFAULT_GAUGE_SERIES_COLOR_RANGE2 }, ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE8 } } = import_ag_charts_community193._ModuleSupport; var LinearGaugeModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["gauge"], identifier: "linear-gauge", moduleFactory: (ctx) => new LinearGaugeSeries(ctx), tooltipDefaults: { range: 10 }, defaultAxes: [ { type: CARTESIAN_AXIS_TYPE8.NUMBER, line: { enabled: false } }, { type: CARTESIAN_AXIS_TYPE8.NUMBER, line: { enabled: false } } ], themeTemplate: { minWidth: 200, minHeight: 200, tooltip: { enabled: false }, series: { thickness: 50, bar: { strokeWidth: 0 }, segmentation: { enabled: false, interval: {}, spacing: 1 }, // @ts-expect-error Private defaultTarget: { fill: { $ref: "foregroundColor" }, stroke: { $ref: "foregroundColor" }, size: 10, shape: "triangle", placement: "after", spacing: 5, label: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "textColor" }, spacing: 5 } }, label: { enabled: false, placement: "inside-start", fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [2] }, minimumFontSize: 12, spacing: 18, color: { $ref: "backgroundColor" } }, margin: 4 }, axes: { [CARTESIAN_AXIS_TYPE8.NUMBER]: { line: { enabled: false }, gridLine: { enabled: false } } } }, paletteFactory(params) { const { takeColors, colorsCount, userPalette, themeTemplateParameters } = params; const { fills } = takeColors(colorsCount); const defaultColorRange = themeTemplateParameters.get(DEFAULT_GAUGE_SERIES_COLOR_RANGE2); const hierarchyFills = themeTemplateParameters.get(DEFAULT_HIERARCHY_FILLS2); const colorRange = userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]]; return { scale: { defaultFill: hierarchyFills?.[1], stroke: hierarchyFills?.[2] }, defaultColorRange: defaultColorStops(colorRange) }; } }; var import_ag_charts_community200 = (init_main4(), __toCommonJS(main_exports)); var MAP_THEME_DEFAULTS = { zoom: { axes: "xy", anchorPointX: "pointer", anchorPointY: "pointer", buttons: { // @ts-expect-error undocumented options anchorPointX: "middle", anchorPointY: "middle" } }, legend: { enabled: false }, gradientLegend: { enabled: false }, tooltip: { range: "exact" } }; var import_ag_charts_community199 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community195 = (init_main4(), __toCommonJS(main_exports)); var delta22 = 1e-9; function lineSegmentDistanceToPointSquared(a, b, x, y) { const [ax, ay] = a; const [bx, by] = b; const abx = bx - ax; const aby = by - ay; const l = abx * abx + aby * aby; let x0; let y0; if (Math.abs(l) < delta22) { x0 = ax; y0 = ay; } else { let t = ((x - ax) * abx + (y - ay) * aby) / l; t = Math.max(0, Math.min(1, t)); x0 = ax + t * (bx - ax); y0 = ay + t * (by - ay); } const dx2 = x - x0; const dy2 = y - y0; return dx2 * dx2 + dy2 * dy2; } function lineStringDistance(lineString, x, y) { let minDistanceSquared = Infinity; let p0 = lineString[lineString.length - 1]; for (const p1 of lineString) { minDistanceSquared = Math.min(minDistanceSquared, lineSegmentDistanceToPointSquared(p0, p1, x, y)); p0 = p1; } return Math.sqrt(minDistanceSquared); } function lineStringLength(lineSegment) { let [x0, y0] = lineSegment[0]; let totalDistance = 0; for (let i = 1; i < lineSegment.length; i += 1) { const [x1, y1] = lineSegment[i]; const distance2 = Math.hypot(x1 - x0, y1 - y0); totalDistance += distance2; x0 = x1; y0 = y1; } return totalDistance; } function lineStringCenter(lineSegment) { if (lineSegment.length === 0) return; const targetDistance = lineStringLength(lineSegment) / 2; let [x0, y0] = lineSegment[0]; let totalDistance = 0; for (let i = 1; i < lineSegment.length; i += 1) { const [x1, y1] = lineSegment[i]; const segmentDistance = Math.hypot(x1 - x0, y1 - y0); const nextDistance = totalDistance + segmentDistance; if (nextDistance > targetDistance) { const ratio2 = (targetDistance - totalDistance) / segmentDistance; const point = [x0 + (x1 - x0) * ratio2, y0 + (y1 - y0) * ratio2]; const angle2 = Math.atan2(y1 - y0, x1 - x0); return { point, angle: angle2 }; } totalDistance = nextDistance; x0 = x1; y0 = y1; } } var import_ag_charts_community194 = (init_main4(), __toCommonJS(main_exports)); var { LonLatBBox: LonLatBBox2 } = import_ag_charts_community194._ModuleSupport; function extendBbox(into, lon0, lat0, lon1, lat1) { if (into == null) { into = new LonLatBBox2(lon0, lat0, lon1, lat1); } else { into.lon0 = Math.min(into.lon0, lon0); into.lat0 = Math.min(into.lat0, lat0); into.lon1 = Math.max(into.lon1, lon1); into.lat1 = Math.max(into.lat1, lat1); } return into; } function polygonBbox(polygon, into) { polygon.forEach((coordinates) => { const [lon, lat] = coordinates; into = extendBbox(into, lon, lat, lon, lat); }); return into; } function polygonCentroid(polygon) { if (polygon.length === 0) return; let x = 0; let y = 0; let k = 0; let [x0, y0] = polygon[polygon.length - 1]; for (const [x1, y1] of polygon) { const c = x0 * y1 - x1 * y0; k += c; x += (x0 + x1) * c; y += (y0 + y1) * c; x0 = x1; y0 = y1; } k *= 3; return [x / k, y / k]; } function polygonDistance(polygons, x, y) { let inside = false; let minDistanceSquared = Infinity; for (const polygon of polygons) { let p0 = polygon[polygon.length - 1]; let [x0, y0] = p0; for (const p1 of polygon) { const [x1, y1] = p1; if (y1 > y !== y0 > y && x < (x0 - x1) * (y - y1) / (y0 - y1) + x1) { inside = !inside; } minDistanceSquared = Math.min(minDistanceSquared, lineSegmentDistanceToPointSquared(p0, p1, x, y)); p0 = p1; x0 = x1; y0 = y1; } } return (inside ? -1 : 1) * Math.sqrt(minDistanceSquared); } var { Path: Path10, ExtendedPath2D: ExtendedPath2D4, BBox: BBox15, ScenePathChangeDetection: ScenePathChangeDetection8 } = import_ag_charts_community195._ModuleSupport; var GeoGeometry = class extends Path10 { constructor() { super(...arguments); this.projectedGeometry = void 0; this.renderMode = 3; this.strokePath = new ExtendedPath2D4(); } computeBBox() { if (this.dirtyPath || this.isDirtyPath()) { this.updatePath(); this.dirtyPath = false; } return this.bbox?.clone(); } updatePath() { const { projectedGeometry } = this; this.strokePath.clear(); this.path.clear(); this.bbox = projectedGeometry != null ? this.drawGeometry(projectedGeometry, void 0) : void 0; } drawPath(ctx) { super.drawPath(ctx); this.renderStroke(ctx, this.strokePath.getPath2D()); } containsPoint(x, y) { const { projectedGeometry } = this; if (projectedGeometry == null) return false; if (!this.getBBox().containsPoint(x, y)) return false; return this.geometryDistance(projectedGeometry, x, y) <= 0; } distanceSquared(x, y) { const { projectedGeometry } = this; if (projectedGeometry == null) return Infinity; const distance2 = this.geometryDistance(projectedGeometry, x, y); return distance2 > 0 ? distance2 * distance2 : 0; } geometryDistance(geometry, x, y) { const { renderMode, strokeWidth } = this; const drawPolygons = (renderMode & 1) !== 0; const drawLines = (renderMode & 2) !== 0; const minStrokeDistance = Math.max(strokeWidth / 2, 1) + 1; switch (geometry.type) { case "GeometryCollection": return geometry.geometries.reduce( (minDistance, g) => Math.min(minDistance, this.geometryDistance(g, x, y)), Infinity ); case "MultiPolygon": return drawPolygons ? geometry.coordinates.reduce( (minDistance, polygon) => Math.min(minDistance, Math.max(polygonDistance(polygon, x, y), 0)), Infinity ) : Infinity; case "Polygon": return drawPolygons ? Math.max(polygonDistance(geometry.coordinates, x, y), 0) : Infinity; case "MultiLineString": return drawLines ? geometry.coordinates.reduce((minDistance, lineString) => { return Math.min( minDistance, Math.max(lineStringDistance(lineString, x, y) - minStrokeDistance, 0) ); }, Infinity) : Infinity; case "LineString": return drawLines ? Math.max(lineStringDistance(geometry.coordinates, x, y) - minStrokeDistance, 0) : Infinity; case "MultiPoint": case "Point": default: return Infinity; } } drawGeometry(geometry, bbox) { const { renderMode, path, strokePath } = this; const drawPolygons = (renderMode & 1) !== 0; const drawLines = (renderMode & 2) !== 0; switch (geometry.type) { case "GeometryCollection": geometry.geometries.forEach((g) => { bbox = this.drawGeometry(g, bbox); }); break; case "MultiPolygon": if (drawPolygons) { geometry.coordinates.forEach((coordinates) => { bbox = this.drawPolygon(path, coordinates, bbox); }); } break; case "Polygon": if (drawPolygons) { bbox = this.drawPolygon(path, geometry.coordinates, bbox); } break; case "LineString": if (drawLines) { bbox = this.drawLineString(strokePath, geometry.coordinates, bbox, false); } break; case "MultiLineString": if (drawLines) { geometry.coordinates.forEach((coordinates) => { bbox = this.drawLineString(strokePath, coordinates, bbox, false); }); } break; case "Point": case "MultiPoint": break; } return bbox; } drawPolygon(path, polygons, bbox) { if (polygons.length < 1) return bbox; bbox = this.drawLineString(path, polygons[0], bbox, true); for (let i = 1; i < polygons.length; i += 1) { const enclave = polygons[i]; this.drawLineString(path, enclave, void 0, true); } return bbox; } drawLineString(path, coordinates, bbox, isClosed) { if (coordinates.length < 2) return bbox; const end2 = isClosed ? coordinates.length - 1 : coordinates.length; for (let i = 0; i < end2; i += 1) { const [x, y] = coordinates[i]; if (i === 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } if (bbox == null) { bbox = new BBox15(x, y, 0, 0); } else { const { x: x0, y: y0 } = bbox; const x1 = x0 + bbox.width; const y1 = y0 + bbox.height; bbox.x = Math.min(x0, x); bbox.y = Math.min(y0, y); bbox.width = Math.max(x1, x) - bbox.x; bbox.height = Math.max(y1, y) - bbox.y; } } if (isClosed) { path.closePath(); } return bbox; } }; __decorateClass2([ ScenePathChangeDetection8() ], GeoGeometry.prototype, "projectedGeometry", 2); __decorateClass2([ ScenePathChangeDetection8() ], GeoGeometry.prototype, "renderMode", 2); function geometryBbox(geometry, into) { if (geometry.bbox != null) { const [lon0, lat0, lon1, lat1] = geometry.bbox; into = extendBbox(into, lon0, lat0, lon1, lat1); return into; } switch (geometry.type) { case "GeometryCollection": geometry.geometries.forEach((g) => { into = geometryBbox(g, into); }); break; case "MultiPolygon": geometry.coordinates.forEach((c) => { if (c.length > 0) { into = polygonBbox(c[0], into); } }); break; case "Polygon": if (geometry.coordinates.length > 0) { into = polygonBbox(geometry.coordinates[0], into); } break; case "MultiLineString": geometry.coordinates.forEach((c) => { into = polygonBbox(c, into); }); break; case "LineString": into = polygonBbox(geometry.coordinates, into); break; case "MultiPoint": geometry.coordinates.forEach((p) => { const [lon, lat] = p; into = extendBbox(into, lon, lat, lon, lat); }); break; case "Point": { const [lon, lat] = geometry.coordinates; into = extendBbox(into, lon, lat, lon, lat); break; } } return into; } function largestPolygon(geometry) { switch (geometry.type) { case "GeometryCollection": { let maxArea; let maxPolygon; geometry.geometries.forEach((g) => { const polygon = largestPolygon(g); if (polygon == null) return; const bbox = polygonBbox(polygon[0], void 0); if (bbox == null) return; const area2 = Math.abs(bbox.lat1 - bbox.lat0) * Math.abs(bbox.lon1 - bbox.lon0); if (maxArea == null || area2 > maxArea) { maxArea = area2; maxPolygon = polygon; } }); return maxPolygon; } case "MultiPolygon": { let maxArea; let maxPolygon; geometry.coordinates.forEach((polygon) => { const bbox = polygonBbox(polygon[0], void 0); if (bbox == null) return; const area2 = Math.abs(bbox.lat1 - bbox.lat0) * Math.abs(bbox.lon1 - bbox.lon0); if (maxArea == null || area2 > maxArea) { maxArea = area2; maxPolygon = polygon; } }); return maxPolygon; } case "Polygon": return geometry.coordinates; case "MultiLineString": case "LineString": case "MultiPoint": case "Point": return; } } function largestLineString(geometry) { switch (geometry.type) { case "GeometryCollection": { let maxLength; let maxLineString; geometry.geometries.forEach((g) => { const lineString = largestLineString(g); if (lineString == null) return; const length2 = lineStringLength(lineString); if (length2 == null) return; if (maxLength == null || length2 > maxLength) { maxLength = length2; maxLineString = lineString; } }); return maxLineString; } case "MultiLineString": { let maxLength = 0; let maxLineString; geometry.coordinates.forEach((lineString) => { const length2 = lineStringLength(lineString); if (length2 > maxLength) { maxLength = length2; maxLineString = lineString; } }); return maxLineString; } case "LineString": return geometry.coordinates; case "MultiPolygon": case "Polygon": case "MultiPoint": case "Point": return; } } function containsType(geometry, type) { if (geometry == null) return false; switch (geometry.type) { case "GeometryCollection": return geometry.geometries.some((g) => containsType(g, type)); case "MultiPolygon": case "Polygon": return (type & 1) !== 0; case "MultiLineString": case "LineString": return (type & 2) !== 0; case "MultiPoint": case "Point": return (type & 4) !== 0; } } function projectGeometry(geometry, scale2) { switch (geometry.type) { case "GeometryCollection": return { type: "GeometryCollection", geometries: geometry.geometries.map((g) => projectGeometry(g, scale2)) }; case "Polygon": return { type: "Polygon", coordinates: projectPolygon(geometry.coordinates, scale2) }; case "MultiPolygon": return { type: "MultiPolygon", coordinates: projectMultiPolygon(geometry.coordinates, scale2) }; case "MultiLineString": return { type: "MultiLineString", coordinates: projectPolygon(geometry.coordinates, scale2) }; case "LineString": return { type: "LineString", coordinates: projectLineString(geometry.coordinates, scale2) }; case "MultiPoint": return { type: "MultiPoint", coordinates: projectLineString(geometry.coordinates, scale2) }; case "Point": return { type: "Point", coordinates: scale2.convert(geometry.coordinates) }; } } function projectMultiPolygon(multiPolygon, scale2) { return multiPolygon.map((polygon) => projectPolygon(polygon, scale2)); } function projectPolygon(polygon, scale2) { return polygon.map((lineString) => projectLineString(lineString, scale2)); } function projectLineString(lineString, scale2) { return lineString.map((lonLat) => scale2.convert(lonLat)); } var import_ag_charts_community196 = (init_main4(), __toCommonJS(main_exports)); var TopologySeriesProperties = class extends import_ag_charts_community196._ModuleSupport.SeriesProperties { }; var TopologySeries = class extends import_ag_charts_community196._ModuleSupport.DataModelSeries { addChartEventListeners() { this.destroyFns.push( this.ctx.chartEventManager.addListener("legend-item-click", (event) => { this.onLegendItemClick(event); }), this.ctx.chartEventManager.addListener("legend-item-double-click", (event) => { this.onLegendItemDoubleClick(event); }) ); } getSeriesDomain() { return [NaN, NaN]; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } }; var import_ag_charts_community197 = (init_main4(), __toCommonJS(main_exports)); function isValidCoordinate(v) { return Array.isArray(v) && v.length >= 2 && v.every(isFiniteNumber2); } function isValidCoordinates(v) { return Array.isArray(v) && v.length >= 2 && v.every(isValidCoordinate); } var delta32 = 1e-3; function hasSameStartEndPoint(c) { return Math.abs(c[0][0] - c[c.length - 1][0]) < delta32 && Math.abs(c[0][1] - c[c.length - 1][1]) < delta32; } function isValidPolygon(v) { return Array.isArray(v) && v.every(isValidCoordinates) && v.every(hasSameStartEndPoint); } function isValidGeometry(v) { if (v === null) return true; if (typeof v !== "object" || v.type == null) return false; const { type, coordinates } = v; switch (type) { case "GeometryCollection": return Array.isArray(v.geometries) && v.geometries.every(isValidGeometry); case "MultiPolygon": return Array.isArray(coordinates) && coordinates.every(isValidPolygon); case "Polygon": return isValidPolygon(coordinates); case "MultiLineString": return Array.isArray(coordinates) && coordinates.every(isValidCoordinates); case "LineString": return isValidCoordinates(coordinates); case "MultiPoint": return isValidCoordinates(coordinates); case "Point": return isValidCoordinate(coordinates); } } function isValidFeature(v) { return v !== null && typeof v === "object" && v.type === "Feature" && isValidGeometry(v.geometry); } function isValidFeatureCollection(v) { return v !== null && typeof v === "object" && v.type === "FeatureCollection" && Array.isArray(v.features) && v.features.every(isValidFeature); } var GEOJSON_OBJECT = import_ag_charts_community197._ModuleSupport.predicateWithMessage(isValidFeatureCollection, "a GeoJSON object"); var import_ag_charts_community198 = (init_main4(), __toCommonJS(main_exports)); var { COLOR_STRING: COLOR_STRING16, LINE_DASH: LINE_DASH12, OBJECT: OBJECT32, POSITIVE_NUMBER: POSITIVE_NUMBER24, RATIO: RATIO20, Validate: Validate65, SeriesProperties: SeriesProperties3, SeriesTooltip: SeriesTooltip9 } = import_ag_charts_community198._ModuleSupport; var MapLineBackgroundSeriesProperties = class extends SeriesProperties3 { constructor() { super(...arguments); this.topology = void 0; this.stroke = "black"; this.strokeOpacity = 1; this.strokeWidth = 0; this.lineDash = [0]; this.lineDashOffset = 0; this.tooltip = new SeriesTooltip9(); } }; __decorateClass2([ Validate65(GEOJSON_OBJECT, { optional: true }) ], MapLineBackgroundSeriesProperties.prototype, "topology", 2); __decorateClass2([ Validate65(COLOR_STRING16) ], MapLineBackgroundSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate65(RATIO20) ], MapLineBackgroundSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate65(POSITIVE_NUMBER24) ], MapLineBackgroundSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate65(LINE_DASH12) ], MapLineBackgroundSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate65(POSITIVE_NUMBER24) ], MapLineBackgroundSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate65(OBJECT32) ], MapLineBackgroundSeriesProperties.prototype, "tooltip", 2); var { createDatumId: createDatumId9, SeriesNodePickMode: SeriesNodePickMode7, Validate: Validate66, Group: Group12, Selection: Selection7, PointerEvents: PointerEvents4 } = import_ag_charts_community199._ModuleSupport; var MapLineBackgroundSeries = class extends TopologySeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode7.EXACT_SHAPE_MATCH] }); this.properties = new MapLineBackgroundSeriesProperties(); this._chartTopology = void 0; this.itemGroup = this.contentGroup.appendChild(new Group12({ name: "itemGroup" })); this.datumSelection = Selection7.select( this.itemGroup, () => this.nodeFactory() ); } getNodeData() { return this.contextNodeData?.nodeData; } get topology() { return this.properties.topology ?? this._chartTopology; } get focusable() { return false; } setOptionsData() { } setChartData() { } get hasData() { return false; } renderToOffscreenCanvas() { return true; } setChartTopology(topology) { this._chartTopology = topology; if (this.topology === topology) { this.nodeDataRefresh = true; } } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [0, index, 0]; this.highlightGroup.zIndex = [0, index, 1]; return true; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 2; geoGeometry.lineJoin = "round"; geoGeometry.lineCap = "round"; geoGeometry.pointerEvents = PointerEvents4.None; return geoGeometry; } processData() { const { topology } = this; this.topologyBounds = topology?.features.reduce((current, feature) => { const geometry = feature.geometry; if (geometry == null) return current; return geometryBbox(geometry, current); }, void 0); if (topology == null) { logger_exports2.warnOnce(`no topology was provided for [MapShapeBackgroundSeries]; nothing will be rendered.`); } } createNodeData() { const { id: seriesId, topology, scale: scale2 } = this; if (topology == null) return; const nodeData = []; const labelData = []; topology.features.forEach((feature, index) => { const { geometry } = feature; const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0; if (projectedGeometry == null) return; nodeData.push({ series: this, itemId: index, datum: feature, datumIndex: 0, index, projectedGeometry }); }); return { itemId: seriesId, nodeData, labelData }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } update() { const { datumSelection } = this; this.updateSelections(); this.contentGroup.visible = this.visible; const { nodeData = [] } = this.contextNodeData ?? {}; this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection }); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId9(datum.index)); } updateDatumNodes(opts) { const { properties } = this; const { datumSelection } = opts; const { stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = properties; const strokeWidth = this.getStrokeWidth(properties.strokeWidth); datumSelection.each((geoGeometry, datum) => { const { projectedGeometry } = datum; if (projectedGeometry == null) { geoGeometry.visible = false; geoGeometry.projectedGeometry = void 0; return; } geoGeometry.visible = true; geoGeometry.projectedGeometry = projectedGeometry; geoGeometry.stroke = stroke22; geoGeometry.strokeWidth = strokeWidth; geoGeometry.strokeOpacity = strokeOpacity; geoGeometry.lineDash = lineDash; geoGeometry.lineDashOffset = lineDashOffset; }); } resetAnimation() { } getLegendData() { return []; } getTooltipContent(_seriesDatum) { return; } computeFocusBounds(_opts) { return void 0; } }; MapLineBackgroundSeries.className = "MapLineBackgroundSeries"; MapLineBackgroundSeries.type = "map-line-background"; __decorateClass2([ Validate66(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapLineBackgroundSeries.prototype, "_chartTopology", 2); var { DEFAULT_HIERARCHY_STROKES: DEFAULT_HIERARCHY_STROKES2 } = import_ag_charts_community200._ModuleSupport.ThemeSymbols; var MapLineBackgroundModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["topology"], identifier: "map-line-background", moduleFactory: (ctx) => new MapLineBackgroundSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: { ...MAP_THEME_DEFAULTS, series: { strokeWidth: 1, lineDash: [0], lineDashOffset: 0 } }, paletteFactory: ({ themeTemplateParameters }) => { return { stroke: themeTemplateParameters.get(DEFAULT_HIERARCHY_STROKES2)?.[1] }; } }; var import_ag_charts_community203 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community202 = (init_main4(), __toCommonJS(main_exports)); function prepareMapMarkerAnimationFunctions() { const fromFn = (marker, _datum, status) => { if (status === "removed") { return { scalingX: 1, scalingY: 1 }; } else if (marker.previousDatum == null) { return { scalingX: 0, scalingY: 0 }; } return { scalingX: marker.scalingX, scalingY: marker.scalingY }; }; const toFn = (_marker, _datum, status) => { if (status === "removed") { return { scalingX: 0, scalingY: 0 }; } return { scalingX: 1, scalingY: 1 }; }; return { fromFn, toFn }; } function findFocusedGeoGeometry(series, opts) { const datum = series.contextNodeData?.nodeData[opts.datumIndex]; if (datum === void 0) return void 0; for (const node of series.datumSelection.nodes()) { if (node.datum === datum) { return node; } } return void 0; } var import_ag_charts_community201 = (init_main4(), __toCommonJS(main_exports)); var { AND: AND6, ARRAY: ARRAY9, COLOR_STRING: COLOR_STRING17, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY7, FUNCTION: FUNCTION13, LINE_DASH: LINE_DASH13, NUMBER_ARRAY: NUMBER_ARRAY22, OBJECT: OBJECT33, POSITIVE_NUMBER: POSITIVE_NUMBER25, RATIO: RATIO21, STRING: STRING31, Validate: Validate67, SeriesProperties: SeriesProperties4, SeriesTooltip: SeriesTooltip10, Label: Label7 } = import_ag_charts_community201._ModuleSupport; var MapLineSeriesProperties = class extends SeriesProperties4 { constructor() { super(...arguments); this.topology = void 0; this.idKey = ""; this.topologyIdKey = "name"; this.idName = void 0; this.labelKey = void 0; this.labelName = void 0; this.colorRange = void 0; this.maxStrokeWidth = void 0; this.stroke = "black"; this.strokeOpacity = 1; this.strokeWidth = 0; this.lineDash = [0]; this.lineDashOffset = 0; this.label = new Label7(); this.tooltip = new SeriesTooltip10(); } }; __decorateClass2([ Validate67(GEOJSON_OBJECT, { optional: true }) ], MapLineSeriesProperties.prototype, "topology", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "title", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "legendItemName", 2); __decorateClass2([ Validate67(STRING31) ], MapLineSeriesProperties.prototype, "idKey", 2); __decorateClass2([ Validate67(STRING31) ], MapLineSeriesProperties.prototype, "topologyIdKey", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "idName", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "labelName", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "sizeKey", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "sizeName", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "colorKey", 2); __decorateClass2([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "colorName", 2); __decorateClass2([ Validate67(NUMBER_ARRAY22, { optional: true }) ], MapLineSeriesProperties.prototype, "sizeDomain", 2); __decorateClass2([ Validate67(AND6(COLOR_STRING_ARRAY7, ARRAY9.restrict({ minLength: 1 })), { optional: true }) ], MapLineSeriesProperties.prototype, "colorRange", 2); __decorateClass2([ Validate67(POSITIVE_NUMBER25, { optional: true }) ], MapLineSeriesProperties.prototype, "maxStrokeWidth", 2); __decorateClass2([ Validate67(COLOR_STRING17) ], MapLineSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate67(RATIO21) ], MapLineSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate67(POSITIVE_NUMBER25) ], MapLineSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate67(LINE_DASH13) ], MapLineSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate67(POSITIVE_NUMBER25) ], MapLineSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate67(FUNCTION13, { optional: true }) ], MapLineSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate67(OBJECT33) ], MapLineSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate67(OBJECT33) ], MapLineSeriesProperties.prototype, "tooltip", 2); var { getMissCount: getMissCount22, createDatumId: createDatumId10, SeriesNodePickMode: SeriesNodePickMode8, valueProperty: valueProperty9, CachedTextMeasurerPool: CachedTextMeasurerPool7, Validate: Validate68, ColorScale: ColorScale3, LinearScale: LinearScale4, Selection: Selection8, Text: Text3, Transformable: Transformable22 } = import_ag_charts_community202._ModuleSupport; var MapLineSeries = class extends TopologySeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode8.EXACT_SHAPE_MATCH, SeriesNodePickMode8.NEAREST_NODE], usesPlacedLabels: true }); this.properties = new MapLineSeriesProperties(); this._chartTopology = void 0; this.colorScale = new ColorScale3(); this.sizeScale = new LinearScale4(); this.datumSelection = Selection8.select( this.contentGroup, () => this.nodeFactory() ); this.labelSelection = Selection8.select(this.labelGroup, Text3); this.highlightDatumSelection = Selection8.select( this.highlightNode, () => this.nodeFactory() ); this._previousDatumMidPoint = void 0; } getNodeData() { return this.contextNodeData?.nodeData; } get topology() { return this.properties.topology ?? this._chartTopology; } get hasData() { return super.hasData && this.topology != null; } renderToOffscreenCanvas() { return true; } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [1, index]; this.highlightGroup.zIndex = [2, index]; return true; } setChartTopology(topology) { this._chartTopology = topology; if (this.topology === topology) { this.nodeDataRefresh = true; } } isLabelEnabled() { return this.properties.labelKey != null && this.properties.label.enabled; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 2; geoGeometry.lineJoin = "round"; geoGeometry.lineCap = "round"; return geoGeometry; } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { data, topology, sizeScale, colorScale } = this; const { topologyIdKey, idKey, sizeKey, colorKey, labelKey, sizeDomain, colorRange } = this.properties; const featureById = /* @__PURE__ */ new Map(); topology?.features.forEach((feature) => { const property = feature.properties?.[topologyIdKey]; if (property == null || !containsType( feature.geometry, 2 /* LineString */ )) return; featureById.set(property, feature); }); const sizeScaleType = this.sizeScale.type; const colorScaleType = this.colorScale.type; const mercatorScaleType = this.scale?.type; const { dataModel, processedData } = await this.requestDataModel(dataController, data, { props: [ valueProperty9(idKey, mercatorScaleType, { id: "idValue", includeProperty: false }), valueProperty9(idKey, mercatorScaleType, { id: "featureValue", includeProperty: false, processor: () => (datum) => featureById.get(datum) }), ...labelKey != null ? [valueProperty9(labelKey, "band", { id: "labelValue" })] : [], ...sizeKey != null ? [valueProperty9(sizeKey, sizeScaleType, { id: "sizeValue" })] : [], ...colorKey != null ? [valueProperty9(colorKey, colorScaleType, { id: "colorValue" })] : [] ] }); const featureValues = dataModel.resolveColumnById( this, `featureValue`, processedData ); this.topologyBounds = featureValues.reduce((current, feature) => { const geometry = feature?.geometry; if (geometry == null) return current; return geometryBbox(geometry, current); }, void 0); if (sizeKey != null) { const sizeIdx = dataModel.resolveProcessedDataIndexById(this, `sizeValue`); const processedSize = processedData.domain.values[sizeIdx] ?? []; sizeScale.domain = sizeDomain ?? processedSize; } if (colorRange != null && this.isColorScaleValid()) { const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); colorScale.domain = processedData.domain.values[colorKeyIdx]; colorScale.range = colorRange; colorScale.update(); } if (topology == null) { logger_exports2.warnOnce(`no topology was provided for [MapLineSeries]; nothing will be rendered.`); } } isColorScaleValid() { const { colorKey } = this.properties; if (!colorKey) { return false; } const { dataModel, processedData } = this; if (!dataModel || !processedData) { return false; } const colorIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); const dataCount = processedData.input.count; const missCount = getMissCount22(this, processedData.defs.values[colorIdx].missing); const colorDataMissing = dataCount === 0 || dataCount === missCount; return !colorDataMissing; } getLabelDatum(datum, labelValue, projectedGeometry, font22) { if (labelValue == null || projectedGeometry == null) return; const lineString = largestLineString(projectedGeometry); if (lineString == null) return; const { idKey, idName, sizeKey, sizeName, colorKey, colorName, labelKey, labelName, label } = this.properties; const labelText = this.getLabelText(label, { value: labelValue, datum, idKey, idName, sizeKey, sizeName, colorKey, colorName, labelKey, labelName }); if (labelText == null) return; const labelSize = CachedTextMeasurerPool7.measureText(String(labelText), { font: font22 }); const labelCenter = lineStringCenter(lineString); if (labelCenter == null) return; const [x, y] = labelCenter.point; const { width: width2, height: height2 } = labelSize; return { point: { x, y, size: 0 }, label: { width: width2, height: height2, text: labelText }, anchor: void 0, placement: void 0 }; } createNodeData() { const { id: seriesId, dataModel, processedData, sizeScale, properties, scale: scale2 } = this; const { idKey, sizeKey, colorKey, labelKey, label } = properties; if (dataModel == null || processedData == null) return; const idValues = dataModel.resolveColumnById(this, `idValue`, processedData); const featureValues = dataModel.resolveColumnById( this, `featureValue`, processedData ); const labelValues = labelKey != null ? dataModel.resolveColumnById(this, `labelValue`, processedData) : void 0; const sizeValues = sizeKey != null ? dataModel.resolveColumnById(this, `sizeValue`, processedData) : void 0; const colorValues = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0; const maxStrokeWidth = properties.maxStrokeWidth ?? properties.strokeWidth; sizeScale.range = [Math.min(properties.strokeWidth, maxStrokeWidth), maxStrokeWidth]; const font22 = label.getFont(); const projectedGeometries = /* @__PURE__ */ new Map(); processedData.dataSources.get(this.id)?.forEach((_datum, datumIndex) => { const id = idValues[datumIndex]; const geometry = featureValues[datumIndex]?.geometry ?? void 0; const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0; if (id != null && projectedGeometry != null) { projectedGeometries.set(id, projectedGeometry); } }); const nodeData = []; const labelData = []; const missingGeometries = []; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const idValue = idValues[datumIndex]; const colorValue = colorValues?.[datumIndex]; const sizeValue = sizeValues?.[datumIndex]; const labelValue = labelValues?.[datumIndex]; const projectedGeometry = projectedGeometries.get(idValue); if (projectedGeometry == null) { missingGeometries.push(idValue); } const labelDatum = this.getLabelDatum(datum, labelValue, projectedGeometry, font22); if (labelDatum != null) { labelData.push(labelDatum); } nodeData.push({ series: this, itemId: idKey, datum, datumIndex, idValue, labelValue, colorValue, sizeValue, projectedGeometry }); }); const missingGeometriesCap = 10; if (missingGeometries.length > missingGeometriesCap) { const excessItems = missingGeometries.length - missingGeometriesCap; missingGeometries.length = missingGeometriesCap; missingGeometries.push(`(+${excessItems} more)`); } if (missingGeometries.length > 0) { logger_exports2.warnOnce(`some data items do not have matches in the provided topology`, missingGeometries); } return { itemId: seriesId, nodeData, labelData }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } update() { const { datumSelection, highlightDatumSelection } = this; this.updateSelections(); this.contentGroup.visible = this.visible; this.contentGroup.opacity = this.getOpacity(); let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); if (highlightedDatum != null && (highlightedDatum.series !== this || highlightedDatum.datum == null)) { highlightedDatum = void 0; } const nodeData = this.contextNodeData?.nodeData ?? []; this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection, isHighlight: false }); this.highlightDatumSelection = this.updateDatumSelection({ nodeData: highlightedDatum != null ? [highlightedDatum] : [], datumSelection: highlightDatumSelection }); this.updateDatumNodes({ datumSelection: highlightDatumSelection, isHighlight: true }); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId10(datum.idValue)); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset }; } getItemStyleOverrides(datumId, datum, colorValue, sizeValue, format, highlighted) { const { id: seriesId, properties, colorScale, sizeScale } = this; const { colorRange, itemStyler } = properties; let overrides; if (!highlighted && colorValue != null) { overrides ?? (overrides = {}); overrides.stroke = this.isColorScaleValid() ? colorScale.convert(colorValue) : colorRange?.[0] ?? properties.stroke; } if (sizeValue != null) { overrides ?? (overrides = {}); overrides.strokeWidth = sizeScale.convert(sizeValue, true); } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId10(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, highlighted, ...format, ...overrides }); } ); overrides ?? (overrides = {}); Object.assign(overrides, itemStyle); } return overrides; } updateDatumNodes(opts) { const { datumSelection, isHighlight } = opts; const format = this.getItemBaseStyle(isHighlight); datumSelection.each((geoGeometry, nodeDatum) => { const { datum, datumIndex, colorValue, sizeValue, projectedGeometry } = nodeDatum; if (projectedGeometry == null) { geoGeometry.visible = false; geoGeometry.projectedGeometry = void 0; return; } const overrides = this.getItemStyleOverrides( String(datumIndex), datum, colorValue, sizeValue, format, isHighlight ); geoGeometry.visible = true; geoGeometry.projectedGeometry = projectedGeometry; geoGeometry.stroke = overrides?.stroke ?? format.stroke; geoGeometry.strokeWidth = overrides?.strokeWidth ?? format.strokeWidth; geoGeometry.strokeOpacity = overrides?.strokeOpacity ?? format.strokeOpacity; geoGeometry.lineDash = overrides?.lineDash ?? format.lineDash; geoGeometry.lineDashOffset = overrides?.lineDashOffset ?? format.lineDashOffset; }); } updatePlacedLabelData(labelData) { this.labelSelection = this.labelSelection.update(labelData, (text22) => { text22.pointerEvents = import_ag_charts_community202._ModuleSupport.PointerEvents.None; }); this.updateLabelNodes({ labelSelection: this.labelSelection }); } updateLabelNodes(opts) { const { labelSelection } = opts; const { color: fill, fontStyle, fontWeight, fontSize, fontFamily } = this.properties.label; labelSelection.each((label, { x, y, width: width2, height: height2, text: text22 }) => { label.visible = true; label.x = x + width2 / 2; label.y = y + height2 / 2; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textAlign = "center"; label.textBaseline = "middle"; }); } resetAnimation() { } getLabelData() { if (!this.isLabelEnabled()) return []; return this.contextNodeData?.labelData ?? []; } pickNodeClosestDatum({ x, y }) { let minDistanceSquared = Infinity; let minDatum; this.datumSelection.each((node, datum) => { const distanceSquared2 = node.distanceSquared(x, y); if (distanceSquared2 < minDistanceSquared) { minDistanceSquared = distanceSquared2; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } datumMidPoint(datum) { const { _previousDatumMidPoint } = this; if (_previousDatumMidPoint?.datum === datum) { return _previousDatumMidPoint.point; } const projectedGeometry = datum.projectedGeometry; const lineString = projectedGeometry != null ? largestLineString(projectedGeometry) : void 0; const center2 = lineString != null ? lineStringCenter(lineString)?.point : void 0; const point = center2 != null ? { x: center2[0], y: center2[1] } : void 0; this._previousDatumMidPoint = { datum, point }; return point; } legendItemSymbol(datumIndex) { const { dataModel, processedData, properties } = this; const { strokeWidth, strokeOpacity, lineDash } = properties; let { stroke: stroke22 } = properties; if (datumIndex != null && this.isColorScaleValid()) { const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData); const colorValue = colorValues[datumIndex]; stroke22 = this.colorScale.convert(colorValue); } return { marker: { fill: void 0, fillOpacity: 0, stroke: void 0, strokeWidth: 0, strokeOpacity: 0, lineDash: [0], lineDashOffset: 0, enabled: false }, line: { stroke: stroke22, strokeWidth, strokeOpacity, lineDash } }; } getLegendData(legendType) { const { processedData, dataModel } = this; if (processedData == null || dataModel == null) return []; const { id: seriesId, visible } = this; const { title, legendItemName, idKey, idName, colorKey, colorName, colorRange, showInLegend } = this.properties; if (legendType === "gradient" && colorKey != null && colorRange != null) { const colorDomain = processedData.domain.values[dataModel.resolveProcessedDataIndexById(this, "colorValue")]; const legendDatum = { legendType: "gradient", enabled: visible, seriesId, colorName, colorRange, colorDomain }; return [legendDatum]; } else if (legendType === "category") { const legendDatum = { legendType: "category", id: seriesId, itemId: seriesId, seriesId, enabled: visible, label: { text: legendItemName ?? title ?? idName ?? idKey }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend }; return [legendDatum]; } else { return []; } } getTooltipContent(seriesDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { idKey, idName, colorKey, colorName, sizeKey, sizeName, labelKey, labelName, title, legendItemName, tooltip } = properties; if (!dataModel || !processedData) return; const { datumIndex } = seriesDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const idValues = dataModel.resolveColumnById(this, `idValue`, processedData); const data = []; const sizeValue = sizeKey != null ? dataModel.resolveColumnById(this, `sizeValue`, processedData)[datumIndex] : void 0; const colorValue = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex] : void 0; if (sizeKey != null) { data.push({ label: sizeName, fallbackLabel: sizeKey, value: String(sizeValue) }); } if (colorKey != null) { data.push({ label: colorName, fallbackLabel: colorKey, value: String(colorValue) }); } if (labelKey != null && labelKey !== idKey) { const labelValue = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex]; data.push({ label: labelName, fallbackLabel: labelKey, value: labelValue }); } const format = this.getItemBaseStyle(false); Object.assign( format, this.getItemStyleOverrides(String(datumIndex), datumIndex, colorValue, sizeValue, format, false) ); return tooltip.formatTooltip( { heading: idValues[datumIndex], title: title ?? legendItemName, symbol: this.legendItemSymbol(datumIndex), data }, { seriesId, datum, title, idKey, idName, colorKey, colorName, sizeKey, sizeName, labelKey, labelName, ...format } ); } computeFocusBounds(opts) { const geometry = findFocusedGeoGeometry(this, opts); return geometry ? Transformable22.toCanvas(this.contentGroup, geometry.getBBox()) : void 0; } }; MapLineSeries.className = "MapLineSeries"; MapLineSeries.type = "map-line"; __decorateClass2([ Validate68(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapLineSeries.prototype, "_chartTopology", 2); var { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE22 } = import_ag_charts_community203._ModuleSupport.ThemeSymbols; var MapLineModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["topology"], identifier: "map-line", moduleFactory: (ctx) => new MapLineSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: { ...MAP_THEME_DEFAULTS, series: { strokeWidth: 1, maxStrokeWidth: 3, lineDash: [0], lineDashOffset: 0, label: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } } } }, paletteFactory: (opts) => { const { takeColors, colorsCount, userPalette, themeTemplateParameters } = opts; const { fill } = import_ag_charts_community203._ModuleSupport.singleSeriesPaletteFactory(opts); const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE22); const { fills } = takeColors(colorsCount); return { colorRange: userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]], stroke: fill }; } }; var import_ag_charts_community206 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community205 = (init_main4(), __toCommonJS(main_exports)); var insertManySorted = (list, items, cmp2) => { let head = list; let current = head; for (const value of items) { if (head == null || cmp2(head.value, value) > 0) { head = { value, next: head }; current = head; } else { current = current; while (current.next != null && cmp2(current.next.value, value) <= 0) { current = current.next; } current.next = { value, next: current.next }; } } return head; }; function polygonPointSearch(polygons, precision, valueFn) { const bbox = polygonBbox(polygons[0], void 0); if (bbox == null) return; const boundingXCenter = (bbox.lon0 + bbox.lon1) / 2; const boundingYCenter = (bbox.lat0 + bbox.lat1) / 2; const boundingWidth = Math.abs(bbox.lon1 - bbox.lon0); const boundingHeight = Math.abs(bbox.lat1 - bbox.lat0); const centroid = polygonCentroid(polygons[0]); const [cx, cy] = centroid; const centroidDistanceToPolygon = -polygonDistance(polygons, cx, cy); let bestResult; const cellValue = (distanceToPolygon, distanceToCentroid) => { const centroidDriftFactor = 0.5; const centroidDrift = Math.max(distanceToCentroid - centroidDistanceToPolygon, 0); return distanceToPolygon - centroidDriftFactor * centroidDrift; }; const createLabelPlacement = (x2, y2, stride) => { const { distance: distance22, maxDistance } = valueFn(polygons, x2, y2, stride); const distanceToCentroid = Math.hypot(cx - x2, cy - y2); const maxXTowardsCentroid = Math.min(Math.max(cx, x2 - stride / 2), x2 + stride / 2); const maxYTowardsCentroid = Math.min(Math.max(cy, y2 - stride / 2), y2 + stride / 2); const minDistanceToCentroid = Math.hypot(cx - maxXTowardsCentroid, cy - maxYTowardsCentroid); const value = cellValue(distance22, distanceToCentroid); const maxValue = cellValue(maxDistance, minDistanceToCentroid); return { distance: distance22, maxDistance, value, maxValue, x: x2, y: y2, stride }; }; const appendLabelPlacement = (into, x2, y2, stride) => { const labelPlacement = createLabelPlacement(x2, y2, stride); if (labelPlacement.maxDistance >= 0) { into.push(labelPlacement); } }; const initialStride = Math.min(boundingWidth, boundingHeight) / 2; let queue = { value: createLabelPlacement(boundingXCenter, boundingYCenter, initialStride), next: null }; while (queue != null) { const item = queue.value; const { distance: distance22, value, maxValue, x: x2, y: y2, stride } = item; queue = queue.next; if (distance22 > 0 && (bestResult == null || value > bestResult.value)) { bestResult = item; } if (bestResult != null && maxValue - bestResult.value <= precision) { continue; } const nextStride = stride / 2; const newLabelPlacements = []; appendLabelPlacement(newLabelPlacements, x2 - nextStride, y2 - nextStride, nextStride); appendLabelPlacement(newLabelPlacements, x2 + nextStride, y2 - nextStride, nextStride); appendLabelPlacement(newLabelPlacements, x2 - nextStride, y2 + nextStride, nextStride); appendLabelPlacement(newLabelPlacements, x2 + nextStride, y2 + nextStride, nextStride); newLabelPlacements.sort(labelPlacementCmp); queue = insertManySorted(queue, newLabelPlacements, labelPlacementCmp); } if (bestResult == null) return; const { distance: distance2, x, y } = bestResult; return { x, y, distance: distance2 }; } var labelPlacementCmp = (a, b) => b.maxValue - a.maxValue; function polygonMarkerCenter(polygons, precision) { const result = polygonPointSearch(polygons, precision, (p, x2, y2, stride) => { const distance2 = -polygonDistance(p, x2, y2); const maxDistance = distance2 + stride * Math.SQRT2; return { distance: distance2, maxDistance }; }); if (result == null) return; const { x, y } = result; return [x, y]; } function markerPositions(geometry, precision) { let center2; switch (geometry.type) { case "GeometryCollection": return geometry.geometries.flatMap((g) => markerPositions(g, precision)); case "MultiPoint": return geometry.coordinates; case "Point": return [geometry.coordinates]; case "MultiPolygon": { const polygon = largestPolygon(geometry); center2 = polygon != null ? polygonMarkerCenter(polygon, precision) : void 0; break; } case "Polygon": { const polygon = geometry.coordinates; center2 = polygon != null ? polygonMarkerCenter(polygon, precision) : void 0; break; } case "MultiLineString": { const lineString = largestLineString(geometry); center2 = lineString != null ? lineStringCenter(lineString)?.point : void 0; break; } case "LineString": { const lineString = geometry.coordinates; center2 = lineStringCenter(lineString)?.point; break; } } return center2 != null ? [center2] : []; } var import_ag_charts_community204 = (init_main4(), __toCommonJS(main_exports)); var { AND: AND7, ARRAY: ARRAY10, COLOR_STRING: COLOR_STRING18, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY8, FUNCTION: FUNCTION14, NUMBER_ARRAY: NUMBER_ARRAY3, OBJECT: OBJECT34, POSITIVE_NUMBER: POSITIVE_NUMBER26, RATIO: RATIO222, STRING: STRING32, MARKER_SHAPE: MARKER_SHAPE22, LINE_DASH: LINE_DASH14, Validate: Validate69, SeriesProperties: SeriesProperties5, SeriesTooltip: SeriesTooltip11, Label: Label8 } = import_ag_charts_community204._ModuleSupport; var MapMarkerSeriesLabel = class extends Label8 { constructor() { super(...arguments); this.placement = "bottom"; } }; __decorateClass2([ Validate69(STRING32) ], MapMarkerSeriesLabel.prototype, "placement", 2); var MapMarkerSeriesProperties = class extends SeriesProperties5 { constructor() { super(...arguments); this.topology = void 0; this.idKey = void 0; this.topologyIdKey = "name"; this.idName = void 0; this.latitudeKey = void 0; this.latitudeName = void 0; this.longitudeKey = void 0; this.longitudeName = void 0; this.labelKey = void 0; this.labelName = void 0; this.colorRange = void 0; this.shape = "circle"; this.size = 6; this.fill = "black"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.label = new MapMarkerSeriesLabel(); this.tooltip = new SeriesTooltip11(); } isValid() { const superIsValid = super.isValid(); const hasTopology = this.idKey != null; const hasLatLon = this.latitudeKey != null && this.longitudeKey != null; if (!hasTopology && !hasLatLon) { logger_exports2.warnOnce( "Either both [topology] and [idKey] or both [latitudeKey] and [longitudeKey] must be set to render a map marker series." ); return false; } return superIsValid; } }; __decorateClass2([ Validate69(GEOJSON_OBJECT, { optional: true }) ], MapMarkerSeriesProperties.prototype, "topology", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "title", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "legendItemName", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "idKey", 2); __decorateClass2([ Validate69(STRING32) ], MapMarkerSeriesProperties.prototype, "topologyIdKey", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "idName", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "latitudeKey", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "latitudeName", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "longitudeKey", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "longitudeName", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "labelName", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "sizeKey", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "sizeName", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "colorKey", 2); __decorateClass2([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "colorName", 2); __decorateClass2([ Validate69(AND7(COLOR_STRING_ARRAY8, ARRAY10.restrict({ minLength: 1 })), { optional: true }) ], MapMarkerSeriesProperties.prototype, "colorRange", 2); __decorateClass2([ Validate69(MARKER_SHAPE22) ], MapMarkerSeriesProperties.prototype, "shape", 2); __decorateClass2([ Validate69(POSITIVE_NUMBER26) ], MapMarkerSeriesProperties.prototype, "size", 2); __decorateClass2([ Validate69(POSITIVE_NUMBER26, { optional: true }) ], MapMarkerSeriesProperties.prototype, "maxSize", 2); __decorateClass2([ Validate69(NUMBER_ARRAY3, { optional: true }) ], MapMarkerSeriesProperties.prototype, "sizeDomain", 2); __decorateClass2([ Validate69(COLOR_STRING18) ], MapMarkerSeriesProperties.prototype, "fill", 2); __decorateClass2([ Validate69(RATIO222) ], MapMarkerSeriesProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate69(COLOR_STRING18) ], MapMarkerSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate69(POSITIVE_NUMBER26) ], MapMarkerSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate69(RATIO222) ], MapMarkerSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate69(LINE_DASH14) ], MapMarkerSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate69(POSITIVE_NUMBER26) ], MapMarkerSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate69(FUNCTION14, { optional: true }) ], MapMarkerSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate69(OBJECT34) ], MapMarkerSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate69(OBJECT34) ], MapMarkerSeriesProperties.prototype, "tooltip", 2); var { CachedTextMeasurerPool: CachedTextMeasurerPool8, Validate: Validate70, fromToMotion: fromToMotion22, StateMachine: StateMachine13, getMissCount: getMissCount3, createDatumId: createDatumId11, SeriesNodePickMode: SeriesNodePickMode9, valueProperty: valueProperty10, computeMarkerFocusBounds: computeMarkerFocusBounds2, ColorScale: ColorScale4, LinearScale: LinearScale5, Group: Group13, Selection: Selection9, Text: Text4, Marker: Marker3, applyShapeStyle: applyShapeStyle4 } = import_ag_charts_community205._ModuleSupport; var MapMarkerSeries = class extends TopologySeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode9.EXACT_SHAPE_MATCH, SeriesNodePickMode9.NEAREST_NODE], usesPlacedLabels: true }); this.properties = new MapMarkerSeriesProperties(); this._chartTopology = void 0; this.colorScale = new ColorScale4(); this.sizeScale = new LinearScale5(); this.markerGroup = this.contentGroup.appendChild(new Group13({ name: "markerGroup" })); this.labelSelection = Selection9.select(this.labelGroup, Text4, false); this.markerSelection = Selection9.select( this.markerGroup, Marker3, false ); this.highlightMarkerSelection = Selection9.select(this.highlightNode, Marker3); this.animationState = new StateMachine13( "empty", { empty: { update: { target: "ready", action: () => this.animateMarkers() }, reset: "empty", skip: "ready" }, ready: { updateData: "waiting", clear: "clearing", resize: () => this.resetAllAnimation(), reset: "empty", skip: "ready" }, waiting: { update: { target: "ready", action: () => this.animateMarkers() }, // chart.ts transitions to updateData on zoom change resize: { target: "ready", action: () => this.resetAllAnimation() }, reset: "empty", skip: "ready" }, clearing: { update: { target: "empty", action: () => this.resetAllAnimation() }, reset: "empty", skip: "ready" } }, () => this.checkProcessedDataAnimatable() ); } getNodeData() { return this.contextNodeData?.nodeData; } get topology() { return this.properties.topology ?? this._chartTopology; } get hasData() { const hasLatLon = this.properties.latitudeKey != null && this.properties.longitudeKey != null; return super.hasData && (this.topology != null || hasLatLon); } renderToOffscreenCanvas() { return true; } setChartTopology(topology) { this._chartTopology = topology; if (this.topology === topology) { this.nodeDataRefresh = true; } } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [3, index]; this.highlightGroup.zIndex = [4, index]; return true; } isLabelEnabled() { return this.properties.labelKey != null && this.properties.label.enabled; } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { data, topology, sizeScale, colorScale } = this; const { topologyIdKey, idKey, latitudeKey, longitudeKey, sizeKey, colorKey, labelKey, sizeDomain, colorRange } = this.properties; const featureById = /* @__PURE__ */ new Map(); topology?.features.forEach((feature) => { const property = feature.properties?.[topologyIdKey]; if (property == null) return; featureById.set(property, feature); }); const sizeScaleType = this.sizeScale.type; const colorScaleType = this.colorScale.type; const mercatorScaleType = this.scale?.type; const hasLatLon = latitudeKey != null && longitudeKey != null; const { dataModel, processedData } = await this.requestDataModel(dataController, data, { props: [ ...idKey != null ? [ valueProperty10(idKey, mercatorScaleType, { id: "idValue", includeProperty: false }), valueProperty10(idKey, mercatorScaleType, { id: "featureValue", includeProperty: false, processor: () => (datum) => featureById.get(datum) }) ] : [], ...hasLatLon ? [ valueProperty10(latitudeKey, mercatorScaleType, { id: "latValue" }), valueProperty10(longitudeKey, mercatorScaleType, { id: "lonValue" }) ] : [], ...labelKey ? [valueProperty10(labelKey, "band", { id: "labelValue" })] : [], ...sizeKey ? [valueProperty10(sizeKey, sizeScaleType, { id: "sizeValue" })] : [], ...colorKey ? [valueProperty10(colorKey, colorScaleType, { id: "colorValue" })] : [] ] }); const featureValues = idKey != null ? dataModel.resolveColumnById(this, `featureValue`, processedData) : void 0; const latValues = hasLatLon ? dataModel.resolveColumnById(this, `latValue`, processedData) : void 0; const lonValues = hasLatLon ? dataModel.resolveColumnById(this, `lonValue`, processedData) : void 0; this.topologyBounds = processedData.dataSources.get(this.id)?.reduce((current, _datum, datumIndex) => { const feature = featureValues?.[datumIndex]; const geometry = feature?.geometry; if (geometry != null) { current = geometryBbox(geometry, current); } if (latValues != null && lonValues != null) { const lon = lonValues[datumIndex]; const lat = latValues[datumIndex]; current = extendBbox(current, lon, lat, lon, lat); } return current; }, void 0); if (sizeKey != null) { const sizeIdx = dataModel.resolveProcessedDataIndexById(this, `sizeValue`); const processedSize = processedData.domain.values[sizeIdx] ?? []; sizeScale.domain = sizeDomain ?? processedSize; } if (colorRange != null && this.isColorScaleValid()) { const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); colorScale.domain = processedData.domain.values[colorKeyIdx]; colorScale.range = colorRange; colorScale.update(); } this.animationState.transition("updateData"); } isColorScaleValid() { const { colorKey } = this.properties; if (!colorKey) { return false; } const { dataModel, processedData } = this; if (!dataModel || !processedData) { return false; } const colorIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); const dataCount = processedData.input.count; const missCount = getMissCount3(this, processedData.defs.values[colorIdx].missing); const colorDataMissing = dataCount === 0 || dataCount === missCount; return !colorDataMissing; } getLabelDatum(datum, labelValue, x, y, size, font22) { if (labelValue == null) return; const { idKey, idName, latitudeKey, latitudeName, longitudeKey, longitudeName, sizeKey, sizeName, colorKey, colorName, labelKey, labelName, label, shape } = this.properties; const { placement } = label; const labelText = this.getLabelText(label, { value: labelValue, datum, idKey, idName, latitudeKey, latitudeName, longitudeKey, longitudeName, sizeKey, sizeName, colorKey, colorName, labelKey, labelName }); if (labelText == null) return; const { width: width2, height: height2 } = CachedTextMeasurerPool8.measureText(String(labelText), { font: font22 }); const anchor = Marker3.anchor(shape); return { point: { x, y, size }, label: { width: width2, height: height2, text: labelText }, anchor, placement }; } createNodeData() { const { id: seriesId, dataModel, processedData, sizeScale, properties, scale: scale2 } = this; const { idKey, latitudeKey, longitudeKey, sizeKey, colorKey, labelKey, label } = properties; if (dataModel == null || processedData == null || scale2 == null) return; const hasLatLon = latitudeKey != null && longitudeKey != null; const idValues = idKey != null ? dataModel.resolveColumnById(this, `idValue`, processedData) : void 0; const featureValues = idKey != null ? dataModel.resolveColumnById(this, `featureValue`, processedData) : void 0; const latValues = hasLatLon ? dataModel.resolveColumnById(this, `latValue`, processedData) : void 0; const lonValues = hasLatLon ? dataModel.resolveColumnById(this, `lonValue`, processedData) : void 0; const labelValues = labelKey != null ? dataModel.resolveColumnById(this, `labelValue`, processedData) : void 0; const sizeValues = sizeKey != null ? dataModel.resolveColumnById(this, `sizeValue`, processedData) : void 0; const colorValues = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0; const markerMaxSize = properties.maxSize ?? properties.size; sizeScale.range = [Math.min(properties.size, markerMaxSize), markerMaxSize]; const font22 = label.getFont(); let projectedGeometries; if (idValues != null && featureValues != null) { projectedGeometries = /* @__PURE__ */ new Map(); processedData.dataSources.get(this.id)?.forEach((_datum, datumIndex) => { const id = idValues[datumIndex]; const geometry = featureValues[datumIndex]?.geometry ?? void 0; const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0; if (id != null && projectedGeometry != null) { projectedGeometries.set(id, projectedGeometry); } }); } const nodeData = []; const labelData = []; const missingGeometries = []; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const idValue = idValues?.[datumIndex]; const lonValue = lonValues?.[datumIndex]; const latValue = latValues?.[datumIndex]; const colorValue = colorValues?.[datumIndex]; const sizeValue = sizeValues?.[datumIndex]; const labelValue = labelValues?.[datumIndex]; const size = sizeValue != null ? sizeScale.convert(sizeValue, true) : properties.size; const projectedGeometry = idValue != null ? projectedGeometries?.get(idValue) : void 0; if (idValue != null && projectGeometry == null) { missingGeometries.push(idValue); } if (lonValue != null && latValue != null) { const [x, y] = scale2.convert([lonValue, latValue]); const labelDatum = this.getLabelDatum(datum, labelValue, x, y, size, font22); if (labelDatum) { labelData.push(labelDatum); } nodeData.push({ series: this, itemId: latitudeKey, datum, datumIndex, index: -1, idValue, lonValue, latValue, labelValue, sizeValue, colorValue, point: { x, y, size }, midPoint: { x, y } }); } else if (projectedGeometry != null) { markerPositions(projectedGeometry, 1).forEach(([x, y], index) => { const labelDatum = this.getLabelDatum(datum, labelValue, x, y, size, font22); if (labelDatum) { labelData.push(labelDatum); } nodeData.push({ series: this, itemId: latitudeKey, datum, datumIndex, index, idValue, lonValue, latValue, labelValue, sizeValue, colorValue, point: { x, y, size }, midPoint: { x, y } }); }); } }); const missingGeometriesCap = 10; if (missingGeometries.length > missingGeometriesCap) { const excessItems = missingGeometries.length - missingGeometriesCap; missingGeometries.length = missingGeometriesCap; missingGeometries.push(`(+${excessItems} more)`); } if (missingGeometries.length > 0) { logger_exports2.warnOnce(`some data items do not have matches in the provided topology`, missingGeometries); } return { itemId: seriesId, nodeData, labelData }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } checkScaleChange() { if (this.previousScale === this.scale) return false; this.previousScale = this.scale; return true; } update({ seriesRect }) { const resize = this.checkResize(seriesRect); const scaleChange = this.checkScaleChange(); const { markerSelection, highlightMarkerSelection } = this; this.updateSelections(); this.contentGroup.visible = this.visible; this.contentGroup.opacity = this.getOpacity(); let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); if (highlightedDatum != null && (highlightedDatum.series !== this || highlightedDatum.datum == null)) { highlightedDatum = void 0; } const nodeData = this.contextNodeData?.nodeData ?? []; this.markerSelection = this.updateMarkerSelection({ markerData: nodeData, markerSelection }); this.updateMarkerNodes({ markerSelection, isHighlight: false, highlightedDatum }); this.highlightMarkerSelection = this.updateMarkerSelection({ markerData: highlightedDatum != null ? [highlightedDatum] : [], markerSelection: highlightMarkerSelection }); this.updateMarkerNodes({ markerSelection: highlightMarkerSelection, isHighlight: true, highlightedDatum }); if (scaleChange || resize) { this.animationState.transition("resize"); } this.animationState.transition("update"); } updatePlacedLabelData(labelData) { this.labelSelection = this.labelSelection.update(labelData, (text22) => { text22.pointerEvents = import_ag_charts_community205._ModuleSupport.PointerEvents.None; }); this.updateLabelNodes({ labelSelection: this.labelSelection }); } updateLabelNodes(opts) { const { labelSelection } = opts; const { color: fill, fontStyle, fontWeight, fontSize, fontFamily } = this.properties.label; labelSelection.each((label, { x, y, width: width2, height: height2, text: text22 }) => { label.visible = true; label.x = x + width2 / 2; label.y = y + height2 / 2; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textAlign = "center"; label.textBaseline = "middle"; }); } updateMarkerSelection(opts) { const { markerData, markerSelection } = opts; return markerSelection.update( markerData, void 0, (datum) => createDatumId11([datum.index, datum.idValue, datum.lonValue, datum.latValue]) ); } getMarkerItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { shape: properties.shape, size: properties.size, fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset }; } getMarkerItemStyleOverrides(datumId, datum, colorValue, sizeValue, format, highlighted) { const { id: seriesId, properties, colorScale, sizeScale } = this; const { colorRange, itemStyler } = properties; let overrides; if (!highlighted && colorValue != null) { overrides ?? (overrides = {}); overrides.fill = this.isColorScaleValid() ? colorScale.convert(colorValue) : colorRange?.[0] ?? properties.fill; } if (sizeValue != null) { overrides ?? (overrides = {}); overrides.size = sizeScale.convert(sizeValue, true); } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId11(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, highlighted, ...format, ...overrides }); } ); overrides ?? (overrides = {}); Object.assign(overrides, itemStyle); } return overrides; } updateMarkerNodes(opts) { const { markerSelection, isHighlight, highlightedDatum } = opts; const style = this.getMarkerItemBaseStyle(isHighlight); markerSelection.each((marker, markerDatum) => { const { datumIndex, datum, point, colorValue, sizeValue } = markerDatum; const overrides = this.getMarkerItemStyleOverrides( String(datumIndex), datum, colorValue, sizeValue, style, isHighlight ); marker.shape = overrides?.shape ?? style.shape; marker.size = overrides?.size ?? style.size; applyShapeStyle4(marker, style, overrides); marker.translationX = point.x; marker.translationY = point.y; marker.zIndex = !isHighlight && highlightedDatum != null && datum === highlightedDatum.datum ? 1 : 0; }); } isProcessedDataAnimatable() { return true; } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } else if (phase === "ready") { this.animationState.transition("skip"); } } resetAllAnimation() { this.ctx.animationManager.stopByAnimationGroupId(this.id); this.ctx.animationManager.skipCurrentBatch(); this.labelSelection.cleanup(); this.markerSelection.cleanup(); this.highlightMarkerSelection.cleanup(); } animateMarkers() { const { animationManager } = this.ctx; const fns = prepareMapMarkerAnimationFunctions(); fromToMotion22(this.id, "markers", animationManager, [this.markerSelection, this.highlightMarkerSelection], fns); } getLabelData() { if (!this.isLabelEnabled()) return []; return this.contextNodeData?.labelData ?? []; } pickNodeClosestDatum(p) { const { x: x0, y: y0 } = p; let minDistanceSquared = Infinity; let minDatum; this.contextNodeData?.nodeData.forEach((datum) => { const { x, y, size } = datum.point; const dx2 = Math.max(Math.abs(x - x0) - size, 0); const dy2 = Math.max(Math.abs(y - y0) - size, 0); const distanceSquared2 = dx2 * dx2 + dy2 * dy2; if (distanceSquared2 < minDistanceSquared) { minDistanceSquared = distanceSquared2; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } legendItemSymbol(datumIndex) { const { dataModel, processedData, properties } = this; const { shape, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = properties; let { fill } = properties; if (datumIndex != null && this.isColorScaleValid()) { const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData); const colorValue = colorValues[datumIndex]; fill = this.colorScale.convert(colorValue); } return { marker: { shape, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } }; } getLegendData(legendType) { const { processedData, dataModel } = this; if (processedData == null || dataModel == null) return []; const { id: seriesId, visible } = this; const { title, legendItemName, idName, idKey, colorKey, colorName, colorRange, showInLegend } = this.properties; if (legendType === "gradient" && colorKey != null && colorRange != null) { const colorDomain = processedData.domain.values[dataModel.resolveProcessedDataIndexById(this, "colorValue")]; const legendDatum = { legendType: "gradient", enabled: visible, seriesId, colorName, colorRange, colorDomain }; return [legendDatum]; } else if (legendType === "category") { const legendDatum = { legendType: "category", id: seriesId, itemId: seriesId, seriesId, enabled: visible, label: { text: legendItemName ?? title ?? idName ?? idKey ?? seriesId }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend }; return [legendDatum]; } else { return []; } } getTooltipContent(seriesDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { idKey, idName, latitudeKey, latitudeName, longitudeKey, longitudeName, colorKey, colorName, sizeKey, sizeName, labelKey, labelName, title, legendItemName, tooltip } = properties; if (!dataModel || !processedData) return; const { datumIndex } = seriesDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const sizeValue = sizeKey != null ? dataModel.resolveColumnById(this, `sizeValue`, processedData)[datumIndex] : void 0; const colorValue = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex] : void 0; const data = []; if (sizeValue != null) { data.push({ label: sizeName, fallbackLabel: sizeKey, value: String(sizeValue) }); } if (colorValue != null) { data.push({ label: colorName, fallbackLabel: colorKey, value: String(colorValue) }); } if (labelKey != null && labelKey !== idKey) { const labelValue = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex]; data.push({ label: labelName, fallbackLabel: labelKey, value: labelValue }); } let heading; if (idKey != null) { heading = dataModel.resolveColumnById(this, `idValue`, processedData)[datumIndex]; } else if (latitudeKey != null && longitudeKey != null) { const latValue = dataModel.resolveColumnById(this, `latValue`, processedData)[datumIndex]; const lonValue = dataModel.resolveColumnById(this, `lonValue`, processedData)[datumIndex]; heading = `${Math.abs(latValue).toFixed(4)}\xB0 ${latValue >= 0 ? "N" : "S"}, ${Math.abs(lonValue).toFixed(4)}\xB0 ${lonValue >= 0 ? "W" : "E"}`; } const format = this.getMarkerItemBaseStyle(false); Object.assign( format, this.getMarkerItemStyleOverrides(String(datumIndex), datumIndex, colorValue, sizeValue, format, false) ); return tooltip.formatTooltip( { heading, title: title ?? legendItemName, symbol: this.legendItemSymbol(datumIndex), data }, { seriesId, datum, title, idKey, idName, latitudeKey, latitudeName, longitudeKey, longitudeName, colorKey, colorName, sizeKey, sizeName, labelKey, labelName, ...format } ); } getFormattedMarkerStyle(markerDatum) { const { datumIndex, colorValue, sizeValue } = markerDatum; const format = this.getMarkerItemBaseStyle(false); Object.assign( format, this.getMarkerItemStyleOverrides(String(datumIndex), datumIndex, colorValue, sizeValue, format, false) ); return { size: format.size }; } computeFocusBounds(opts) { return computeMarkerFocusBounds2(this, opts); } }; MapMarkerSeries.className = "MapMarkerSeries"; MapMarkerSeries.type = "map-marker"; __decorateClass2([ Validate70(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapMarkerSeries.prototype, "_chartTopology", 2); var { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE3 } = import_ag_charts_community206._ModuleSupport.ThemeSymbols; var MapMarkerModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["topology"], identifier: "map-marker", moduleFactory: (ctx) => new MapMarkerSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: { ...MAP_THEME_DEFAULTS, series: { shape: "circle", maxSize: 30, fillOpacity: 0.5, label: { color: { $ref: "textColor" } } } }, paletteFactory: (opts) => { const { takeColors, colorsCount, userPalette, themeTemplateParameters } = opts; const { fill, stroke: stroke22 } = import_ag_charts_community206._ModuleSupport.singleSeriesPaletteFactory(opts); const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE3); const { fills } = takeColors(colorsCount); return { fill, stroke: stroke22, colorRange: userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]] }; } }; var import_ag_charts_community209 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community208 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community207 = (init_main4(), __toCommonJS(main_exports)); var { COLOR_STRING: COLOR_STRING19, LINE_DASH: LINE_DASH15, OBJECT: OBJECT35, POSITIVE_NUMBER: POSITIVE_NUMBER27, RATIO: RATIO23, Validate: Validate71, SeriesProperties: SeriesProperties6, SeriesTooltip: SeriesTooltip12 } = import_ag_charts_community207._ModuleSupport; var MapShapeBackgroundSeriesProperties = class extends SeriesProperties6 { constructor() { super(...arguments); this.topology = void 0; this.fill = "black"; this.fillOpacity = 1; this.stroke = "black"; this.strokeOpacity = 1; this.strokeWidth = 0; this.lineDash = [0]; this.lineDashOffset = 0; this.tooltip = new SeriesTooltip12(); } }; __decorateClass2([ Validate71(GEOJSON_OBJECT, { optional: true }) ], MapShapeBackgroundSeriesProperties.prototype, "topology", 2); __decorateClass2([ Validate71(COLOR_STRING19) ], MapShapeBackgroundSeriesProperties.prototype, "fill", 2); __decorateClass2([ Validate71(RATIO23) ], MapShapeBackgroundSeriesProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate71(COLOR_STRING19) ], MapShapeBackgroundSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate71(RATIO23) ], MapShapeBackgroundSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate71(POSITIVE_NUMBER27) ], MapShapeBackgroundSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate71(LINE_DASH15) ], MapShapeBackgroundSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate71(POSITIVE_NUMBER27) ], MapShapeBackgroundSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate71(OBJECT35) ], MapShapeBackgroundSeriesProperties.prototype, "tooltip", 2); var { createDatumId: createDatumId12, SeriesNodePickMode: SeriesNodePickMode10, Validate: Validate72, Selection: Selection10, Group: Group14, PointerEvents: PointerEvents5 } = import_ag_charts_community208._ModuleSupport; var MapShapeBackgroundSeries = class extends TopologySeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode10.EXACT_SHAPE_MATCH] }); this.properties = new MapShapeBackgroundSeriesProperties(); this._chartTopology = void 0; this.itemGroup = this.contentGroup.appendChild(new Group14({ name: "itemGroup" })); this.datumSelection = Selection10.select( this.itemGroup, () => this.nodeFactory() ); } get topology() { return this.properties.topology ?? this._chartTopology; } get focusable() { return false; } setOptionsData() { } setChartData() { } getNodeData() { return; } get hasData() { return false; } renderToOffscreenCanvas() { return true; } setChartTopology(topology) { this._chartTopology = topology; if (this.topology === topology) { this.nodeDataRefresh = true; } } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [0, index, 0]; this.highlightGroup.zIndex = [0, index, 1]; return true; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 1; geoGeometry.lineJoin = "round"; geoGeometry.pointerEvents = PointerEvents5.None; return geoGeometry; } processData() { const { topology } = this; this.topologyBounds = topology?.features.reduce((current, feature) => { const geometry = feature.geometry; if (geometry == null) return current; return geometryBbox(geometry, current); }, void 0); if (topology == null) { logger_exports2.warnOnce(`no topology was provided for [MapShapeBackgroundSeries]; nothing will be rendered.`); } } createNodeData() { const { id: seriesId, topology, scale: scale2 } = this; if (topology == null) return; const nodeData = []; const labelData = []; topology.features.forEach((feature, index) => { const { geometry } = feature; const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0; if (projectedGeometry == null) return; nodeData.push({ series: this, itemId: index, datum: feature, datumIndex: 0, index, projectedGeometry }); }); return { itemId: seriesId, nodeData, labelData }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } update() { const { datumSelection } = this; this.updateSelections(); this.contentGroup.visible = this.visible; const { nodeData = [] } = this.contextNodeData ?? {}; this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection }); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId12(datum.index)); } updateDatumNodes(opts) { const { properties } = this; const { datumSelection } = opts; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = properties; const strokeWidth = this.getStrokeWidth(properties.strokeWidth); datumSelection.each((geoGeometry, datum) => { const { projectedGeometry } = datum; if (projectedGeometry == null) { geoGeometry.visible = false; geoGeometry.projectedGeometry = void 0; return; } geoGeometry.visible = true; geoGeometry.projectedGeometry = projectedGeometry; geoGeometry.fill = fill; geoGeometry.fillOpacity = fillOpacity; geoGeometry.stroke = stroke22; geoGeometry.strokeWidth = strokeWidth; geoGeometry.strokeOpacity = strokeOpacity; geoGeometry.lineDash = lineDash; geoGeometry.lineDashOffset = lineDashOffset; }); } resetAnimation() { } getLegendData() { return []; } getTooltipContent(_seriesDatum) { return; } pickFocus() { return void 0; } computeFocusBounds(_opts) { return void 0; } }; MapShapeBackgroundSeries.className = "MapShapeBackgroundSeries"; MapShapeBackgroundSeries.type = "map-shape-background"; __decorateClass2([ Validate72(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapShapeBackgroundSeries.prototype, "_chartTopology", 2); var { DEFAULT_HIERARCHY_FILLS: DEFAULT_HIERARCHY_FILLS22 } = import_ag_charts_community209._ModuleSupport.ThemeSymbols; var MapShapeBackgroundModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["topology"], identifier: "map-shape-background", moduleFactory: (ctx) => new MapShapeBackgroundSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: { ...MAP_THEME_DEFAULTS, series: { stroke: { $ref: "backgroundColor" }, strokeWidth: 1 } }, paletteFactory: ({ themeTemplateParameters }) => { return { fill: themeTemplateParameters.get(DEFAULT_HIERARCHY_FILLS22)?.[1] }; } }; var import_ag_charts_community212 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community211 = (init_main4(), __toCommonJS(main_exports)); function preferredLabelCenter(polygons, { aspectRatio, precision }) { const result = polygonPointSearch(polygons, precision, (p, cx, cy, stride) => { const width2 = maxWidthOfRectConstrainedByCenterAndAspectRatioToPolygon(p, cx, cy, aspectRatio); const maxWidth2 = width2 + 2 * stride * aspectRatio; const distance22 = width2 * Math.SQRT2; const maxDistance = maxWidth2 * Math.SQRT2; return { distance: distance22, maxDistance }; }); if (result == null) return; const { x, y, distance: distance2 } = result; const maxWidth = distance2 / Math.SQRT2; return { x, y, maxWidth }; } function maxWidthOfRectConstrainedByCenterAndAspectRatioToLineSegment(a, b, cx, cy, aspectRatio) { const [ax, ay] = a; const [bx, by] = b; const positiveM = 1 / aspectRatio; const abx = bx - ax; const aby = by - ay; const [topPointX, topPointY] = ay <= by ? a : b; const [leftPointX, leftPointY] = ax <= bx ? a : b; const [bottomPointX, bottomPointY] = ay <= by ? b : a; const [rightPointX, rightPointY] = ax <= bx ? b : a; let maxWidth = Infinity; if (abx !== 0) { const abm = aby / abx; for (let i = 0; i <= 1; i += 1) { const m = i === 0 ? positiveM : -positiveM; const x = (abm * ax - ay - m * cx + cy) / (abm - m); if (x >= leftPointX && x <= rightPointX) { const width2 = Math.abs(cx - x) * 2; maxWidth = Math.min(maxWidth, width2); } } } else { for (let i = 0; i <= 1; i += 1) { const m = i === 0 ? positiveM : -positiveM; const y = m * (ax - cx) + cy; if (y >= topPointY && y <= bottomPointY) { const height2 = Math.abs(cy - y) * 2; const width2 = height2 * aspectRatio; maxWidth = Math.min(maxWidth, width2); } } } const positiveMRecip = aspectRatio; const centerToTopMRecip = Math.abs((topPointX - cx) / (topPointY - cy)); const centerToBottomMRecip = Math.abs((bottomPointX - cx) / (bottomPointY - cy)); if (bottomPointY < cy && centerToBottomMRecip < positiveMRecip) { const height2 = Math.abs(cy - bottomPointY) * 2; const width2 = height2 * aspectRatio; maxWidth = Math.min(maxWidth, width2); } else if (topPointY > cy && centerToTopMRecip < positiveMRecip) { const height2 = Math.abs(cy - topPointY) * 2; const width2 = height2 * aspectRatio; maxWidth = Math.min(maxWidth, width2); } const centerToLeftM = Math.abs((leftPointY - cy) / (leftPointX - cx)); const centerToRightM = Math.abs((rightPointY - cy) / (rightPointX - cx)); if (rightPointX < cx && centerToRightM < positiveM) { const width2 = Math.abs(cx - rightPointX) * 2; maxWidth = Math.min(maxWidth, width2); } else if (leftPointX > cx && centerToLeftM < positiveM) { const width2 = Math.abs(cx - leftPointX) * 2; maxWidth = Math.min(maxWidth, width2); } return maxWidth; } function maxWidthOfRectConstrainedByCenterAndAspectRatioToPolygon(polygons, cx, cy, aspectRatio) { let inside = false; let minWidth = Infinity; for (const polygon of polygons) { let p0 = polygon[polygon.length - 1]; let [x0, y0] = p0; for (const p1 of polygon) { const [x1, y1] = p1; if (y1 > cy !== y0 > cy && cx < (x0 - x1) * (cy - y1) / (y0 - y1) + x1) { inside = !inside; } const width2 = maxWidthOfRectConstrainedByCenterAndAspectRatioToLineSegment(p0, p1, cx, cy, aspectRatio); minWidth = Math.min(minWidth, width2); p0 = p1; x0 = x1; y0 = y1; } } return (inside ? 1 : -1) * minWidth; } function applyX(into, cx, x) { if (x >= cx) { into.maxX = Math.min(into.maxX, x - cx); } if (x <= cx) { into.minX = Math.max(into.minX, x - cx); } } function xExtentsOfRectConstrainedByCenterAndHeightToLineSegment(into, a, b, cx, cy, height2) { const ry0 = cy - height2 / 2; const ry1 = cy + height2 / 2; const [ax, ay] = a; const [bx, by] = b; const abx = bx - ax; const aby = by - ay; const [leftPointX, leftPointY] = ax <= bx ? a : b; const [rightPointX, rightPointY] = ax <= bx ? b : a; if (abx !== 0) { const abm = aby / abx; for (let i = 0; i <= 1; i += 1) { const y = i === 0 ? ry0 : ry1; const x = (y - ay) / abm + ax; if (x >= leftPointX && x <= rightPointX) { applyX(into, cx, x); } } } else if (Math.max(ry0, Math.min(ay, by)) <= Math.min(ry1, Math.max(ay, by))) { applyX(into, cx, ax); } if (rightPointX < cx && rightPointY >= ry0 && rightPointY <= ry1) { applyX(into, cx, rightPointX); } else if (leftPointX > cx && leftPointY >= ry0 && leftPointY <= ry1) { applyX(into, cx, leftPointX); } return into; } function maxWidthInPolygonForRectOfHeight(polygons, cx, cy, height2) { const result = { minX: -Infinity, maxX: Infinity }; for (const polygon of polygons) { let p0 = polygon[polygon.length - 1]; for (const p1 of polygon) { xExtentsOfRectConstrainedByCenterAndHeightToLineSegment(result, p0, p1, cx, cy, height2); p0 = p1; } } const { minX, maxX } = result; if (Number.isFinite(minX) && Number.isFinite(maxX)) { return { x: cx + (minX + maxX) / 2, width: maxX - minX }; } else { return { x: cx, width: 0 }; } } var import_ag_charts_community210 = (init_main4(), __toCommonJS(main_exports)); var { AND: AND8, ARRAY: ARRAY11, COLOR_STRING: COLOR_STRING20, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY9, FUNCTION: FUNCTION15, LINE_DASH: LINE_DASH16, OBJECT: OBJECT36, POSITIVE_NUMBER: POSITIVE_NUMBER28, RATIO: RATIO24, STRING: STRING33, Validate: Validate73, SeriesProperties: SeriesProperties7, SeriesTooltip: SeriesTooltip13 } = import_ag_charts_community210._ModuleSupport; var MapShapeSeriesProperties = class extends SeriesProperties7 { constructor() { super(...arguments); this.topology = void 0; this.idKey = ""; this.idName = void 0; this.topologyIdKey = "name"; this.labelKey = void 0; this.labelName = void 0; this.colorRange = void 0; this.fill = "black"; this.fillOpacity = 1; this.stroke = "black"; this.strokeOpacity = 1; this.strokeWidth = 0; this.lineDash = [0]; this.lineDashOffset = 0; this.padding = 0; this.label = new AutoSizedSecondaryLabel(); this.tooltip = new SeriesTooltip13(); } }; __decorateClass2([ Validate73(GEOJSON_OBJECT, { optional: true }) ], MapShapeSeriesProperties.prototype, "topology", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "title", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "legendItemName", 2); __decorateClass2([ Validate73(STRING33) ], MapShapeSeriesProperties.prototype, "idKey", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "idName", 2); __decorateClass2([ Validate73(STRING33) ], MapShapeSeriesProperties.prototype, "topologyIdKey", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "labelName", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "colorKey", 2); __decorateClass2([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "colorName", 2); __decorateClass2([ Validate73(AND8(COLOR_STRING_ARRAY9, ARRAY11.restrict({ minLength: 1 })), { optional: true }) ], MapShapeSeriesProperties.prototype, "colorRange", 2); __decorateClass2([ Validate73(COLOR_STRING20) ], MapShapeSeriesProperties.prototype, "fill", 2); __decorateClass2([ Validate73(RATIO24) ], MapShapeSeriesProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate73(COLOR_STRING20) ], MapShapeSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate73(RATIO24) ], MapShapeSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate73(POSITIVE_NUMBER28) ], MapShapeSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate73(LINE_DASH16) ], MapShapeSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate73(POSITIVE_NUMBER28) ], MapShapeSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate73(POSITIVE_NUMBER28) ], MapShapeSeriesProperties.prototype, "padding", 2); __decorateClass2([ Validate73(FUNCTION15, { optional: true }) ], MapShapeSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate73(OBJECT36) ], MapShapeSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate73(OBJECT36) ], MapShapeSeriesProperties.prototype, "tooltip", 2); var { getMissCount: getMissCount4, createDatumId: createDatumId13, SeriesNodePickMode: SeriesNodePickMode11, valueProperty: valueProperty11, Validate: Validate74, CachedTextMeasurerPool: CachedTextMeasurerPool9, TextUtils: TextUtils6, ColorScale: ColorScale5, Group: Group15, Selection: Selection11, Text: Text5, PointerEvents: PointerEvents6, applyShapeStyle: applyShapeStyle5 } = import_ag_charts_community211._ModuleSupport; var fixedScale = import_ag_charts_community211._ModuleSupport.MercatorScale.fixedScale(); var MapShapeSeries = class extends TopologySeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode11.EXACT_SHAPE_MATCH, SeriesNodePickMode11.NEAREST_NODE] }); this.properties = new MapShapeSeriesProperties(); this._chartTopology = void 0; this.colorScale = new ColorScale5(); this.itemGroup = this.contentGroup.appendChild(new Group15({ name: "itemGroup" })); this.itemLabelGroup = this.contentGroup.appendChild(new Group15({ name: "itemLabelGroup" })); this.datumSelection = Selection11.select( this.itemGroup, () => this.nodeFactory() ); this.labelSelection = Selection11.select( this.itemLabelGroup, Text5 ); this.highlightDatumSelection = Selection11.select( this.highlightNode, () => this.nodeFactory() ); this.previousLabelLayouts = void 0; this._previousDatumMidPoint = void 0; this.itemLabelGroup.pointerEvents = PointerEvents6.None; } getNodeData() { return this.contextNodeData?.nodeData; } get topology() { return this.properties.topology ?? this._chartTopology; } get hasData() { return super.hasData && this.topology != null; } renderToOffscreenCanvas() { return true; } setChartTopology(topology) { this._chartTopology = topology; if (this.topology === topology) { this.nodeDataRefresh = true; } } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [1, index]; this.highlightGroup.zIndex = [2, index]; return true; } isLabelEnabled() { return this.properties.labelKey != null && this.properties.label.enabled; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 1; geoGeometry.lineJoin = "round"; return geoGeometry; } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { data, topology, colorScale } = this; const { topologyIdKey, idKey, colorKey, labelKey, colorRange } = this.properties; const featureById = /* @__PURE__ */ new Map(); topology?.features.forEach((feature) => { const property = feature.properties?.[topologyIdKey]; if (property == null || !containsType( feature.geometry, 1 /* Polygon */ )) return; featureById.set(property, feature); }); const colorScaleType = this.colorScale.type; const mercatorScaleType = this.scale?.type; const { dataModel, processedData } = await this.requestDataModel(dataController, data, { props: [ valueProperty11(idKey, mercatorScaleType, { id: "idValue", includeProperty: false }), valueProperty11(idKey, mercatorScaleType, { id: "featureValue", includeProperty: false, processor: () => (datum) => featureById.get(datum) }), ...labelKey ? [valueProperty11(labelKey, "band", { id: "labelValue" })] : [], ...colorKey ? [valueProperty11(colorKey, colorScaleType, { id: "colorValue" })] : [] ] }); const featureValues = dataModel.resolveColumnById( this, `featureValue`, processedData ); this.topologyBounds = featureValues.reduce((current, feature) => { const geometry = feature?.geometry; if (geometry == null) return current; return geometryBbox(geometry, current); }, void 0); if (colorRange != null && this.isColorScaleValid()) { const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); colorScale.domain = processedData.domain.values[colorKeyIdx]; colorScale.range = colorRange; colorScale.update(); } if (topology == null) { logger_exports2.warnOnce(`no topology was provided for [MapShapeSeries]; nothing will be rendered.`); } } isColorScaleValid() { const { colorKey } = this.properties; if (!colorKey) { return false; } const { dataModel, processedData } = this; if (!dataModel || !processedData) { return false; } const colorIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue"); const dataCount = processedData.input.count; const missCount = getMissCount4(this, processedData.defs.values[colorIdx].missing); const colorDataMissing = dataCount === 0 || dataCount === missCount; return !colorDataMissing; } getLabelLayout(datum, labelValue, font22, geometry, previousLabelLayout) { if (labelValue == null || geometry == null) return; const { idKey, idName, colorKey, colorName, labelKey, labelName, padding, label } = this.properties; const labelText = this.getLabelText(label, { value: labelValue, datum, idKey, idName, colorKey, colorName, labelKey, labelName }); if (labelText == null) return; const baseSize = CachedTextMeasurerPool9.measureText(String(labelText), { font: font22 }); const numLines = labelText.split("\n").length; const aspectRatio = (baseSize.width + 2 * padding) / (numLines * TextUtils6.getLineHeight(label.fontSize) + 2 * padding); if (previousLabelLayout?.geometry === geometry && previousLabelLayout?.labelText === labelText && previousLabelLayout?.aspectRatio === aspectRatio) { return previousLabelLayout; } const fixedGeometry = projectGeometry(geometry, fixedScale); const fixedPolygon = largestPolygon(fixedGeometry); if (fixedPolygon == null) return; const labelPlacement = preferredLabelCenter(fixedPolygon, { aspectRatio, precision: 1e-3 }); if (labelPlacement == null) return; const { x, y, maxWidth } = labelPlacement; return { geometry, labelText, aspectRatio, x, y, maxWidth, fixedPolygon }; } getLabelDatum(labelLayout, scaling) { const { scale: scale2 } = this; if (scale2 == null) return; const { padding, label } = this.properties; const { labelText, aspectRatio, x: untruncatedX, y, maxWidth, fixedPolygon } = labelLayout; const maxSizeWithoutTruncation = { width: Math.ceil(maxWidth * scaling), height: Math.ceil(maxWidth * scaling / aspectRatio), meta: untruncatedX }; const labelFormatting = formatSingleLabel(labelText, label, { padding }, (height2, allowTruncation) => { if (!allowTruncation) return maxSizeWithoutTruncation; const result = maxWidthInPolygonForRectOfHeight(fixedPolygon, untruncatedX, y, height2 / scaling); return { width: result.width * scaling, height: height2, meta: result.x }; }); if (labelFormatting == null) return; const [{ text: text22, fontSize, lineHeight, width: width2 }, formattingX] = labelFormatting; if (text22 === TextUtils6.EllipsisChar) return; const x = width2 < maxSizeWithoutTruncation.width ? untruncatedX : formattingX; const position = this.scale.convert(fixedScale.invert([x, y])); return { x: position[0], y: position[1], text: text22, fontSize, lineHeight }; } createNodeData() { const { id: seriesId, dataModel, processedData, properties, scale: scale2, previousLabelLayouts } = this; const { idKey, colorKey, labelKey, label } = properties; if (dataModel == null || processedData == null) return; const scaling = scale2 != null ? (scale2.range[1][0] - scale2.range[0][0]) / scale2.bounds.width : NaN; const idValues = dataModel.resolveColumnById(this, `idValue`, processedData); const featureValues = dataModel.resolveColumnById( this, `featureValue`, processedData ); const labelValues = labelKey != null ? dataModel.resolveColumnById(this, `labelValue`, processedData) : void 0; const colorValues = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0; const font22 = label.getFont(); const labelLayouts = /* @__PURE__ */ new Map(); this.previousLabelLayouts = labelLayouts; const nodeData = []; const labelData = []; const missingGeometries = []; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const idValue = idValues[datumIndex]; const colorValue = colorValues?.[datumIndex]; const labelValue = labelValues?.[datumIndex]; const geometry = featureValues[datumIndex]?.geometry ?? void 0; if (geometry == null) { missingGeometries.push(idValue); } const labelLayout = this.getLabelLayout( datum, labelValue, font22, geometry, previousLabelLayouts?.get(idValue) ); if (labelLayout != null) { labelLayouts.set(idValue, labelLayout); } const labelDatum = labelLayout != null && scale2 != null ? this.getLabelDatum(labelLayout, scaling) : void 0; if (labelDatum != null) { labelData.push(labelDatum); } const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0; nodeData.push({ series: this, itemId: idKey, datum, datumIndex, idValue, colorValue, labelValue, projectedGeometry }); }); const missingGeometriesCap = 10; if (missingGeometries.length > missingGeometriesCap) { const excessItems = missingGeometries.length - missingGeometriesCap; missingGeometries.length = missingGeometriesCap; missingGeometries.push(`(+${excessItems} more)`); } if (missingGeometries.length > 0) { logger_exports2.warnOnce(`some data items do not have matches in the provided topology`, missingGeometries); } return { itemId: seriesId, nodeData, labelData }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } update() { const { datumSelection, labelSelection, highlightDatumSelection } = this; this.updateSelections(); this.contentGroup.visible = this.visible; this.contentGroup.opacity = this.getOpacity(); let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); if (highlightedDatum != null && (highlightedDatum.series !== this || highlightedDatum.datum == null)) { highlightedDatum = void 0; } const nodeData = this.contextNodeData?.nodeData ?? []; const labelData = this.contextNodeData?.labelData ?? []; this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection, isHighlight: false }); this.labelSelection = this.updateLabelSelection({ labelData, labelSelection }); this.updateLabelNodes({ labelSelection }); this.highlightDatumSelection = this.updateDatumSelection({ nodeData: highlightedDatum != null ? [highlightedDatum] : [], datumSelection: highlightDatumSelection }); this.updateDatumNodes({ datumSelection: highlightDatumSelection, isHighlight: true }); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId13(datum.idValue)); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset }; } getItemStyleOverrides(datumId, datum, colorValue, format, highlighted) { const { id: seriesId, properties, colorScale } = this; const { colorRange, itemStyler } = properties; let overrides; if (!highlighted && colorValue != null) { overrides ?? (overrides = {}); overrides.fill = this.isColorScaleValid() ? colorScale.convert(colorValue) : colorRange?.[0] ?? properties.fill; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId13(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, highlighted, ...format, ...overrides }); } ); overrides ?? (overrides = {}); Object.assign(overrides, itemStyle); } return overrides; } updateDatumNodes(opts) { const { datumSelection, isHighlight } = opts; const style = this.getItemBaseStyle(isHighlight); datumSelection.each((geoGeometry, nodeDatum) => { const { datum, datumIndex, colorValue, projectedGeometry } = nodeDatum; if (projectedGeometry == null) { geoGeometry.visible = false; geoGeometry.projectedGeometry = void 0; return; } const overrides = this.getItemStyleOverrides(String(datumIndex), datum, colorValue, style, isHighlight); geoGeometry.visible = true; geoGeometry.projectedGeometry = projectedGeometry; applyShapeStyle5(geoGeometry, style, overrides); }); } updateLabelSelection(opts) { const labels = this.isLabelEnabled() ? opts.labelData : []; return opts.labelSelection.update(labels); } updateLabelNodes(opts) { const { labelSelection } = opts; const { color: fill, fontStyle, fontWeight, fontFamily } = this.properties.label; labelSelection.each((label, { x, y, text: text22, fontSize, lineHeight }) => { label.visible = true; label.x = x; label.y = y; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.lineHeight = lineHeight; label.fontFamily = fontFamily; label.textAlign = "center"; label.textBaseline = "middle"; }); } resetAnimation() { } pickNodeClosestDatum({ x, y }) { let minDistanceSquared = Infinity; let minDatum; this.datumSelection.each((node, datum) => { const distanceSquared2 = node.distanceSquared(x, y); if (distanceSquared2 < minDistanceSquared) { minDistanceSquared = distanceSquared2; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } datumMidPoint(datum) { const { _previousDatumMidPoint } = this; if (_previousDatumMidPoint?.datum === datum) { return _previousDatumMidPoint.point; } const projectedGeometry = datum.projectedGeometry; const polygon = projectedGeometry != null ? largestPolygon(projectedGeometry) : void 0; const center2 = polygon != null ? polygonMarkerCenter(polygon, 2) : void 0; const point = center2 != null ? { x: center2[0], y: center2[1] } : void 0; this._previousDatumMidPoint = { datum, point }; return point; } legendItemSymbol(datumIndex) { const { dataModel, processedData, properties } = this; const { fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = properties; let { fill } = properties; if (datumIndex != null && this.isColorScaleValid()) { const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData); const colorValue = colorValues[datumIndex]; fill = this.colorScale.convert(colorValue); } return { marker: { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } }; } getLegendData(legendType) { const { processedData, dataModel } = this; if (processedData == null || dataModel == null) return []; const { id: seriesId, visible } = this; const { title, legendItemName, idKey, idName, colorKey, colorName, colorRange, showInLegend } = this.properties; if (legendType === "gradient" && colorKey != null && colorRange != null) { const colorDomain = processedData.domain.values[dataModel.resolveProcessedDataIndexById(this, "colorValue")]; const legendDatum = { legendType: "gradient", enabled: visible, seriesId, colorName, colorRange, colorDomain }; return [legendDatum]; } else if (legendType === "category") { const legendDatum = { legendType: "category", id: seriesId, itemId: seriesId, seriesId, enabled: visible, label: { text: legendItemName ?? title ?? idName ?? idKey }, symbol: this.legendItemSymbol(), legendItemName, hideInLegend: !showInLegend }; return [legendDatum]; } else { return []; } } getTooltipContent(seriesDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { idKey, idName, colorKey, colorName, labelKey, labelName, legendItemName, title, tooltip } = properties; if (!dataModel || !processedData) return; const { datumIndex } = seriesDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const idValue = dataModel.resolveColumnById(this, `idValue`, processedData)[datumIndex]; const colorValue = colorKey != null ? dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex] : void 0; const data = []; if (colorValue != null) { data.push({ label: colorName, fallbackLabel: colorKey, value: String(colorValue) }); } if (labelKey != null && labelKey !== idKey) { const labelValue = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex]; data.push({ label: labelName, fallbackLabel: labelKey, value: labelValue }); } const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datumIndex, colorValue, format, false)); return tooltip.formatTooltip( { heading: idValue, title: title ?? legendItemName, symbol: this.legendItemSymbol(datumIndex), data }, { seriesId, datum, title, idKey, idName, colorKey, colorName, labelKey, labelName, ...format } ); } computeFocusBounds(opts) { return findFocusedGeoGeometry(this, opts); } }; MapShapeSeries.className = "MapShapeSeries"; MapShapeSeries.type = "map-shape"; __decorateClass2([ Validate74(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapShapeSeries.prototype, "_chartTopology", 2); var { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE4, DEFAULT_BACKGROUND_COLOUR: DEFAULT_BACKGROUND_COLOUR3 } = import_ag_charts_community212._ModuleSupport.ThemeSymbols; var MapShapeModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["topology"], identifier: "map-shape", moduleFactory: (ctx) => new MapShapeSeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: { ...MAP_THEME_DEFAULTS, series: { fillOpacity: 1, strokeWidth: 1, lineDash: [0], lineDashOffset: 0, padding: 2, label: { color: { $ref: "backgroundColor" }, fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: "bold", overflowStrategy: "hide" } } }, paletteFactory: (opts) => { const { takeColors, colorsCount, userPalette, themeTemplateParameters } = opts; const { fill } = import_ag_charts_community212._ModuleSupport.singleSeriesPaletteFactory(opts); const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE4); const { fills } = takeColors(colorsCount); return { fill, stroke: themeTemplateParameters.get(DEFAULT_BACKGROUND_COLOUR3), colorRange: userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]] }; } }; var import_ag_charts_community219 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community217 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community213 = (init_main4(), __toCommonJS(main_exports)); var { ChartAxisDirection: ChartAxisDirection25, PolarAxis: PolarAxis22, diff: diff4, fixNumericExtent: fixNumericExtent5, groupAccumulativeValueProperty: groupAccumulativeValueProperty22, keyProperty: keyProperty6, normaliseGroupTo: normaliseGroupTo2, resetLabelFn: resetLabelFn22, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation22, seriesLabelFadeOutAnimation: seriesLabelFadeOutAnimation2, valueProperty: valueProperty12, animationValidation: animationValidation4, createDatumId: createDatumId14, SeriesNodePickMode: SeriesNodePickMode12, normalizeAngle360: normalizeAngle3606, CategoryScale: CategoryScale3, motion: motion4, applyShapeStyle: applyShapeStyle6 } = import_ag_charts_community213._ModuleSupport; var RadialColumnSeriesNodeEvent = class extends import_ag_charts_community213._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.angleKey = series.properties.angleKey; this.radiusKey = series.properties.radiusKey; } }; var RadialColumnSeriesBase = class extends import_ag_charts_community213._ModuleSupport.PolarSeries { constructor(moduleCtx, { animationResetFns }) { super({ moduleCtx, useLabelLayer: true, canHaveAxes: true, pickModes: [SeriesNodePickMode12.NEAREST_NODE, SeriesNodePickMode12.EXACT_SHAPE_MATCH], animationResetFns: { ...animationResetFns, label: resetLabelFn22 } }); this.NodeEvent = RadialColumnSeriesNodeEvent; this.groupScale = new CategoryScale3(); this.circleCache = { r: 0, cx: 0, cy: 0 }; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!processedData || !dataModel) return []; if (direction === ChartAxisDirection25.X) { return dataModel.getDomain(this, "angleValue", "key", processedData); } else { const yExtent = dataModel.getDomain(this, "radiusValue-end", "value", processedData); const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [yExtent[0] > 0 ? 0 : yExtent[0], yExtent[1] < 0 ? 0 : yExtent[1]] : []; return fixNumericExtent5(fixedYExtent); } } async processData(dataController) { const { visible } = this; const { angleKey, radiusKey, normalizedTo } = this.properties; const animationEnabled = !this.ctx.animationManager.isSkipped(); if (!this.properties.isValid()) return; const stackGroupId = this.getStackId(); const stackGroupTrailingId = `${stackGroupId}-trailing`; const extraProps = []; if (isDefined2(normalizedTo)) { extraProps.push(normaliseGroupTo2([stackGroupId, stackGroupTrailingId], Math.abs(normalizedTo))); } if (animationEnabled && this.processedData) { extraProps.push(diff4(this.id, this.processedData)); } if (animationEnabled) { extraProps.push(animationValidation4()); } const visibleProps = visible || !animationEnabled ? {} : { forceValue: 0 }; const radiusScaleType = this.axes[ChartAxisDirection25.Y]?.scale.type; const angleScaleType = this.axes[ChartAxisDirection25.X]?.scale.type; await this.requestDataModel(dataController, this.data, { props: [ keyProperty6(angleKey, angleScaleType, { id: "angleValue" }), valueProperty12(radiusKey, radiusScaleType, { id: "radiusValue-raw", invalidValue: null, ...visibleProps }), ...groupAccumulativeValueProperty22( radiusKey, "normal", "current", { id: `radiusValue-end`, rangeId: `radiusValue-range`, invalidValue: null, groupId: stackGroupId, separateNegative: true, ...visibleProps }, radiusScaleType ), ...groupAccumulativeValueProperty22( radiusKey, "trailing", "current", { id: `radiusValue-start`, invalidValue: null, groupId: stackGroupTrailingId, separateNegative: true, ...visibleProps }, radiusScaleType ), ...extraProps ], groupByKeys: true, groupByData: false }); this.animationState.transition("updateData"); } didCircleChange() { const r = this.radius; const cx = this.centerX; const cy = this.centerY; const cache = this.circleCache; if (r !== cache.r || cx !== cache.cx || cy !== cache.cy) { this.circleCache = { r, cx, cy }; return true; } return false; } isRadiusAxisReversed() { return this.axes[ChartAxisDirection25.Y]?.isReversed(); } maybeRefreshNodeData() { const circleChanged = this.didCircleChange(); if (!circleChanged && !this.nodeDataRefresh) return; const { nodeData = [] } = this.createNodeData() ?? {}; this.nodeData = nodeData; this.nodeDataRefresh = false; } getAxisInnerRadius() { const radiusAxis = this.axes[ChartAxisDirection25.Y]; return radiusAxis instanceof PolarAxis22 ? this.radius * radiusAxis.innerRadiusRatio : 0; } createNodeData() { const { processedData, dataModel, groupScale } = this; if (!dataModel || !processedData || processedData.type !== "grouped" || !this.properties.isValid()) { return; } const angleAxis = this.axes[ChartAxisDirection25.X]; const radiusAxis = this.axes[ChartAxisDirection25.Y]; const angleScale = angleAxis?.scale; const radiusScale = radiusAxis?.scale; if (!angleScale || !radiusScale) { return; } const angleValues = dataModel.resolveKeysById(this, `angleValue`, processedData); const radiusStartValues = dataModel.resolveColumnById(this, `radiusValue-start`, processedData); const radiusEndValues = dataModel.resolveColumnById(this, `radiusValue-end`, processedData); const radiusRawValues = dataModel.resolveColumnById(this, `radiusValue-raw`, processedData); const radiusRangeIndex = dataModel.resolveProcessedDataIndexById(this, `radiusValue-range`); let groupPaddingInner = 0; let groupPaddingOuter = 0; if (angleAxis instanceof AngleCategoryAxis) { groupPaddingInner = angleAxis.groupPaddingInner; groupPaddingOuter = angleAxis.paddingInner; } const groupAngleStep = angleScale.bandwidth ?? 0; const paddedGroupAngleStep = groupAngleStep * (1 - groupPaddingOuter); const { index: groupIndex, visibleGroupCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this); groupScale.domain = Array.from({ length: visibleGroupCount }).map((_, i) => String(i)); groupScale.range = [-paddedGroupAngleStep / 2, paddedGroupAngleStep / 2]; groupScale.paddingInner = visibleGroupCount > 1 ? groupPaddingInner : 0; const radiusAxisReversed = this.isRadiusAxisReversed(); const axisInnerRadius = radiusAxisReversed ? this.radius : this.getAxisInnerRadius(); const axisOuterRadius = radiusAxisReversed ? this.getAxisInnerRadius() : this.radius; const axisTotalRadius = axisOuterRadius + axisInnerRadius; const { angleKey, radiusKey, angleName, radiusName, label } = this.properties; const getLabelNodeDatum = (datum, radiusDatum, x, y) => { const labelText = this.getLabelText(label, { value: radiusDatum, datum, angleKey, radiusKey, angleName, radiusName }); if (labelText) { return { x, y, text: labelText, textAlign: "center", textBaseline: "middle" }; } }; const nodeData = []; const context = { itemId: radiusKey, nodeData, labelData: nodeData }; if (!this.visible) return context; const { dataSources } = processedData; const rawData = dataSources.get(this.id) ?? []; for (const { datumIndex, group } of dataModel.forEachGroupDatum(this, processedData)) { const datum = rawData[datumIndex]; const angleDatum = angleValues[datumIndex]; if (angleDatum == null) return; const radiusDatum = radiusRawValues[datumIndex]; const isPositive = radiusDatum >= 0 && !Object.is(radiusDatum, -0); const innerRadiusDatum = radiusStartValues[datumIndex]; const outerRadiusDatum = radiusEndValues[datumIndex]; const radiusRange = group.aggregation[radiusRangeIndex][isPositive ? 1 : 0] ?? 0; const negative = isPositive === radiusAxisReversed; if (innerRadiusDatum === void 0 || outerRadiusDatum === void 0) return; let startAngle; let endAngle; if (rawData.length === 1) { startAngle = -0.5 * Math.PI; endAngle = 1.5 * Math.PI; } else { const groupAngle = angleScale.convert(angleDatum); startAngle = normalizeAngle3606(groupAngle + groupScale.convert(String(groupIndex))); endAngle = normalizeAngle3606(startAngle + groupScale.bandwidth); } const angle2 = startAngle + groupScale.bandwidth / 2; const innerRadius = axisTotalRadius - radiusScale.convert(innerRadiusDatum); const outerRadius = axisTotalRadius - radiusScale.convert(outerRadiusDatum); const midRadius = (innerRadius + outerRadius) / 2; const stackInnerRadius = axisTotalRadius - radiusScale.convert(0); const stackOuterRadius = axisTotalRadius - radiusScale.convert(radiusRange); const x = Math.cos(angle2) * midRadius; const y = Math.sin(angle2) * midRadius; const labelNodeDatum = this.properties.label.enabled ? getLabelNodeDatum(datum, radiusDatum, x, y) : void 0; const columnWidth = this.getColumnWidth(startAngle, endAngle); nodeData.push({ series: this, datum, datumIndex, point: { x, y, size: 0 }, midPoint: { x, y }, label: labelNodeDatum, angleValue: angleDatum, radiusValue: radiusDatum, negative, innerRadius, outerRadius, stackInnerRadius, stackOuterRadius, startAngle, endAngle, axisInnerRadius, axisOuterRadius, columnWidth, index: datumIndex }); } return { itemId: radiusKey, nodeData, labelData: nodeData }; } getColumnWidth(_startAngle, _endAngle) { return NaN; } update({ seriesRect }) { const resize = this.checkResize(seriesRect); this.maybeRefreshNodeData(); this.contentGroup.translationX = this.centerX; this.contentGroup.translationY = this.centerY; this.highlightGroup.translationX = this.centerX; this.highlightGroup.translationY = this.centerY; if (this.labelGroup) { this.labelGroup.translationX = this.centerX; this.labelGroup.translationY = this.centerY; } this.updateSectorSelection(this.itemSelection, false); this.updateSectorSelection(this.highlightSelection, true); this.updateLabels(); if (resize) { this.animationState.transition("resize"); } this.animationState.transition("update"); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset, cornerRadius: properties.cornerRadius }; } getItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { angleKey, radiusKey, itemStyler } = properties; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId14(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, highlighted, angleKey, radiusKey, ...format }); }); } updateSectorSelection(selection, highlighted) { let selectionData = []; if (highlighted) { const activeHighlight = this.ctx.highlightManager?.getActiveHighlight(); if (activeHighlight?.datum && activeHighlight.series === this) { selectionData.push(activeHighlight); } } else { selectionData = this.nodeData; } const style = this.getItemBaseStyle(highlighted); selection.update(selectionData, void 0, (datum) => this.getDatumId(datum)).each((node, nodeDatum) => { const { datum, datumIndex } = nodeDatum; const overrides = this.getItemStyleOverrides(String(datumIndex), datum, style, highlighted); this.updateItemPath(node, nodeDatum, highlighted); applyShapeStyle6(node, style, overrides); node.cornerRadius = overrides?.cornerRadius ?? style.cornerRadius; node.lineJoin = "round"; }); } updateLabels() { const { label } = this.properties; this.labelSelection.update(this.nodeData).each((node, datum) => { if (label.enabled && datum.label) { node.x = datum.label.x; node.y = datum.label.y; node.fill = label.color; node.fontFamily = label.fontFamily; node.fontSize = label.fontSize; node.fontStyle = label.fontStyle; node.fontWeight = label.fontWeight; node.text = datum.label.text; node.textAlign = datum.label.textAlign; node.textBaseline = datum.label.textBaseline; node.visible = true; } else { node.visible = false; } }); } animateEmptyUpdateReady() { const { labelSelection } = this; const fns = this.getColumnTransitionFunctions(); motion4.fromToMotion(this.id, "datums", this.ctx.animationManager, [this.itemSelection], fns); seriesLabelFadeInAnimation22(this, "labels", this.ctx.animationManager, labelSelection); } animateClearingUpdateEmpty() { const { itemSelection } = this; const { animationManager } = this.ctx; const fns = this.getColumnTransitionFunctions(); motion4.fromToMotion(this.id, "datums", animationManager, [itemSelection], fns); seriesLabelFadeOutAnimation2(this, "labels", animationManager, this.labelSelection); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { angleKey, angleName, radiusKey, radiusName, tooltip } = properties; const angleAxis = axes[ChartAxisDirection25.X]; const radiusAxis = axes[ChartAxisDirection25.Y]; if (!dataModel || !processedData || !angleAxis || !radiusAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const angleValue = dataModel.resolveKeysById(this, `angleValue`, processedData)[datumIndex]; const radiusValue = dataModel.resolveColumnById(this, `radiusValue-raw`, processedData)[datumIndex]; if (angleValue == null) return; const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datumIndex, format, false)); return tooltip.formatTooltip( { heading: angleAxis.formatDatum(angleValue), symbol: this.legendItemSymbol(), data: [{ label: radiusName, fallbackLabel: radiusKey, value: radiusAxis.formatDatum(radiusValue) }] }, { seriesId, datum, title: angleName, angleKey, angleName, radiusKey, radiusName, ...format } ); } pickNodeClosestDatum(point) { return this.pickNodeNearestDistantObject(point, this.itemSelection.nodes()); } legendItemSymbol() { const { fill, stroke: stroke22, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties; return { marker: { fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke22 ?? "rgba(0, 0, 0, 0)", fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (!this.properties.isValid() || legendType !== "category") { return []; } const { id: seriesId, visible } = this; const { radiusKey, radiusName, showInLegend } = this.properties; return [ { legendType: "category", id: seriesId, itemId: radiusKey, seriesId, enabled: visible, label: { text: radiusName ?? radiusKey }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } getDatumId(datum) { return createDatumId14(datum.angleValue); } computeLabelsBBox() { return null; } }; var import_ag_charts_community214 = (init_main4(), __toCommonJS(main_exports)); var { SeriesProperties: SeriesProperties8, SeriesTooltip: SeriesTooltip14, Validate: Validate75, COLOR_STRING: COLOR_STRING21, NUMBER: NUMBER17, FUNCTION: FUNCTION16, LINE_DASH: LINE_DASH17, OBJECT: OBJECT37, POSITIVE_NUMBER: POSITIVE_NUMBER29, RATIO: RATIO25, STRING: STRING34, Label: Label9 } = import_ag_charts_community214._ModuleSupport; var RadialColumnSeriesBaseProperties = class extends SeriesProperties8 { constructor() { super(...arguments); this.fill = "black"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.rotation = 0; this.label = new Label9(); this.tooltip = new SeriesTooltip14(); } }; __decorateClass2([ Validate75(STRING34) ], RadialColumnSeriesBaseProperties.prototype, "angleKey", 2); __decorateClass2([ Validate75(STRING34, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "angleName", 2); __decorateClass2([ Validate75(STRING34) ], RadialColumnSeriesBaseProperties.prototype, "radiusKey", 2); __decorateClass2([ Validate75(STRING34, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "radiusName", 2); __decorateClass2([ Validate75(COLOR_STRING21) ], RadialColumnSeriesBaseProperties.prototype, "fill", 2); __decorateClass2([ Validate75(RATIO25) ], RadialColumnSeriesBaseProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate75(COLOR_STRING21) ], RadialColumnSeriesBaseProperties.prototype, "stroke", 2); __decorateClass2([ Validate75(POSITIVE_NUMBER29) ], RadialColumnSeriesBaseProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate75(RATIO25) ], RadialColumnSeriesBaseProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate75(LINE_DASH17) ], RadialColumnSeriesBaseProperties.prototype, "lineDash", 2); __decorateClass2([ Validate75(POSITIVE_NUMBER29) ], RadialColumnSeriesBaseProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate75(POSITIVE_NUMBER29) ], RadialColumnSeriesBaseProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate75(FUNCTION16, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate75(NUMBER17) ], RadialColumnSeriesBaseProperties.prototype, "rotation", 2); __decorateClass2([ Validate75(STRING34, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "stackGroup", 2); __decorateClass2([ Validate75(NUMBER17, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "normalizedTo", 2); __decorateClass2([ Validate75(OBJECT37) ], RadialColumnSeriesBaseProperties.prototype, "label", 2); __decorateClass2([ Validate75(OBJECT37) ], RadialColumnSeriesBaseProperties.prototype, "tooltip", 2); var import_ag_charts_community216 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community215 = (init_main4(), __toCommonJS(main_exports)); var { motion: motion5 } = import_ag_charts_community215._ModuleSupport; function createAngleMotionCalculator() { const angles = { startAngle: /* @__PURE__ */ new Map(), endAngle: /* @__PURE__ */ new Map() }; const angleKeys = ["startAngle", "endAngle"]; const calculate = (node, datum, status) => { angleKeys.forEach((key) => { const map = angles[key]; let from22 = (status === "removed" || status === "updated" ? node : datum)[key]; let to2 = (status === "removed" ? node : datum)[key]; if (isNaN(to2)) { to2 = node.previousDatum?.[key] ?? NaN; } const diff8 = from22 - to2; if (Math.abs(diff8) > Math.PI) { from22 -= Math.sign(diff8) * 2 * Math.PI; } map.set(datum, { from: from22, to: to2 }); }); }; const getAngles = (datum, fromToKey) => { return { startAngle: angles.startAngle.get(datum)[fromToKey], endAngle: angles.endAngle.get(datum)[fromToKey] }; }; const from3 = (datum) => getAngles(datum, "from"); const to = (datum) => getAngles(datum, "to"); return { calculate, from: from3, to }; } function fixRadialColumnAnimationStatus(node, datum, status) { if (status === "updated") { if (node.previousDatum == null || isNaN(node.previousDatum.startAngle) || isNaN(node.previousDatum.endAngle)) { return "added"; } if (isNaN(datum.startAngle) || isNaN(datum.endAngle)) { return "removed"; } } if (status === "added" && node.previousDatum != null) { return "updated"; } return status; } function prepareRadialColumnAnimationFunctions(axisZeroRadius) { const angles = createAngleMotionCalculator(); const fromFn = (node, datum, status) => { status = fixRadialColumnAnimationStatus(node, datum, status); angles.calculate(node, datum, status); const { startAngle, endAngle } = angles.from(datum); let innerRadius; let outerRadius; let columnWidth; let axisInnerRadius; let axisOuterRadius; if (status === "removed" || status === "updated") { innerRadius = node.innerRadius; outerRadius = node.outerRadius; columnWidth = node.columnWidth; axisInnerRadius = node.axisInnerRadius; axisOuterRadius = node.axisOuterRadius; } else { innerRadius = axisZeroRadius; outerRadius = axisZeroRadius; columnWidth = datum.columnWidth; axisInnerRadius = datum.axisInnerRadius; axisOuterRadius = datum.axisOuterRadius; } const phase = motion5.NODE_UPDATE_STATE_TO_PHASE_MAPPING[status]; return { innerRadius, outerRadius, columnWidth, axisInnerRadius, axisOuterRadius, startAngle, endAngle, phase }; }; const toFn = (node, datum, status) => { const { startAngle, endAngle } = angles.to(datum); let innerRadius; let outerRadius; let columnWidth; let axisInnerRadius; let axisOuterRadius; if (status === "removed") { innerRadius = node.innerRadius; outerRadius = node.innerRadius; columnWidth = node.columnWidth; axisInnerRadius = node.axisInnerRadius; axisOuterRadius = node.axisOuterRadius; } else { innerRadius = isNaN(datum.innerRadius) ? axisZeroRadius : datum.innerRadius; outerRadius = isNaN(datum.outerRadius) ? axisZeroRadius : datum.outerRadius; columnWidth = isNaN(datum.columnWidth) ? node.columnWidth : datum.columnWidth; axisInnerRadius = datum.axisInnerRadius; axisOuterRadius = datum.axisOuterRadius; } return { innerRadius, outerRadius, columnWidth, axisInnerRadius, axisOuterRadius, startAngle, endAngle }; }; return { toFn, fromFn }; } function resetRadialColumnSelectionFn(_node, { innerRadius, outerRadius, columnWidth, axisInnerRadius, axisOuterRadius, startAngle, endAngle }) { return { innerRadius, outerRadius, columnWidth, axisInnerRadius, axisOuterRadius, startAngle, endAngle }; } var { SectorBox: SectorBox2, motion: motion6 } = import_ag_charts_community216._ModuleSupport; function getRadii(datum) { const { negative, innerRadius, outerRadius, stackInnerRadius, stackOuterRadius } = datum; return { innerRadius: negative ? stackOuterRadius : stackInnerRadius, outerRadius: negative ? stackInnerRadius : stackOuterRadius, clipInnerRadius: negative ? outerRadius : innerRadius, clipOuterRadius: negative ? innerRadius : outerRadius }; } function prepareNightingaleAnimationFunctions(axisZeroRadius) { const angles = createAngleMotionCalculator(); const fromFn = (sect, datum, status) => { status = fixRadialColumnAnimationStatus(sect, datum, status); angles.calculate(sect, datum, status); const { startAngle, endAngle } = angles.from(datum); let innerRadius; let outerRadius; let clipSector; if (status === "removed" || status === "updated") { innerRadius = sect.innerRadius; outerRadius = sect.outerRadius; clipSector = sect.clipSector; } else { innerRadius = axisZeroRadius; outerRadius = axisZeroRadius; } clipSector ?? (clipSector = new SectorBox2(startAngle, endAngle, innerRadius, outerRadius)); const phase = motion6.NODE_UPDATE_STATE_TO_PHASE_MAPPING[status]; return { innerRadius, outerRadius, startAngle, endAngle, clipSector, phase }; }; const toFn = (_sect, datum, status) => { const { startAngle, endAngle } = angles.to(datum); let innerRadius; let outerRadius; let clipSector; if (status === "removed") { innerRadius = axisZeroRadius; outerRadius = axisZeroRadius; clipSector = new SectorBox2(startAngle, endAngle, innerRadius, outerRadius); } else { let clipInnerRadius, clipOuterRadius; ({ innerRadius, outerRadius, clipInnerRadius, clipOuterRadius } = getRadii(datum)); if (isNaN(innerRadius)) innerRadius = axisZeroRadius; if (isNaN(outerRadius)) outerRadius = axisZeroRadius; if (isNaN(clipInnerRadius)) clipInnerRadius = axisZeroRadius; if (isNaN(clipOuterRadius)) clipOuterRadius = axisZeroRadius; clipSector = new SectorBox2(startAngle, endAngle, clipInnerRadius, clipOuterRadius); } return { innerRadius, outerRadius, startAngle, endAngle, clipSector }; }; return { toFn, fromFn }; } function resetNightingaleSelectionFn(_sect, datum) { const { startAngle, endAngle } = datum; const { innerRadius, outerRadius, clipInnerRadius, clipOuterRadius } = getRadii(datum); const clipSector = new SectorBox2(startAngle, endAngle, clipInnerRadius, clipOuterRadius); return { innerRadius, outerRadius, startAngle, endAngle, clipSector }; } var { Sector: Sector4, SectorBox: SectorBox22, PolarZIndexMap: PolarZIndexMap2 } = import_ag_charts_community217._ModuleSupport; var NightingaleSeries = class extends RadialColumnSeriesBase { // TODO: Enable once the options contract has been revisited // @Validate(POSITIVE_NUMBER) // sectorSpacing = 1; constructor(moduleCtx) { super(moduleCtx, { animationResetFns: { item: resetNightingaleSelectionFn } }); this.properties = new RadialColumnSeriesBaseProperties(); } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.contentGroup.zIndex = [0, PolarZIndexMap2.FOREGROUND, index]; this.highlightGroup.zIndex = [0, PolarZIndexMap2.HIGHLIGHT, index]; this.labelGroup.zIndex = [0, PolarZIndexMap2.LABEL, index]; return true; } getStackId() { const groupIndex = this.seriesGrouping?.groupIndex ?? this.id; return `nightingale-stack-${groupIndex}-yValues`; } nodeFactory() { return new Sector4(); } updateItemPath(node, datum, highlight) { const { negative } = datum; node.centerX = 0; node.centerY = 0; node.startOuterCornerRadius = !negative ? this.properties.cornerRadius : 0; node.endOuterCornerRadius = !negative ? this.properties.cornerRadius : 0; node.startInnerCornerRadius = negative ? this.properties.cornerRadius : 0; node.endInnerCornerRadius = negative ? this.properties.cornerRadius : 0; if (highlight) { const { startAngle, endAngle } = datum; const { innerRadius, outerRadius, clipInnerRadius, clipOuterRadius } = getRadii(datum); node.innerRadius = innerRadius; node.outerRadius = outerRadius; node.startAngle = startAngle; node.endAngle = endAngle; node.clipSector = new SectorBox22(startAngle, endAngle, clipInnerRadius, clipOuterRadius); } } getColumnTransitionFunctions() { const axisZeroRadius = this.isRadiusAxisReversed() ? this.radius : this.getAxisInnerRadius(); return prepareNightingaleAnimationFunctions(axisZeroRadius); } }; NightingaleSeries.className = "NightingaleSeries"; NightingaleSeries.type = "nightingale"; var import_ag_charts_community218 = (init_main4(), __toCommonJS(main_exports)); var { ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE2, POLAR_AXIS_SHAPE: POLAR_AXIS_SHAPE2 } } = import_ag_charts_community218._ModuleSupport; var NIGHTINGALE_SERIES_THEME = { series: { strokeWidth: 1, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } } }, axes: { [POLAR_AXIS_TYPE2.ANGLE_CATEGORY]: { shape: POLAR_AXIS_SHAPE2.CIRCLE, groupPaddingInner: 0, paddingInner: 0, label: { spacing: 10 } }, [POLAR_AXIS_TYPE2.RADIUS_NUMBER]: { shape: POLAR_AXIS_SHAPE2.CIRCLE } } }; var { ThemeSymbols: { DEFAULT_POLAR_SERIES_STROKE: DEFAULT_POLAR_SERIES_STROKE2 }, ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE22 } } = import_ag_charts_community219._ModuleSupport; var NightingaleModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "nightingale", moduleFactory: (ctx) => new NightingaleSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: [{ type: POLAR_AXIS_TYPE22.ANGLE_CATEGORY }, { type: POLAR_AXIS_TYPE22.RADIUS_NUMBER }], themeTemplate: NIGHTINGALE_SERIES_THEME, paletteFactory({ takeColors, userPalette }) { const { fills: [fill], strokes: [stroke22] } = takeColors(1); return { fill, stroke: userPalette !== "inbuilt" ? stroke22 : DEFAULT_POLAR_SERIES_STROKE2 }; }, stackable: true, groupable: true, stackedByDefault: true }; var import_ag_charts_community221 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community220 = (init_main4(), __toCommonJS(main_exports)); var { createDatumId: createDatumId15 } = import_ag_charts_community220._ModuleSupport; var OhlcSeries = class extends OhlcSeriesBase { constructor() { super(...arguments); this.properties = new OhlcSeriesProperties(); } nodeFactory() { return new OhlcNode(); } updateDatumNodes({ datumSelection, isHighlight }) { const { id: seriesId, properties } = this; const { xKey, highKey, lowKey, openKey, closeKey, item, itemStyler } = properties; const { up, down } = item; const { stroke: upStroke, strokeWidth: upStrokeWidth, strokeOpacity: upStrokeOpacity, lineDash: upLineDash, lineDashOffset: upLineDashOffset } = up; const { stroke: downStroke, strokeWidth: downStrokeWidth, strokeOpacity: downStrokeOpacity, lineDash: downLineDash, lineDashOffset: downLineDashOffset } = down; const highlightStyle = isHighlight ? properties.highlightStyle.item : void 0; datumSelection.each((node, datum) => { const { isRising, centerX, width: width2, y, height: height2, yOpen, yClose, crisp } = datum; let style; if (itemStyler != null) { const { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = isRising ? up : down; style = this.cachedDatumCallback( createDatumId15(this.getDatumId(datum), isHighlight ? "highlight" : "node"), () => itemStyler({ seriesId, itemId: datum.itemId, xKey, highKey, lowKey, openKey, closeKey, datum: datum.datum, strokeOpacity, stroke: stroke22, strokeWidth, lineDash, lineDashOffset, highlighted: isHighlight }) ); } node.centerX = centerX; node.width = width2; node.y = y; node.height = height2; node.yOpen = yOpen; node.yClose = yClose; node.crisp = crisp; node.stroke = highlightStyle?.stroke ?? style?.stroke ?? (isRising ? upStroke : downStroke); node.strokeWidth = highlightStyle?.strokeWidth ?? style?.strokeWidth ?? (isRising ? upStrokeWidth : downStrokeWidth); node.strokeOpacity = highlightStyle?.strokeOpacity ?? style?.strokeOpacity ?? (isRising ? upStrokeOpacity : downStrokeOpacity); node.lineDash = highlightStyle?.lineDash ?? style?.lineDash ?? (isRising ? upLineDash : downLineDash); node.lineDashOffset = highlightStyle?.lineDashOffset ?? style?.lineDashOffset ?? (isRising ? upLineDashOffset : downLineDashOffset); node.strokeAlignment = (style?.strokeWidth ?? (isRising ? upStrokeWidth : downStrokeWidth)) / 2; }); } getLegendData(legendType) { const { id, data, ctx: { legendManager }, visible } = this; const { xKey, yName, item: { up, down }, showInLegend, legendItemName } = this.properties; if (!data?.length || !xKey || legendType !== "category") { return []; } const fill = new import_ag_charts_community220._ModuleSupport.LinearGradient( "rgb", [ { color: up.stroke, offset: 0 }, { color: up.stroke, offset: 0.5 }, { color: down.stroke, offset: 0.5 } ], 90 ); return [ { legendType: "category", id, itemId: id, seriesId: id, enabled: visible && legendManager.getItemEnabled({ seriesId: id, itemId: id }), label: { text: legendItemName ?? yName ?? id }, symbol: { marker: { fill, fillOpacity: up.strokeOpacity, stroke: void 0, strokeWidth: 0, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0 } }, legendItemName, hideInLegend: !showInLegend } ]; } }; OhlcSeries.className = "ohlc"; OhlcSeries.type = "ohlc"; var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE9, CARTESIAN_POSITION: CARTESIAN_POSITION5 } = import_ag_charts_community221._ModuleSupport.ThemeConstants; var OhlcModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "ohlc", moduleFactory: (ctx) => new OhlcSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: CARTESIAN_AXIS_TYPE9.NUMBER, position: CARTESIAN_POSITION5.LEFT }, { type: CARTESIAN_AXIS_TYPE9.ORDINAL_TIME, position: CARTESIAN_POSITION5.BOTTOM } ], themeTemplate: { animation: { enabled: false }, axes: { [CARTESIAN_AXIS_TYPE9.NUMBER]: { crosshair: { snap: false } }, [CARTESIAN_AXIS_TYPE9.ORDINAL_TIME]: { groupPaddingInner: 0, crosshair: { enabled: true } } } }, groupable: false, paletteFactory: ({ takeColors, colorsCount, userPalette, palette }) => { if (userPalette === "user-indexed") { const [stroke22] = takeColors(colorsCount).strokes; return { item: { up: { stroke: stroke22 }, down: { stroke: stroke22 } } }; } return { item: { up: { stroke: palette.up.stroke }, down: { stroke: palette.down.stroke } } }; } }; var import_ag_charts_community225 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community223 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community222 = (init_main4(), __toCommonJS(main_exports)); var { SeriesProperties: SeriesProperties9, SeriesTooltip: SeriesTooltip15, Validate: Validate76, UNION: UNION15, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY10, FUNCTION: FUNCTION17, DIRECTION: DIRECTION22, BOOLEAN: BOOLEAN30, LINE_DASH: LINE_DASH18, OBJECT: OBJECT38, NUMBER: NUMBER18, POSITIVE_NUMBER: POSITIVE_NUMBER30, RATIO: RATIO26, STRING: STRING35, Label: Label10, DropShadow: DropShadow22 } = import_ag_charts_community222._ModuleSupport; var PyramidSeriesLabel = class extends Label10 { }; var PyramidSeriesStageLabel = class extends Label10 { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass2([ Validate76(NUMBER18) ], PyramidSeriesStageLabel.prototype, "spacing", 2); __decorateClass2([ Validate76(UNION15(["before", "after"], "a placement")) ], PyramidSeriesStageLabel.prototype, "placement", 2); var PyramidProperties = class extends SeriesProperties9 { constructor() { super(...arguments); this.fills = []; this.fillOpacity = 1; this.strokes = []; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.direction = "vertical"; this.reverse = void 0; this.spacing = 0; this.aspectRatio = void 0; this.shadow = new DropShadow22().set({ enabled: false }); this.label = new PyramidSeriesLabel(); this.stageLabel = new PyramidSeriesStageLabel(); this.tooltip = new SeriesTooltip15(); } }; __decorateClass2([ Validate76(STRING35) ], PyramidProperties.prototype, "stageKey", 2); __decorateClass2([ Validate76(STRING35) ], PyramidProperties.prototype, "valueKey", 2); __decorateClass2([ Validate76(COLOR_STRING_ARRAY10) ], PyramidProperties.prototype, "fills", 2); __decorateClass2([ Validate76(RATIO26) ], PyramidProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate76(COLOR_STRING_ARRAY10) ], PyramidProperties.prototype, "strokes", 2); __decorateClass2([ Validate76(POSITIVE_NUMBER30) ], PyramidProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate76(RATIO26) ], PyramidProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate76(LINE_DASH18) ], PyramidProperties.prototype, "lineDash", 2); __decorateClass2([ Validate76(POSITIVE_NUMBER30) ], PyramidProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate76(DIRECTION22) ], PyramidProperties.prototype, "direction", 2); __decorateClass2([ Validate76(BOOLEAN30, { optional: true }) ], PyramidProperties.prototype, "reverse", 2); __decorateClass2([ Validate76(POSITIVE_NUMBER30) ], PyramidProperties.prototype, "spacing", 2); __decorateClass2([ Validate76(POSITIVE_NUMBER30, { optional: true }) ], PyramidProperties.prototype, "aspectRatio", 2); __decorateClass2([ Validate76(FUNCTION17, { optional: true }) ], PyramidProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate76(OBJECT38) ], PyramidProperties.prototype, "shadow", 2); __decorateClass2([ Validate76(OBJECT38) ], PyramidProperties.prototype, "label", 2); __decorateClass2([ Validate76(OBJECT38) ], PyramidProperties.prototype, "stageLabel", 2); __decorateClass2([ Validate76(OBJECT38) ], PyramidProperties.prototype, "tooltip", 2); var { valueProperty: valueProperty13, SeriesNodePickMode: SeriesNodePickMode13, CachedTextMeasurerPool: CachedTextMeasurerPool10, TextUtils: TextUtils7, createDatumId: createDatumId16, BBox: BBox16, Group: Group16, Selection: Selection12, Text: Text6, PointerEvents: PointerEvents7, applyShapeStyle: applyShapeStyle7 } = import_ag_charts_community223._ModuleSupport; var PyramidSeries = class extends import_ag_charts_community223._ModuleSupport.DataModelSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [SeriesNodePickMode13.EXACT_SHAPE_MATCH, SeriesNodePickMode13.NEAREST_NODE] }); this.properties = new PyramidProperties(); this.itemGroup = this.contentGroup.appendChild(new Group16({ name: "itemGroup" })); this.itemLabelGroup = this.contentGroup.appendChild(new Group16({ name: "itemLabelGroup" })); this.stageLabelGroup = this.contentGroup.appendChild(new Group16({ name: "stageLabelGroup" })); this.datumSelection = Selection12.select( this.itemGroup, () => this.nodeFactory() ); this.labelSelection = Selection12.select( this.itemLabelGroup, Text6 ); this.stageLabelSelection = Selection12.select(this.stageLabelGroup, Text6); this.highlightDatumSelection = Selection12.select( this.highlightNode, () => this.nodeFactory() ); this.itemLabelGroup.pointerEvents = PointerEvents7.None; this.stageLabelGroup.pointerEvents = PointerEvents7.None; } addChartEventListeners() { this.destroyFns.push( this.ctx.chartEventManager?.addListener("legend-item-click", (event) => this.onLegendItemClick(event)) ); } nodeFactory() { return new FunnelConnector(); } getNodeData() { return this.contextNodeData?.nodeData; } async processData(dataController) { if (this.data == null || !this.properties.isValid()) { return; } const { id: seriesId, visible, ctx: { legendManager } } = this; const { stageKey, valueKey } = this.properties; const xScaleType = "band"; const yScaleType = "number"; const validation = (_value, _datum, index) => visible && legendManager.getItemEnabled({ seriesId, itemId: index }); const visibleProps = this.visible ? {} : { forceValue: 0 }; await this.requestDataModel(dataController, this.data, { props: [ valueProperty13(stageKey, xScaleType, { id: "xValue" }), valueProperty13(valueKey, yScaleType, { id: `yValue`, ...visibleProps, validation, invalidValue: 0 }) ] }); } createNodeData() { const { id: seriesId, dataModel, processedData, properties, visible, ctx: { legendManager } } = this; const { stageKey, valueKey, direction, reverse = direction === "horizontal", spacing, aspectRatio, label, stageLabel } = properties; if (dataModel == null || processedData == null) return; const horizontal = direction === "horizontal"; const xValues = dataModel.resolveColumnById(this, `xValue`, processedData); const yValues = dataModel.resolveColumnById(this, `yValue`, processedData); const textMeasurer = CachedTextMeasurerPool10.getMeasurer({ font: stageLabel.getFont() }); let textAlign; let textBaseline; if (horizontal) { textAlign = "center"; textBaseline = stageLabel.placement === "before" ? "bottom" : "top"; } else { textAlign = stageLabel.placement === "after" ? "left" : "right"; textBaseline = "middle"; } const stageLabelData = stageLabel.enabled ? [] : void 0; let maxLabelWidth = 0; let maxLabelHeight = 0; let yTotal = 0; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const xValue = xValues[datumIndex]; const yValue = yValues[datumIndex]; const enabled = visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }); yTotal += yValue; if (stageLabelData == null) return; const text22 = this.getLabelText(this.properties.stageLabel, { datum, value: xValue, stageKey, valueKey }); const { width: width2 } = textMeasurer.measureText(text22); const height2 = text22.split("\n").length * TextUtils7.getLineHeight(label.fontSize); maxLabelWidth = Math.max(maxLabelWidth, width2); maxLabelHeight = Math.max(maxLabelHeight, height2); stageLabelData.push({ x: NaN, y: NaN, text: text22, textAlign, textBaseline, visible: enabled }); }); const seriesRectWidth = this._nodeDataDependencies?.seriesRectWidth ?? 0; const seriesRectHeight = this._nodeDataDependencies?.seriesRectHeight ?? 0; const totalSpacing = spacing * (processedData.input.count - 1); let bounds; if (horizontal) { const verticalInset = maxLabelHeight + stageLabel.spacing; bounds = new BBox16( 0, stageLabel.placement === "before" ? verticalInset : 0, seriesRectWidth, seriesRectHeight - verticalInset ); } else { const horizontalInset = maxLabelWidth + stageLabel.spacing; bounds = new BBox16( stageLabel.placement === "after" ? 0 : horizontalInset, 0, seriesRectWidth - horizontalInset, seriesRectHeight ); } if (aspectRatio != null && aspectRatio !== 0) { const directionalAspectRatio = direction === "horizontal" ? 1 / aspectRatio : aspectRatio; const constrainedWidth = Math.min(bounds.width, bounds.height * directionalAspectRatio); const constrainedHeight = constrainedWidth / directionalAspectRatio; bounds = new BBox16( bounds.x + (bounds.width - constrainedWidth) / 2, bounds.y + (bounds.height - constrainedHeight) / 2, constrainedWidth, constrainedHeight ); } let labelX; let labelY; if (horizontal) { labelY = stageLabel.placement === "before" ? bounds.y - stageLabel.spacing : bounds.y + bounds.height + stageLabel.spacing; } else { labelX = stageLabel.placement === "after" ? bounds.x + bounds.width + stageLabel.spacing : bounds.x - stageLabel.spacing; } const availableWidth = bounds.width - (horizontal ? totalSpacing : 0); const availableHeight = bounds.height - (horizontal ? 0 : totalSpacing); if (availableWidth < 0 || availableHeight < 0) return; const nodeData = []; const labelData = []; let yStart = 0; rawData.forEach((datum, datumIndex) => { const xValue = xValues[datumIndex]; const yValue = yValues[datumIndex]; const enabled = visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }); const yEnd = yStart + yValue; const yMidRatio = (yStart + yEnd) / (2 * yTotal); const yRangeRatio = (yEnd - yStart) / yTotal; const xOffset = horizontal ? availableWidth * yMidRatio + spacing * datumIndex : availableWidth * 0.5; const yOffset = horizontal ? availableHeight * 0.5 : availableHeight * yMidRatio + spacing * datumIndex; const x = bounds.x + xOffset; const y = bounds.y + yOffset; if (stageLabelData != null) { const stageLabelDatum = stageLabelData[datumIndex]; stageLabelDatum.x = labelX ?? x; stageLabelDatum.y = labelY ?? y; } let top; let right; let bottom; let left; if (horizontal) { const barWidth = availableWidth * yRangeRatio; top = barWidth; bottom = barWidth; const y0 = (xOffset + barWidth / 2) * (availableHeight / bounds.width); const y1 = (xOffset - barWidth / 2) * (availableHeight / bounds.width); right = reverse ? bounds.height - y0 : y0; left = reverse ? bounds.height - y1 : y1; } else { const barHeight = availableHeight * yRangeRatio; right = barHeight; left = barHeight; const x0 = (yOffset - barHeight / 2) * (availableWidth / bounds.height); const x1 = (yOffset + barHeight / 2) * (availableWidth / bounds.height); top = reverse ? bounds.width - x0 : x0; bottom = reverse ? bounds.width - x1 : x1; } const text22 = this.getLabelText(label, { datum, value: yValue, stageKey, valueKey }); const labelDatum = { x, y, text: text22, textAlign: "center", textBaseline: "middle", visible: enabled }; labelData.push(labelDatum); nodeData.push({ series: this, itemId: valueKey, datum, datumIndex, index: datumIndex, xValue, yValue, x, y, top, right, bottom, left, label: labelDatum, enabled, midPoint: { x, y } }); yStart = yEnd; }); return { itemId: seriesId, nodeData, labelData, stageLabelData }; } updateSelections() { if (this.nodeDataRefresh) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } update({ seriesRect }) { this.checkResize(seriesRect); const { datumSelection, labelSelection, stageLabelSelection, highlightDatumSelection } = this; this.updateSelections(); this.contentGroup.visible = this.visible; this.contentGroup.opacity = this.getOpacity(); let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); if (highlightedDatum != null && (highlightedDatum.series !== this || highlightedDatum.datum == null)) { highlightedDatum = void 0; } const nodeData = this.contextNodeData?.nodeData ?? []; const labelData = this.contextNodeData?.labelData ?? []; const stageLabelData = this.contextNodeData?.stageLabelData ?? []; this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection, isHighlight: false }); this.labelSelection = this.updateLabelSelection({ labelData, labelSelection }); this.updateLabelNodes({ labelSelection, labelProperties: this.properties.label }); this.stageLabelSelection = this.updateStageLabelSelection({ stageLabelData, stageLabelSelection }); this.updateLabelNodes({ labelSelection: stageLabelSelection, labelProperties: this.properties.stageLabel }); this.highlightDatumSelection = this.updateDatumSelection({ nodeData: highlightedDatum != null ? [highlightedDatum] : [], datumSelection: highlightDatumSelection }); this.updateDatumNodes({ datumSelection: highlightDatumSelection, isHighlight: true }); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset }; } getItemStyleOverrides(datumId, datum, datumIndex, format, highlighted) { const { id: seriesId, properties } = this; const { fills, strokes, stageKey, valueKey, itemStyler } = properties; const fill = format.fill ?? fills[datumIndex % fills.length]; const stroke22 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId16(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, stageKey, valueKey, highlighted, fill, stroke: stroke22, ...format }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateDatumNodes(opts) { const { datumSelection, isHighlight } = opts; const { properties } = this; const { shadow } = properties; const style = this.getItemBaseStyle(isHighlight); datumSelection.each((connector, nodeDatum) => { const { datumIndex, datum, x, y, top, right, bottom, left } = nodeDatum; const overrides = this.getItemStyleOverrides(String(datumIndex), datum, datumIndex, style, isHighlight); connector.x0 = x - top / 2; connector.x1 = x + top / 2; connector.x2 = x + bottom / 2; connector.x3 = x - bottom / 2; connector.y0 = y - left / 2; connector.y1 = y - right / 2; connector.y2 = y + right / 2; connector.y3 = y + left / 2; applyShapeStyle7(connector, style, overrides); connector.fillShadow = shadow; }); } updateLabelSelection(opts) { return opts.labelSelection.update(this.properties.label.enabled ? opts.labelData : []); } updateStageLabelSelection(opts) { return opts.stageLabelSelection.update(opts.stageLabelData); } updateLabelNodes(opts) { const { labelSelection, labelProperties } = opts; const { color: fill, fontSize, fontStyle, fontWeight, fontFamily } = labelProperties; labelSelection.each((label, { visible, x, y, text: text22, textAlign, textBaseline }) => { label.visible = visible; label.x = x; label.y = y; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textAlign = textAlign; label.textBaseline = textBaseline; }); } resetAnimation(_chartAnimationPhase) { } computeFocusBounds(opts) { const datum = this.getNodeData()?.[opts.datumIndex]; if (datum === void 0) return; for (const node of this.datumSelection) { if (node.datum === datum) { return node.node; } } } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { stageKey, valueKey, tooltip } = properties; if (!dataModel || !processedData) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveColumnById(this, "xValue", processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex]; if (xValue == null) return; const value = this.getLabelText(this.properties.stageLabel, { datum: processedData.dataSources.get(this.id)?.[datumIndex], value: yValue, stageKey, valueKey }); const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datumIndex, datumIndex, format, false)); return tooltip.formatTooltip( { symbol: this.legendItemSymbol(datumIndex), data: [ { label: String(xValue), value } ] }, { seriesId, datum, title: void 0, stageKey, valueKey, ...format } ); } getSeriesDomain() { return [NaN, NaN]; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } pickNodeClosestDatum({ x, y }) { let minDistanceSquared = Infinity; let minDatum; this.datumSelection.each((node, datum) => { const distanceSquared2 = node.distanceSquared(x, y); if (distanceSquared2 < minDistanceSquared) { minDistanceSquared = distanceSquared2; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } legendItemSymbol(datumIndex) { const { fills, strokes, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.properties; const fill = fills[datumIndex % fills.length] ?? "black"; const stroke22 = strokes[datumIndex % strokes.length] ?? "black"; return { marker: { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } }; } getLegendData(legendType) { const { processedData, dataModel, id: seriesId, ctx: { legendManager }, visible } = this; if (!dataModel || !processedData || legendType !== "category" || !this.properties.isValid()) { return []; } const { showInLegend } = this.properties; const legendData = []; const stageValues = dataModel.resolveColumnById(this, `xValue`, processedData); const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((_datum, datumIndex) => { const stageValue = stageValues[datumIndex]; legendData.push({ legendType: "category", id: seriesId, itemId: datumIndex, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }), label: { text: stageValue }, symbol: this.legendItemSymbol(datumIndex), hideInLegend: !showInLegend }); }); return legendData; } }; PyramidSeries.className = "PyramidSeries"; PyramidSeries.type = "pyramid"; var import_ag_charts_community224 = (init_main4(), __toCommonJS(main_exports)); var { ThemeSymbols: { DEFAULT_SHADOW_COLOUR: DEFAULT_SHADOW_COLOUR22 } } = import_ag_charts_community224._ModuleSupport; var PYRAMID_SERIES_THEME = { series: { direction: "vertical", strokeWidth: 0, spacing: 2, label: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" } }, stageLabel: { enabled: true, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, spacing: 12 }, shadow: { enabled: false, color: DEFAULT_SHADOW_COLOUR22, xOffset: 3, yOffset: 3, blur: 5 } } }; var PyramidModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["standalone"], identifier: "pyramid", moduleFactory: (ctx) => new PyramidSeries(ctx), solo: true, tooltipDefaults: { range: "exact" }, themeTemplate: PYRAMID_SERIES_THEME, paletteFactory: ({ takeColors, colorsCount }) => { const { fills, strokes } = takeColors(colorsCount); return { fills, strokes }; } }; var import_ag_charts_community231 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community226 = (init_main4(), __toCommonJS(main_exports)); var { ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE3 } } = import_ag_charts_community226._ModuleSupport; var BASE_RADAR_SERIES_THEME = { series: { label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } }, marker: { enabled: true, fillOpacity: 1, shape: "circle", size: 6, strokeOpacity: 1, strokeWidth: 0 } }, axes: { [POLAR_AXIS_TYPE3.ANGLE_CATEGORY]: { label: { spacing: 10 } } } }; var RADAR_LINE_SERIES_THEME = import_ag_charts_community226._ModuleSupport.mergeDefaults({ series: { strokeWidth: 2 } }, BASE_RADAR_SERIES_THEME); var RADAR_AREA_SERIES_THEME = import_ag_charts_community226._ModuleSupport.mergeDefaults( { series: { fillOpacity: 0.8, strokeWidth: 2, marker: { enabled: false } } }, BASE_RADAR_SERIES_THEME ); var import_ag_charts_community230 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community228 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community227 = (init_main4(), __toCommonJS(main_exports)); var { Label: Label11, SeriesMarker: SeriesMarker2, SeriesProperties: SeriesProperties10, SeriesTooltip: SeriesTooltip16, Validate: Validate77, BOOLEAN: BOOLEAN31, COLOR_STRING: COLOR_STRING222, NUMBER: NUMBER19, LINE_DASH: LINE_DASH19, OBJECT: OBJECT39, POSITIVE_NUMBER: POSITIVE_NUMBER31, RATIO: RATIO27, STRING: STRING36 } = import_ag_charts_community227._ModuleSupport; var RadarSeriesProperties = class extends SeriesProperties10 { constructor() { super(...arguments); this.stroke = "black"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.rotation = 0; this.marker = new SeriesMarker2(); this.label = new Label11(); this.tooltip = new SeriesTooltip16(); this.connectMissingData = false; } }; __decorateClass2([ Validate77(STRING36) ], RadarSeriesProperties.prototype, "angleKey", 2); __decorateClass2([ Validate77(STRING36) ], RadarSeriesProperties.prototype, "radiusKey", 2); __decorateClass2([ Validate77(STRING36, { optional: true }) ], RadarSeriesProperties.prototype, "angleName", 2); __decorateClass2([ Validate77(STRING36, { optional: true }) ], RadarSeriesProperties.prototype, "radiusName", 2); __decorateClass2([ Validate77(COLOR_STRING222) ], RadarSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate77(POSITIVE_NUMBER31) ], RadarSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate77(RATIO27) ], RadarSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate77(LINE_DASH19) ], RadarSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate77(POSITIVE_NUMBER31) ], RadarSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate77(NUMBER19) ], RadarSeriesProperties.prototype, "rotation", 2); __decorateClass2([ Validate77(OBJECT39) ], RadarSeriesProperties.prototype, "marker", 2); __decorateClass2([ Validate77(OBJECT39) ], RadarSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate77(OBJECT39) ], RadarSeriesProperties.prototype, "tooltip", 2); __decorateClass2([ Validate77(BOOLEAN31) ], RadarSeriesProperties.prototype, "connectMissingData", 2); var { ChartAxisDirection: ChartAxisDirection26, PolarAxis: PolarAxis3, SeriesNodePickMode: SeriesNodePickMode14, valueProperty: valueProperty14, fixNumericExtent: fixNumericExtent6, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation3, markerFadeInAnimation: markerFadeInAnimation2, resetMarkerFn: resetMarkerFn2, animationValidation: animationValidation5, computeMarkerFocusBounds: computeMarkerFocusBounds22, extent: extent2, isNumberEqual: isNumberEqual9, createDatumId: createDatumId17, BBox: BBox17, Group: Group17, Path: Path11, PointerEvents: PointerEvents8, Selection: Selection13, Text: Text7, Marker: Marker4, applyShapeStyle: applyShapeStyle8 } = import_ag_charts_community228._ModuleSupport; var RadarSeriesNodeEvent = class extends import_ag_charts_community228._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.angleKey = series.properties.angleKey; this.radiusKey = series.properties.radiusKey; } }; var RadarSeries = class extends import_ag_charts_community228._ModuleSupport.PolarSeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode14.NEAREST_NODE, SeriesNodePickMode14.EXACT_SHAPE_MATCH], canHaveAxes: true, animationResetFns: { item: resetMarkerFn2 } }); this.clipFocusBox = false; this.properties = new RadarSeriesProperties(); this.NodeEvent = RadarSeriesNodeEvent; this.lineGroup = this.contentGroup.appendChild( new Group17({ name: "radar-line", zIndex: import_ag_charts_community228._ModuleSupport.SeriesZIndexMap.ANY_CONTENT }) ); this.lineSelection = Selection13.select( this.lineGroup, Path11 ); this.resetInvalidToZero = false; this.circleCache = { r: 0, cx: 0, cy: 0 }; } nodeFactory() { return new Marker4(); } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.lineGroup.zIndex = [ import_ag_charts_community228._ModuleSupport.SeriesZIndexMap.ANY_CONTENT, index, import_ag_charts_community228._ModuleSupport.SeriesContentZIndexMap.FOREGROUND, 1 ]; return true; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!processedData || !dataModel) return []; if (direction === ChartAxisDirection26.X) { return dataModel.getDomain(this, `angleValue`, "value", processedData); } else { const domain = dataModel.getDomain(this, `radiusValue`, "value", processedData); const ext = extent2(domain.length === 0 ? domain : [0].concat(domain)); return fixNumericExtent6(ext); } } async processData(dataController) { if (!this.properties.isValid()) { return; } const { angleKey, radiusKey } = this.properties; const extraProps = []; if (!this.ctx.animationManager.isSkipped()) { extraProps.push(animationValidation5()); } const radiusScaleType = this.axes[ChartAxisDirection26.Y]?.scale.type; const angleScaleType = this.axes[ChartAxisDirection26.X]?.scale.type; await this.requestDataModel(dataController, this.data, { props: [ valueProperty14(angleKey, angleScaleType, { id: "angleValue" }), valueProperty14(radiusKey, radiusScaleType, { id: "radiusValue", invalidValue: void 0 }), ...extraProps ] }); this.animationState.transition("updateData"); } didCircleChange() { const r = this.radius; const cx = this.centerX; const cy = this.centerY; const cache = this.circleCache; if (!(r === cache.r && cx === cache.cx && cy === cache.cy)) { this.circleCache = { r, cx, cy }; return true; } return false; } getAxisInnerRadius() { const radiusAxis = this.axes[ChartAxisDirection26.Y]; return radiusAxis instanceof PolarAxis3 ? this.radius * radiusAxis.innerRadiusRatio : 0; } maybeRefreshNodeData() { const didCircleChange = this.didCircleChange(); if (!didCircleChange && !this.nodeDataRefresh) return; const { nodeData = [] } = this.createNodeData() ?? {}; this.nodeData = nodeData; this.nodeDataRefresh = false; } createNodeData() { const { processedData, dataModel } = this; if (!processedData || !dataModel || !this.properties.isValid()) return; const { angleKey, radiusKey, angleName, radiusName, marker, label } = this.properties; const angleScale = this.axes[ChartAxisDirection26.X]?.scale; const radiusScale = this.axes[ChartAxisDirection26.Y]?.scale; if (!angleScale || !radiusScale) { return; } const angleValues = dataModel.resolveColumnById(this, `angleValue`, processedData); const radiusValues = dataModel.resolveColumnById(this, `radiusValue`, processedData); const axisInnerRadius = this.getAxisInnerRadius(); const rawData = processedData.dataSources.get(this.id) ?? []; const nodeData = rawData.map((datum, datumIndex) => { const angleDatum = angleValues[datumIndex]; const radiusDatum = radiusValues[datumIndex]; const angle2 = angleScale.convert(angleDatum); const radius = this.radius + axisInnerRadius - radiusScale.convert(radiusDatum); const cos = Math.cos(angle2); const sin = Math.sin(angle2); const x = cos * radius; const y = sin * radius; let labelNodeDatum; if (label.enabled) { const labelText = this.getLabelText(label, { value: radiusDatum, datum, angleKey, radiusKey, angleName, radiusName }); if (labelText) { let textAlign = "right"; if (isNumberEqual9(cos, 0)) { textAlign = "center"; } else if (cos > 0) { textAlign = "left"; } let textBaseline = "bottom"; if (isNumberEqual9(sin, 0)) { textBaseline = "middle"; } else if (sin > 0) { textBaseline = "top"; } labelNodeDatum = { x: x + cos * marker.size, y: y + sin * marker.size, text: labelText, textAlign, textBaseline }; } } return { series: this, datum, datumIndex, index: datumIndex, point: { x, y, size: marker.size }, midPoint: { x, y }, label: labelNodeDatum, angleValue: angleDatum, radiusValue: radiusDatum, missing: !isFiniteNumber2(angle2) || !isFiniteNumber2(radius) }; }); return { itemId: radiusKey, nodeData, labelData: nodeData }; } update({ seriesRect }) { const resize = this.checkResize(seriesRect); const animationEnabled = !this.ctx.animationManager.isSkipped(); const { series } = this.ctx.highlightManager?.getActiveHighlight() ?? {}; this.highlightGroup.visible = (animationEnabled || this.visible) && series === this; this.maybeRefreshNodeData(); this.contentGroup.translationX = this.centerX; this.contentGroup.translationY = this.centerY; this.highlightGroup.translationX = this.centerX; this.highlightGroup.translationY = this.centerY; if (this.labelGroup) { this.labelGroup.translationX = this.centerX; this.labelGroup.translationY = this.centerY; } this.updatePathSelections(); this.updateMarkerSelection(); this.updateMarkers(this.itemSelection, false); this.updateMarkers(this.highlightSelection, true); this.updateLabels(); if (resize) { this.animationState.transition("resize"); } this.animationState.transition("update"); } updatePathSelections() { const pathData = this.visible ? [true] : []; this.lineSelection.update(pathData); } updateMarkerSelection() { if (this.properties.marker.isDirty()) { this.itemSelection.clear(); this.itemSelection.cleanup(); this.itemSelection = Selection13.select(this.itemGroup, () => this.nodeFactory(), false); } this.itemSelection.update(this.properties.marker.enabled ? this.nodeData : []); } getMarkerFill(highlightedStyle) { return highlightedStyle?.fill ?? this.properties.marker.fill; } getMarkerItemBaseStyle(highlighted) { const { properties } = this; const { marker } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { shape: marker.shape, size: marker.size, fill: highlightStyle?.fill ?? marker.fill, fillOpacity: highlightStyle?.fillOpacity ?? marker.fillOpacity, stroke: highlightStyle?.stroke ?? marker.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(marker.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? marker.strokeOpacity, lineDash: highlightStyle?.lineDash ?? marker.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? marker.lineDashOffset }; } getMarkerItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { angleKey, radiusKey, marker } = properties; const { itemStyler } = marker; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId17(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, angleKey, radiusKey, highlighted, ...format }); }); } updateMarkers(selection, highlight) { const { visible } = this; const { marker } = this.properties; let selectionData = []; if (visible && marker.shape && marker.enabled) { if (highlight) { const highlighted = this.ctx.highlightManager?.getActiveHighlight(); if (highlighted?.datum) { selectionData = [highlighted]; } } else { selectionData = this.nodeData; } } const style = this.getMarkerItemBaseStyle(highlight); selection.update(selectionData).each((node, nodeDatum) => { const { datum, datumIndex, point } = nodeDatum; const overrides = this.getMarkerItemStyleOverrides(String(datumIndex), datum, style, highlight); applyShapeStyle8(node, style, overrides); node.shape = overrides?.shape ?? style.shape; node.size = overrides?.size ?? style.size; const { x, y } = point; node.x = x; node.y = y; node.visible = visible && node.size > 0 && !isNaN(x) && !isNaN(y); }); } updateLabels() { const { label } = this.properties; this.labelSelection.update(this.nodeData).each((node, datum) => { if (label.enabled && datum.label) { node.x = datum.label.x; node.y = datum.label.y; node.fill = label.color; node.fontFamily = label.fontFamily; node.fontSize = label.fontSize; node.fontStyle = label.fontStyle; node.fontWeight = label.fontWeight; node.text = datum.label.text; node.textAlign = datum.label.textAlign; node.textBaseline = datum.label.textBaseline; node.visible = true; } else { node.visible = false; } }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { angleKey, angleName, radiusKey, radiusName, tooltip } = properties; const angleAxis = axes[ChartAxisDirection26.X]; const radiusAxis = axes[ChartAxisDirection26.Y]; if (!dataModel || !processedData || !angleAxis || !radiusAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const angleValue = dataModel.resolveColumnById(this, `angleValue`, processedData)[datumIndex]; const radiusValue = dataModel.resolveColumnById(this, `radiusValue`, processedData)[datumIndex]; if (angleValue == null) return; const format = this.getMarkerItemBaseStyle(false); Object.assign(format, this.getMarkerItemStyleOverrides(String(datumIndex), datumIndex, format, false)); return tooltip.formatTooltip( { heading: angleAxis.formatDatum(angleValue), symbol: this.legendItemSymbol(), data: [{ label: radiusName, fallbackLabel: radiusKey, value: radiusAxis.formatDatum(radiusValue) }] }, { seriesId, datum, title: angleName, angleKey, radiusKey, angleName, radiusName, ...format } ); } legendItemSymbol() { const { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, marker } = this.properties; return { marker: { shape: marker.shape, fill: this.getMarkerFill() ?? marker.stroke ?? stroke22 ?? "rgba(0, 0, 0, 0)", stroke: marker.stroke ?? stroke22 ?? "rgba(0, 0, 0, 0)", fillOpacity: marker.fillOpacity, strokeOpacity: marker.strokeOpacity, strokeWidth: marker.strokeWidth, lineDash: marker.lineDash, lineDashOffset: marker.lineDashOffset, enabled: marker.enabled || strokeWidth <= 0 }, line: { stroke: stroke22, strokeOpacity, strokeWidth, lineDash } }; } getLegendData(legendType) { if (!this.properties.isValid() || legendType !== "category") { return []; } const { id: seriesId, ctx: { legendManager }, visible } = this; const { radiusKey, radiusName, showInLegend } = this.properties; return [ { legendType: "category", id: seriesId, itemId: radiusKey, seriesId, enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: radiusKey }), label: { text: radiusName ?? radiusKey }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } pickNodeClosestDatum(hitPoint) { const { nodeData, centerX: cx, centerY: cy } = this; const { x, y } = hitPoint; const radius = this.radius; const distanceFromCenter = Math.sqrt((x - cx) ** 2 + (y - cy) ** 2); if (distanceFromCenter > radius + this.properties.marker.size) { return; } let minDistance = Infinity; let closestDatum; for (const datum of nodeData) { const { point: { x: datumX = NaN, y: datumY = NaN } = {} } = datum; if (isNaN(datumX) || isNaN(datumY)) { continue; } const distance2 = Math.sqrt((hitPoint.x - datumX - cx) ** 2 + (hitPoint.y - datumY - cy) ** 2); if (distance2 < minDistance) { minDistance = distance2; closestDatum = datum; } } if (closestDatum) { const distance2 = Math.max(minDistance - (closestDatum.point?.size ?? 0), 0); return { datum: closestDatum, distance: distance2 }; } } computeLabelsBBox() { const { label } = this.properties; this.maybeRefreshNodeData(); const textBoxes = []; const tempText2 = new Text7(); this.nodeData.forEach((nodeDatum) => { if (!label.enabled || !nodeDatum.label) { return; } tempText2.text = nodeDatum.label.text; tempText2.x = nodeDatum.label.x; tempText2.y = nodeDatum.label.y; tempText2.setFont(label); tempText2.setAlign(nodeDatum.label); const box = tempText2.getBBox(); textBoxes.push(box); }); if (textBoxes.length === 0) { return null; } return BBox17.merge(textBoxes); } getLineNode() { return this.lineSelection?.at(0); } beforePathAnimation() { const lineNode = this.getLineNode(); if (!lineNode) return; lineNode.fill = void 0; lineNode.lineJoin = "round"; lineNode.lineCap = "round"; lineNode.pointerEvents = PointerEvents8.None; lineNode.stroke = this.properties.stroke; lineNode.strokeWidth = this.getStrokeWidth(this.properties.strokeWidth); lineNode.strokeOpacity = this.properties.strokeOpacity; lineNode.lineDash = this.properties.lineDash; lineNode.lineDashOffset = this.properties.lineDashOffset; } getLinePoints() { const { nodeData, resetInvalidToZero } = this; const { connectMissingData } = this.properties; if (nodeData.length === 0) { return []; } const radiusAxis = this.axes[ChartAxisDirection26.Y]; const angleAxis = this.axes[ChartAxisDirection26.X]; const reversedAngleAxis = angleAxis?.isReversed(); const reversedRadiusAxis = radiusAxis?.isReversed(); const data = reversedRadiusAxis && !reversedAngleAxis ? [...nodeData].reverse() : nodeData; const points = []; let prevPointInvalid = false; let firstValid; data.forEach((datum, index) => { let { x, y } = datum.point; const isPointInvalid = isNaN(x) || isNaN(y); if (!isPointInvalid) { firstValid ?? (firstValid = datum); } if (isPointInvalid && !connectMissingData) { x = 0; y = 0; } const moveTo = index === 0 || !resetInvalidToZero && !connectMissingData && (isPointInvalid || prevPointInvalid); points.push({ x, y, moveTo }); prevPointInvalid = isPointInvalid; }); if (firstValid !== void 0) { points.push({ x: firstValid.point.x, y: firstValid.point.y, moveTo: false }); } return points; } animateSinglePath(pathNode, points, ratio2) { const { path } = pathNode; path.clear(true); const axisInnerRadius = this.getAxisInnerRadius(); const radiusAxis = this.axes[ChartAxisDirection26.Y]; const reversedRadiusAxis = radiusAxis?.isReversed(); const radiusZero = reversedRadiusAxis ? this.radius + axisInnerRadius - radiusAxis?.scale.convert(0) : axisInnerRadius; points.forEach((point) => { const { x: x1, y: y1, arc, radius = 0, startAngle = 0, endAngle = 0, moveTo } = point; const angle2 = Math.atan2(y1, x1); const x0 = radiusZero * Math.cos(angle2); const y0 = radiusZero * Math.sin(angle2); const t = ratio2; const x = x0 * (1 - t) + x1 * t; const y = y0 * (1 - t) + y1 * t; if (arc) { path.arc(x1, y1, radius, startAngle, endAngle); } else if (moveTo) { path.moveTo(x, y); } else { path.lineTo(x, y); } }); pathNode.checkPathDirty(); } animatePaths(ratio2) { const linePoints = this.getLinePoints(); const lineNode = this.getLineNode(); if (!lineNode) return; this.animateSinglePath(lineNode, linePoints, ratio2); } animateEmptyUpdateReady() { const { itemSelection, labelSelection } = this; const { animationManager } = this.ctx; this.beforePathAnimation(); animationManager.animate({ id: `${this.id}_'path`, groupId: this.id, from: 0, to: 1, phase: "initial", collapsable: false, onUpdate: (ratio2) => this.animatePaths(ratio2), onStop: () => this.animatePaths(1) }); markerFadeInAnimation2(this, animationManager, "added", itemSelection); seriesLabelFadeInAnimation3(this, "labels", animationManager, labelSelection); } animateWaitingUpdateReady(data) { super.animateWaitingUpdateReady(data); this.resetPaths(); } animateReadyResize(data) { super.animateReadyResize(data); this.resetPaths(); } resetPaths() { const lineNode = this.getLineNode(); if (lineNode) { const { path: linePath } = lineNode; const linePoints = this.getLinePoints(); lineNode.fill = void 0; lineNode.stroke = this.properties.stroke; lineNode.strokeWidth = this.getStrokeWidth(this.properties.strokeWidth); lineNode.strokeOpacity = this.properties.strokeOpacity; lineNode.lineDash = this.properties.lineDash; lineNode.lineDashOffset = this.properties.lineDashOffset; linePath.clear(true); for (const { x, y, moveTo } of linePoints) { if (moveTo) { linePath.moveTo(x, y); } else { linePath.lineTo(x, y); } } lineNode.checkPathDirty(); } } getFormattedMarkerStyle(datum) { const { angleKey, radiusKey } = this.properties; return this.getMarkerStyle(this.properties.marker, { datum, angleKey, radiusKey, highlighted: true }); } computeFocusBounds(opts) { return computeMarkerFocusBounds22(this, opts); } }; RadarSeries.className = "RadarSeries"; var import_ag_charts_community229 = (init_main4(), __toCommonJS(main_exports)); var { RATIO: RATIO28, COLOR_STRING: COLOR_STRING23, Validate: Validate78 } = import_ag_charts_community229._ModuleSupport; var RadarAreaSeriesProperties = class extends RadarSeriesProperties { constructor() { super(...arguments); this.fill = "black"; this.fillOpacity = 1; } }; __decorateClass2([ Validate78(COLOR_STRING23) ], RadarAreaSeriesProperties.prototype, "fill", 2); __decorateClass2([ Validate78(RATIO28) ], RadarAreaSeriesProperties.prototype, "fillOpacity", 2); var { Group: Group18, Path: Path12, PointerEvents: PointerEvents9, Selection: Selection14, ChartAxisDirection: ChartAxisDirection27 } = import_ag_charts_community230._ModuleSupport; var RadarAreaSeries = class extends RadarSeries { constructor(moduleCtx) { super(moduleCtx); this.properties = new RadarAreaSeriesProperties(); this.resetInvalidToZero = true; const areaGroup = new Group18(); this.contentGroup.append(areaGroup); this.areaSelection = Selection14.select(areaGroup, Path12); } updatePathSelections() { const pathData = this.visible ? [true] : []; this.areaSelection.update(pathData); super.updatePathSelections(); } getAreaNode() { return this.areaSelection.at(0); } getMarkerFill(highlightedStyle) { return highlightedStyle?.fill ?? this.properties.marker.fill ?? this.properties.fill; } beforePathAnimation() { super.beforePathAnimation(); const areaNode = this.getAreaNode(); areaNode.fill = this.properties.fill; areaNode.fillOpacity = this.properties.fillOpacity; areaNode.pointerEvents = PointerEvents9.None; areaNode.stroke = void 0; } animatePaths(ratio2) { super.animatePaths(ratio2); this.animateSinglePath(this.getAreaNode(), this.getAreaPoints(), ratio2); } getAreaPoints() { const points = this.getLinePoints(); const getPolarAxis = (direction) => { const axis = this.axes[direction]; return axis instanceof import_ag_charts_community230._ModuleSupport.PolarAxis ? axis : void 0; }; const radiusAxis = getPolarAxis(ChartAxisDirection27.Y); const angleAxis = getPolarAxis(ChartAxisDirection27.X); const reversedRadiusAxis = radiusAxis?.isReversed(); if (!reversedRadiusAxis) { return points; } const zeroLinePoints = angleAxis?.getAxisLinePoints()?.points ?? []; return points.concat(...zeroLinePoints); } resetPaths() { super.resetPaths(); const areaNode = this.getAreaNode(); if (areaNode) { const { path: areaPath } = areaNode; const areaPoints = this.getAreaPoints(); areaNode.fill = this.properties.fill; areaNode.fillOpacity = this.properties.fillOpacity; areaNode.stroke = void 0; areaNode.lineDash = this.properties.lineDash; areaNode.lineDashOffset = this.properties.lineDashOffset; areaNode.lineJoin = areaNode.lineCap = "round"; areaPath.clear(true); areaPoints.forEach(({ x, y, moveTo, arc, radius = 0, startAngle = 0, endAngle = 0 }) => { if (arc) { areaPath.arc(x, y, radius, startAngle, endAngle); } else if (moveTo) { areaPath.moveTo(x, y); } else { areaPath.lineTo(x, y); } }); areaPath.closePath(); areaNode.checkPathDirty(); } } }; RadarAreaSeries.className = "RadarAreaSeries"; RadarAreaSeries.type = "radar-area"; var { markerPaletteFactory: markerPaletteFactory2, ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE4 } } = import_ag_charts_community231._ModuleSupport; var RadarAreaModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radar-area", moduleFactory: (ctx) => new RadarAreaSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [{ type: POLAR_AXIS_TYPE4.ANGLE_CATEGORY }, { type: POLAR_AXIS_TYPE4.RADIUS_NUMBER }], themeTemplate: RADAR_AREA_SERIES_THEME, paletteFactory: (params) => { const { marker } = markerPaletteFactory2(params); return { stroke: marker.stroke, fill: marker.fill, marker }; } }; var import_ag_charts_community232 = (init_main4(), __toCommonJS(main_exports)); var RadarLineSeries = class extends RadarSeries { updatePathSelections() { this.lineSelection.update(this.visible ? [true] : []); } }; RadarLineSeries.className = "RadarLineSeries"; RadarLineSeries.type = "radar-line"; var { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE5 } = import_ag_charts_community232._ModuleSupport.ThemeConstants; var RadarLineModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radar-line", moduleFactory: (ctx) => new RadarLineSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [{ type: POLAR_AXIS_TYPE5.ANGLE_CATEGORY }, { type: POLAR_AXIS_TYPE5.RADIUS_NUMBER }], themeTemplate: RADAR_LINE_SERIES_THEME, paletteFactory: ({ takeColors }) => { const { fills: [fill], strokes: [stroke22] } = takeColors(1); return { stroke: fill, marker: { fill, stroke: stroke22 } }; } }; var import_ag_charts_community237 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community235 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community233 = (init_main4(), __toCommonJS(main_exports)); var { SeriesProperties: SeriesProperties11, SeriesTooltip: SeriesTooltip17, Validate: Validate79, COLOR_STRING: COLOR_STRING24, NUMBER: NUMBER20, FUNCTION: FUNCTION18, LINE_DASH: LINE_DASH20, OBJECT: OBJECT40, POSITIVE_NUMBER: POSITIVE_NUMBER32, RATIO: RATIO29, STRING: STRING37, Label: Label12 } = import_ag_charts_community233._ModuleSupport; var RadialBarSeriesProperties = class extends SeriesProperties11 { constructor() { super(...arguments); this.fill = "black"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.rotation = 0; this.label = new Label12(); this.tooltip = new SeriesTooltip17(); } }; __decorateClass2([ Validate79(STRING37) ], RadialBarSeriesProperties.prototype, "angleKey", 2); __decorateClass2([ Validate79(STRING37) ], RadialBarSeriesProperties.prototype, "radiusKey", 2); __decorateClass2([ Validate79(STRING37, { optional: true }) ], RadialBarSeriesProperties.prototype, "angleName", 2); __decorateClass2([ Validate79(STRING37, { optional: true }) ], RadialBarSeriesProperties.prototype, "radiusName", 2); __decorateClass2([ Validate79(COLOR_STRING24) ], RadialBarSeriesProperties.prototype, "fill", 2); __decorateClass2([ Validate79(RATIO29) ], RadialBarSeriesProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate79(COLOR_STRING24) ], RadialBarSeriesProperties.prototype, "stroke", 2); __decorateClass2([ Validate79(POSITIVE_NUMBER32) ], RadialBarSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate79(RATIO29) ], RadialBarSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate79(LINE_DASH20) ], RadialBarSeriesProperties.prototype, "lineDash", 2); __decorateClass2([ Validate79(POSITIVE_NUMBER32) ], RadialBarSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate79(POSITIVE_NUMBER32) ], RadialBarSeriesProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate79(FUNCTION18, { optional: true }) ], RadialBarSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate79(NUMBER20) ], RadialBarSeriesProperties.prototype, "rotation", 2); __decorateClass2([ Validate79(STRING37, { optional: true }) ], RadialBarSeriesProperties.prototype, "stackGroup", 2); __decorateClass2([ Validate79(NUMBER20, { optional: true }) ], RadialBarSeriesProperties.prototype, "normalizedTo", 2); __decorateClass2([ Validate79(OBJECT40) ], RadialBarSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate79(OBJECT40) ], RadialBarSeriesProperties.prototype, "tooltip", 2); var import_ag_charts_community234 = (init_main4(), __toCommonJS(main_exports)); var { SectorBox: SectorBox3, motion: motion7 } = import_ag_charts_community234._ModuleSupport; function fixRadialBarAnimationStatus(node, datum, status) { if (status === "updated") { if (node.previousDatum == null || isNaN(node.previousDatum.innerRadius) || isNaN(node.previousDatum.outerRadius)) { return "added"; } if (isNaN(datum.innerRadius) || isNaN(datum.outerRadius)) { return "removed"; } } if (status === "added" && node.previousDatum != null) { return "updated"; } return status; } function prepareRadialBarSeriesAnimationFunctions(axisZeroAngle) { const fromFn = (sect, datum, status) => { status = fixRadialBarAnimationStatus(sect, datum, status); let startAngle; let endAngle; let innerRadius; let outerRadius; let clipSector; if (status === "removed" || status === "updated") { startAngle = sect.startAngle; endAngle = sect.endAngle; innerRadius = sect.innerRadius; outerRadius = sect.outerRadius; clipSector = sect.clipSector; } else { startAngle = axisZeroAngle; endAngle = axisZeroAngle; innerRadius = datum.innerRadius; outerRadius = datum.outerRadius; } clipSector ?? (clipSector = new SectorBox3(startAngle, endAngle, innerRadius, outerRadius)); const phase = motion7.NODE_UPDATE_STATE_TO_PHASE_MAPPING[status]; return { startAngle, endAngle, innerRadius, outerRadius, clipSector, phase }; }; const toFn = (sect, datum, status) => { let startAngle; let endAngle; let innerRadius; let outerRadius; let clipSector; if (status === "removed") { startAngle = axisZeroAngle; endAngle = axisZeroAngle; innerRadius = datum.innerRadius; outerRadius = datum.outerRadius; clipSector = new SectorBox3(startAngle, endAngle, innerRadius, outerRadius); } else { startAngle = datum.startAngle; endAngle = datum.endAngle; innerRadius = isNaN(datum.innerRadius) ? sect.innerRadius : datum.innerRadius; outerRadius = isNaN(datum.outerRadius) ? sect.outerRadius : datum.outerRadius; clipSector = datum.clipSector; } return { startAngle, endAngle, innerRadius, outerRadius, clipSector }; }; return { toFn, fromFn }; } function resetRadialBarSelectionsFn(_node, datum) { return { centerX: 0, centerY: 0, innerRadius: datum.innerRadius, outerRadius: datum.outerRadius, startAngle: datum.startAngle, endAngle: datum.endAngle, clipSector: datum.clipSector }; } var { ChartAxisDirection: ChartAxisDirection28, PolarAxis: PolarAxis4, diff: diff5, groupAccumulativeValueProperty: groupAccumulativeValueProperty3, keyProperty: keyProperty7, normaliseGroupTo: normaliseGroupTo22, valueProperty: valueProperty15, fixNumericExtent: fixNumericExtent7, resetLabelFn: resetLabelFn3, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation4, seriesLabelFadeOutAnimation: seriesLabelFadeOutAnimation22, animationValidation: animationValidation6, angleBetween: angleBetween3, createDatumId: createDatumId18, CategoryScale: CategoryScale4, Sector: Sector5, SectorBox: SectorBox4, motion: motion8, applyShapeStyle: applyShapeStyle9 } = import_ag_charts_community235._ModuleSupport; var RadialBarSeriesNodeEvent = class extends import_ag_charts_community235._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.angleKey = series.properties.angleKey; this.radiusKey = series.properties.radiusKey; } }; var RadialBarSeries = class extends import_ag_charts_community235._ModuleSupport.PolarSeries { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, canHaveAxes: true, animationResetFns: { item: resetRadialBarSelectionsFn, label: resetLabelFn3 } }); this.properties = new RadialBarSeriesProperties(); this.NodeEvent = RadialBarSeriesNodeEvent; this.groupScale = new CategoryScale4(); this.circleCache = { r: 0, cx: 0, cy: 0 }; } nodeFactory() { return new Sector5(); } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!processedData || !dataModel) return []; if (direction === ChartAxisDirection28.X) { const xExtent = dataModel.getDomain(this, "angleValue-end", "value", processedData); const fixedXExtent = [xExtent[0] > 0 ? 0 : xExtent[0], xExtent[1] < 0 ? 0 : xExtent[1]]; return fixNumericExtent7(fixedXExtent); } else { return dataModel.getDomain(this, "radiusValue", "key", processedData); } } async processData(dataController) { const { visible } = this; const { angleKey, radiusKey, normalizedTo } = this.properties; const animationEnabled = !this.ctx.animationManager.isSkipped(); if (!this.properties.isValid()) return; const stackGroupId = this.getStackId(); const stackGroupTrailingId = `${stackGroupId}-trailing`; const extraProps = []; if (isDefined2(normalizedTo)) { extraProps.push(normaliseGroupTo22([stackGroupId, stackGroupTrailingId], Math.abs(normalizedTo))); } if (animationEnabled) { if (this.processedData) { extraProps.push(diff5(this.id, this.processedData)); } extraProps.push(animationValidation6()); } const visibleProps = visible || !animationEnabled ? {} : { forceValue: 0 }; const radiusScaleType = this.axes[ChartAxisDirection28.Y]?.scale.type; const angleScaleType = this.axes[ChartAxisDirection28.X]?.scale.type; await this.requestDataModel(dataController, this.data, { props: [ keyProperty7(radiusKey, radiusScaleType, { id: "radiusValue" }), valueProperty15(angleKey, angleScaleType, { id: "angleValue-raw", invalidValue: null, ...visibleProps }), ...groupAccumulativeValueProperty3( angleKey, "normal", "current", { id: `angleValue-end`, rangeId: `angleValue-range`, invalidValue: null, groupId: stackGroupId, separateNegative: true, ...visibleProps }, angleScaleType ), ...groupAccumulativeValueProperty3( angleKey, "trailing", "current", { id: `angleValue-start`, invalidValue: null, groupId: stackGroupTrailingId, separateNegative: true, ...visibleProps }, angleScaleType ), ...extraProps ], groupByKeys: true, groupByData: false }); this.animationState.transition("updateData"); } didCircleChange() { const r = this.radius; const cx = this.centerX; const cy = this.centerY; const cache = this.circleCache; if (!(r === cache.r && cx === cache.cx && cy === cache.cy)) { this.circleCache = { r, cx, cy }; return true; } return false; } maybeRefreshNodeData() { const circleChanged = this.didCircleChange(); if (!circleChanged && !this.nodeDataRefresh) return; const { nodeData = [] } = this.createNodeData() ?? {}; this.nodeData = nodeData; this.nodeDataRefresh = false; } getAxisInnerRadius() { const radiusAxis = this.axes[ChartAxisDirection28.Y]; return radiusAxis instanceof PolarAxis4 ? this.radius * radiusAxis.innerRadiusRatio : 0; } createNodeData() { const { processedData, dataModel } = this; if (!dataModel || !processedData || processedData.type !== "grouped" || !this.properties.isValid()) { return; } const angleAxis = this.axes[ChartAxisDirection28.X]; const radiusAxis = this.axes[ChartAxisDirection28.Y]; const angleScale = angleAxis?.scale; const radiusScale = radiusAxis?.scale; if (!angleScale || !radiusScale) { return; } const radiusValues = dataModel.resolveKeysById(this, "radiusValue", processedData); const angleStartValues = dataModel.resolveColumnById(this, `angleValue-start`, processedData); const angleEndValues = dataModel.resolveColumnById(this, `angleValue-end`, processedData); const angleRawValues = dataModel.resolveColumnById(this, `angleValue-raw`, processedData); const angleRangeIndex = dataModel.resolveProcessedDataIndexById(this, `angleValue-range`); let groupPaddingInner = 0; if (radiusAxis instanceof RadiusCategoryAxis) { groupPaddingInner = radiusAxis.groupPaddingInner; } const { groupScale } = this; const { index: groupIndex, visibleGroupCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this); groupScale.domain = Array.from({ length: visibleGroupCount }).map((_, i) => String(i)); groupScale.range = [0, Math.abs(radiusScale.bandwidth ?? 0)]; groupScale.paddingInner = visibleGroupCount > 1 ? groupPaddingInner : 0; const barWidth = groupScale.bandwidth >= 1 ? groupScale.bandwidth : groupScale.rawBandwidth; const angleAxisReversed = angleAxis.isReversed(); const radiusAxisReversed = radiusAxis.isReversed(); const axisInnerRadius = radiusAxisReversed ? this.radius : this.getAxisInnerRadius(); const axisOuterRadius = radiusAxisReversed ? this.getAxisInnerRadius() : this.radius; const axisTotalRadius = axisOuterRadius + axisInnerRadius; const { angleKey, radiusKey, angleName, radiusName, label } = this.properties; const getLabelNodeDatum = (datum, angleDatum, x, y) => { const labelText = this.getLabelText(label, { value: angleDatum, datum, angleKey, radiusKey, angleName, radiusName }); if (labelText) { return { x, y, text: labelText, textAlign: "center", textBaseline: "middle" }; } }; const nodeData = []; const context = { itemId: radiusKey, nodeData, labelData: nodeData }; if (!this.visible) return context; const { dataSources } = processedData; const rawData = dataSources.get(this.id) ?? []; for (const { datumIndex, group } of dataModel.forEachGroupDatum(this, processedData)) { const datum = rawData[datumIndex]; const radiusDatum = radiusValues[datumIndex]; if (radiusDatum == null) return; const angleDatum = angleRawValues[datumIndex]; const angleStartDatum = angleStartValues[datumIndex]; const angleEndDatum = angleEndValues[datumIndex]; const isPositive = angleDatum >= 0 && !Object.is(angleDatum, -0); const angleRange = group.aggregation[angleRangeIndex][isPositive ? 1 : 0]; const reversed = isPositive === angleAxisReversed; let startAngle = angleScale.convert(angleStartDatum, true); let endAngle = angleScale.convert(angleEndDatum, true); let rangeStartAngle = angleScale.convert(0, true); let rangeEndAngle = angleScale.convert(angleRange, true); if (reversed) { [rangeStartAngle, rangeEndAngle] = [rangeEndAngle, rangeStartAngle]; [startAngle, endAngle] = [endAngle, startAngle]; } const dataRadius = axisTotalRadius - radiusScale.convert(radiusDatum); const innerRadius = dataRadius + groupScale.convert(String(groupIndex)); const outerRadius = innerRadius + barWidth; const midRadius = (innerRadius + outerRadius) / 2; const midAngle = startAngle + angleBetween3(startAngle, endAngle) / 2; const x = Math.cos(midAngle) * midRadius; const y = Math.sin(midAngle) * midRadius; const labelNodeDatum = this.properties.label.enabled ? getLabelNodeDatum(datum, angleDatum, x, y) : void 0; const clipSector = new SectorBox4(startAngle, endAngle, innerRadius, outerRadius); nodeData.push({ series: this, datum, datumIndex, point: { x, y, size: 0 }, midPoint: { x, y }, label: labelNodeDatum, angleValue: angleDatum, radiusValue: radiusDatum, innerRadius, outerRadius, startAngle: rangeStartAngle, endAngle: rangeEndAngle, clipSector, reversed, index: datumIndex }); } return context; } update({ seriesRect }) { const resize = this.checkResize(seriesRect); this.maybeRefreshNodeData(); this.contentGroup.translationX = this.centerX; this.contentGroup.translationY = this.centerY; this.highlightGroup.translationX = this.centerX; this.highlightGroup.translationY = this.centerY; if (this.labelGroup) { this.labelGroup.translationX = this.centerX; this.labelGroup.translationY = this.centerY; } this.updateSectorSelection(this.itemSelection, false); this.updateSectorSelection(this.highlightSelection, true); this.updateLabels(); if (resize) { this.animationState.transition("resize"); } this.animationState.transition("update"); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset, cornerRadius: properties.cornerRadius }; } getItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { angleKey, radiusKey, itemStyler } = properties; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId18(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, highlighted, angleKey, radiusKey, ...format }); }); } updateSectorSelection(selection, highlighted) { let selectionData = []; if (highlighted) { const activeHighlight = this.ctx.highlightManager?.getActiveHighlight(); if (activeHighlight?.datum && activeHighlight.series === this) { selectionData.push(activeHighlight); } } else { selectionData = this.nodeData; } const style = this.getItemBaseStyle(highlighted); selection.update(selectionData, void 0, (datum) => this.getDatumId(datum)).each((node, nodeDatum) => { const { datum, datumIndex } = nodeDatum; const overrides = this.getItemStyleOverrides(String(datumIndex), datum, style, highlighted); const cornerRadius = overrides?.cornerRadius ?? style.cornerRadius; applyShapeStyle9(node, style, overrides); node.lineJoin = "round"; node.inset = node.stroke != null ? node.strokeWidth / 2 : 0; node.startInnerCornerRadius = datum.reversed ? cornerRadius : 0; node.startOuterCornerRadius = datum.reversed ? cornerRadius : 0; node.endInnerCornerRadius = datum.reversed ? 0 : cornerRadius; node.endOuterCornerRadius = datum.reversed ? 0 : cornerRadius; if (highlighted) { node.startAngle = nodeDatum.startAngle; node.endAngle = nodeDatum.endAngle; node.clipSector = nodeDatum.clipSector; node.innerRadius = nodeDatum.innerRadius; node.outerRadius = nodeDatum.outerRadius; } }); } updateLabels() { const { label } = this.properties; this.labelSelection.update(this.nodeData).each((node, datum) => { if (label.enabled && datum.label) { node.x = datum.label.x; node.y = datum.label.y; node.fill = label.color; node.fontFamily = label.fontFamily; node.fontSize = label.fontSize; node.fontStyle = label.fontStyle; node.fontWeight = label.fontWeight; node.text = datum.label.text; node.textAlign = datum.label.textAlign; node.textBaseline = datum.label.textBaseline; node.visible = true; } else { node.visible = false; } }); } getBarTransitionFunctions() { const angleScale = this.axes[ChartAxisDirection28.X]?.scale; let axisZeroAngle = 0; if (!angleScale) { return prepareRadialBarSeriesAnimationFunctions(axisZeroAngle); } const d0 = Math.min(angleScale.domain[0], angleScale.domain[1]); const d1 = Math.max(angleScale.domain[0], angleScale.domain[1]); if (d0 <= 0 && d1 >= 0) { axisZeroAngle = angleScale.convert(0); } return prepareRadialBarSeriesAnimationFunctions(axisZeroAngle); } animateEmptyUpdateReady() { const { labelSelection } = this; const fns = this.getBarTransitionFunctions(); motion8.fromToMotion(this.id, "datums", this.ctx.animationManager, [this.itemSelection], fns); seriesLabelFadeInAnimation4(this, "labels", this.ctx.animationManager, labelSelection); } animateClearingUpdateEmpty() { const { itemSelection } = this; const { animationManager } = this.ctx; const fns = this.getBarTransitionFunctions(); motion8.fromToMotion(this.id, "datums", animationManager, [itemSelection], fns); seriesLabelFadeOutAnimation22(this, "labels", animationManager, this.labelSelection); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { angleKey, angleName, radiusKey, radiusName, tooltip } = properties; const angleAxis = axes[ChartAxisDirection28.X]; const radiusAxis = axes[ChartAxisDirection28.Y]; if (!dataModel || !processedData || !angleAxis || !radiusAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const radiusValue = dataModel.resolveKeysById(this, `radiusValue`, processedData)[datumIndex]; const angleValue = dataModel.resolveColumnById(this, `angleValue-raw`, processedData)[datumIndex]; if (radiusValue == null) return; const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datumIndex, format, false)); return tooltip.formatTooltip( { heading: radiusAxis.formatDatum(radiusValue), symbol: this.legendItemSymbol(), data: [{ label: angleName, fallbackLabel: angleKey, value: angleAxis.formatDatum(angleValue) }] }, { seriesId, datum, title: angleName, angleKey, angleName, radiusKey, radiusName, ...format } ); } pickNodeClosestDatum(point) { return this.pickNodeNearestDistantObject(point, this.itemSelection.nodes()); } legendItemSymbol() { const { fill, stroke: stroke22, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties; return { marker: { fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke22 ?? "rgba(0, 0, 0, 0)", fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (!this.properties.isValid() || legendType !== "category") { return []; } const { id: seriesId, visible } = this; const { angleKey, angleName, showInLegend } = this.properties; return [ { legendType: "category", id: seriesId, itemId: angleKey, seriesId, enabled: visible, label: { text: angleName ?? angleKey }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } getDatumId(datum) { return createDatumId18(datum.radiusValue); } computeLabelsBBox() { return null; } getStackId() { const groupIndex = this.seriesGrouping?.groupIndex ?? this.id; return `radialBar-stack-${groupIndex}-xValues`; } }; RadialBarSeries.className = "RadialBarSeries"; RadialBarSeries.type = "radial-bar"; var import_ag_charts_community236 = (init_main4(), __toCommonJS(main_exports)); var { ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE6 } } = import_ag_charts_community236._ModuleSupport; var RADIAL_BAR_SERIES_THEME = { series: { strokeWidth: 0, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" } } }, axes: { [POLAR_AXIS_TYPE6.RADIUS_CATEGORY]: { innerRadiusRatio: 0.2, groupPaddingInner: 0.2, paddingInner: 0.2, paddingOuter: 0.1 } } }; var { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE7 } = import_ag_charts_community237._ModuleSupport.ThemeConstants; var RadialBarModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radial-bar", moduleFactory: (ctx) => new RadialBarSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: [{ type: POLAR_AXIS_TYPE7.ANGLE_NUMBER }, { type: POLAR_AXIS_TYPE7.RADIUS_CATEGORY }], themeTemplate: RADIAL_BAR_SERIES_THEME, paletteFactory: ({ takeColors }) => { const { fills: [fill], strokes: [stroke22] } = takeColors(1); return { fill, stroke: stroke22 }; }, stackable: true, groupable: true }; var import_ag_charts_community241 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community239 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community238 = (init_main4(), __toCommonJS(main_exports)); var { Validate: Validate80, RATIO: RATIO30 } = import_ag_charts_community238._ModuleSupport; var RadialColumnSeriesProperties = class extends RadialColumnSeriesBaseProperties { }; __decorateClass2([ Validate80(RATIO30, { optional: true }) ], RadialColumnSeriesProperties.prototype, "columnWidthRatio", 2); __decorateClass2([ Validate80(RATIO30, { optional: true }) ], RadialColumnSeriesProperties.prototype, "maxColumnWidthRatio", 2); var { ChartAxisDirection: ChartAxisDirection29, PolarAxis: PolarAxis5, RadialColumnShape: RadialColumnShape2, getRadialColumnWidth: getRadialColumnWidth2 } = import_ag_charts_community239._ModuleSupport; var RadialColumnSeries = class extends RadialColumnSeriesBase { constructor(moduleCtx) { super(moduleCtx, { animationResetFns: { item: resetRadialColumnSelectionFn } }); this.properties = new RadialColumnSeriesProperties(); } getStackId() { const groupIndex = this.seriesGrouping?.groupIndex ?? this.id; return `radarColumn-stack-${groupIndex}-yValues`; } nodeFactory() { return new RadialColumnShape2(); } getColumnTransitionFunctions() { const axisZeroRadius = this.isRadiusAxisReversed() ? this.radius : this.getAxisInnerRadius(); return prepareRadialColumnAnimationFunctions(axisZeroRadius); } isRadiusAxisCircle() { const radiusAxis = this.axes[ChartAxisDirection29.Y]; return radiusAxis instanceof PolarAxis5 ? radiusAxis.shape === "circle" : false; } updateItemPath(node, datum, highlight) { node.isBeveled = this.isRadiusAxisCircle(); node.isRadiusAxisReversed = this.isRadiusAxisReversed(); if (highlight) { node.innerRadius = datum.innerRadius; node.outerRadius = datum.outerRadius; node.startAngle = datum.startAngle; node.endAngle = datum.endAngle; node.columnWidth = datum.columnWidth; node.axisInnerRadius = datum.axisInnerRadius; node.axisOuterRadius = datum.axisOuterRadius; } } getColumnWidth(startAngle, endAngle) { const { columnWidthRatio = 0.5, maxColumnWidthRatio = 0.5 } = this.properties; return getRadialColumnWidth2(startAngle, endAngle, this.radius, columnWidthRatio, maxColumnWidthRatio); } }; RadialColumnSeries.className = "RadialColumnSeries"; RadialColumnSeries.type = "radial-column"; var import_ag_charts_community240 = (init_main4(), __toCommonJS(main_exports)); var { ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE8, POLAR_AXIS_SHAPE: POLAR_AXIS_SHAPE22 } } = import_ag_charts_community240._ModuleSupport; var RADIAL_COLUMN_SERIES_THEME = { series: { columnWidthRatio: 0.5, maxColumnWidthRatio: 0.5, strokeWidth: 0, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } } }, axes: { [POLAR_AXIS_TYPE8.ANGLE_CATEGORY]: { shape: POLAR_AXIS_SHAPE22.CIRCLE, groupPaddingInner: 0, paddingInner: 0, label: { spacing: 10 } }, [POLAR_AXIS_TYPE8.RADIUS_NUMBER]: { shape: POLAR_AXIS_SHAPE22.CIRCLE, innerRadiusRatio: 0.5 } } }; var { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE9 } = import_ag_charts_community241._ModuleSupport.ThemeConstants; var RadialColumnModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radial-column", moduleFactory: (ctx) => new RadialColumnSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: [{ type: POLAR_AXIS_TYPE9.ANGLE_CATEGORY }, { type: POLAR_AXIS_TYPE9.RADIUS_NUMBER }], themeTemplate: RADIAL_COLUMN_SERIES_THEME, paletteFactory: ({ takeColors }) => { const { fills: [fill], strokes: [stroke22] } = takeColors(1); return { fill, stroke: stroke22 }; }, stackable: true, groupable: true }; var import_ag_charts_community246 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community245 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community242 = (init_main4(), __toCommonJS(main_exports)); var { SvgPath: SvgPath2, Rotatable: Rotatable2, Translatable: Translatable2, Scalable: Scalable2 } = import_ag_charts_community242._ModuleSupport; var RadialGaugeNeedle = class extends Rotatable2(Scalable2(Translatable2(SvgPath2))) { constructor() { super(...arguments); this.scalingCenterX = 0.5; this.scalingCenterY = 0.5; this.rotationCenterX = 0.5; this.rotationCenterY = 0.5; } }; RadialGaugeNeedle.defaultPathData = "M0.50245 0.53745C0.481767 0.53745 0.465 0.520683 0.465 0.5C0.465 0.479317 0.481767 0.46255 0.50245 0.46255L1 0.500012L0.50245 0.53745Z"; var import_ag_charts_community243 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties26, SeriesTooltip: SeriesTooltip18, SeriesProperties: SeriesProperties12, PropertiesArray: PropertiesArray7, Validate: Validate81, BOOLEAN: BOOLEAN32, COLOR_STRING: COLOR_STRING25, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY11, FUNCTION: FUNCTION19, LINE_DASH: LINE_DASH21, NUMBER: NUMBER21, OBJECT_ARRAY: OBJECT_ARRAY22, OBJECT: OBJECT41, POSITIVE_NUMBER: POSITIVE_NUMBER33, RATIO: RATIO31, STRING: STRING38, UNION: UNION16, Label: Label13 } = import_ag_charts_community243._ModuleSupport; var TARGET_PLACEMENT2 = UNION16(["inside", "outside", "middle"], "a placement"); var RadialGaugeDefaultTargetLabelProperties = class extends Label13 { }; __decorateClass2([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeDefaultTargetLabelProperties.prototype, "spacing", 2); var RadialGaugeTargetProperties = class extends BaseProperties26 { constructor() { super(...arguments); this.label = new RadialGaugeDefaultTargetLabelProperties(); } }; __decorateClass2([ Validate81(STRING38, { optional: true }) ], RadialGaugeTargetProperties.prototype, "text", 2); __decorateClass2([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "value", 2); __decorateClass2([ Validate81(TARGET_MARKER_SHAPE, { optional: true }) ], RadialGaugeTargetProperties.prototype, "shape", 2); __decorateClass2([ Validate81(TARGET_PLACEMENT2, { optional: true }) ], RadialGaugeTargetProperties.prototype, "placement", 2); __decorateClass2([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "spacing", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeTargetProperties.prototype, "size", 2); __decorateClass2([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "rotation", 2); __decorateClass2([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeTargetProperties.prototype, "fill", 2); __decorateClass2([ Validate81(RATIO31, { optional: true }) ], RadialGaugeTargetProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeTargetProperties.prototype, "stroke", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeTargetProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate81(RATIO31, { optional: true }) ], RadialGaugeTargetProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate81(LINE_DASH21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "lineDash", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeTargetProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeTargetProperties.prototype, "label", 2); var RadialGaugeBarProperties = class extends BaseProperties26 { constructor() { super(...arguments); this.enabled = true; this.fills = new PropertiesArray7(import_ag_charts_community243._ModuleSupport.StopProperties); this.fillMode = "continuous"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 0; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate81(BOOLEAN32) ], RadialGaugeBarProperties.prototype, "enabled", 2); __decorateClass2([ Validate81(OBJECT_ARRAY22) ], RadialGaugeBarProperties.prototype, "fills", 2); __decorateClass2([ Validate81(FILL_MODE) ], RadialGaugeBarProperties.prototype, "fillMode", 2); __decorateClass2([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeBarProperties.prototype, "fill", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeBarProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeBarProperties.prototype, "stroke", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeBarProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeBarProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate81(LINE_DASH21) ], RadialGaugeBarProperties.prototype, "lineDash", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeBarProperties.prototype, "lineDashOffset", 2); var RadialGaugeScaleProperties = class extends BaseProperties26 { constructor() { super(...arguments); this.fills = new PropertiesArray7(import_ag_charts_community243._ModuleSupport.StopProperties); this.fillMode = "continuous"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 0; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.defaultFill = "black"; } }; __decorateClass2([ Validate81(OBJECT_ARRAY22) ], RadialGaugeScaleProperties.prototype, "fills", 2); __decorateClass2([ Validate81(FILL_MODE) ], RadialGaugeScaleProperties.prototype, "fillMode", 2); __decorateClass2([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeScaleProperties.prototype, "fill", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeScaleProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate81(COLOR_STRING25) ], RadialGaugeScaleProperties.prototype, "stroke", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeScaleProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeScaleProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate81(LINE_DASH21) ], RadialGaugeScaleProperties.prototype, "lineDash", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeScaleProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate81(COLOR_STRING25) ], RadialGaugeScaleProperties.prototype, "defaultFill", 2); var RadialGaugeNeedleProperties = class extends BaseProperties26 { constructor() { super(...arguments); this.enabled = true; this.spacing = 0; this.fill = "black"; this.fillOpacity = 1; this.stroke = "black"; this.strokeWidth = 0; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate81(BOOLEAN32) ], RadialGaugeNeedleProperties.prototype, "enabled", 2); __decorateClass2([ Validate81(RATIO31, { optional: true }) ], RadialGaugeNeedleProperties.prototype, "radiusRatio", 2); __decorateClass2([ Validate81(NUMBER21) ], RadialGaugeNeedleProperties.prototype, "spacing", 2); __decorateClass2([ Validate81(COLOR_STRING25) ], RadialGaugeNeedleProperties.prototype, "fill", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeNeedleProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate81(COLOR_STRING25) ], RadialGaugeNeedleProperties.prototype, "stroke", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeNeedleProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeNeedleProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate81(LINE_DASH21) ], RadialGaugeNeedleProperties.prototype, "lineDash", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeNeedleProperties.prototype, "lineDashOffset", 2); var RadialGaugeLabelProperties = class extends AutoSizedLabel { }; __decorateClass2([ Validate81(STRING38, { optional: true }) ], RadialGaugeLabelProperties.prototype, "text", 2); var RadialGaugeSecondaryLabelProperties = class extends AutoSizedSecondaryLabel { }; __decorateClass2([ Validate81(STRING38, { optional: true }) ], RadialGaugeSecondaryLabelProperties.prototype, "text", 2); var RadialGaugeSeriesProperties = class extends SeriesProperties12 { constructor() { super(...arguments); this.segmentation = new GaugeSegmentationProperties(); this.defaultColorRange = []; this.targets = new PropertiesArray7(RadialGaugeTargetProperties); this.defaultTarget = new RadialGaugeTargetProperties(); this.outerRadiusRatio = 1; this.innerRadiusRatio = 1; this.cornerRadius = 0; this.cornerMode = "container"; this.spacing = 0; this.scale = new RadialGaugeScaleProperties(); this.bar = new RadialGaugeBarProperties(); this.needle = new RadialGaugeNeedleProperties(); this.label = new RadialGaugeLabelProperties(); this.secondaryLabel = new RadialGaugeSecondaryLabelProperties(); this.tooltip = new SeriesTooltip18(); } isValid(warningPrefix) { if (!super.isValid(warningPrefix)) return false; const { outerRadius, innerRadius } = this; if (outerRadius == null !== (innerRadius == null)) { logger_exports2.warnOnce("Either [innerRadius] and [outerRadius] must both be set, or neither can be set."); return false; } return true; } }; __decorateClass2([ Validate81(NUMBER21) ], RadialGaugeSeriesProperties.prototype, "value", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "segmentation", 2); __decorateClass2([ Validate81(COLOR_STRING_ARRAY11) ], RadialGaugeSeriesProperties.prototype, "defaultColorRange", 2); __decorateClass2([ Validate81(OBJECT_ARRAY22) ], RadialGaugeSeriesProperties.prototype, "targets", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "defaultTarget", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeSeriesProperties.prototype, "outerRadiusRatio", 2); __decorateClass2([ Validate81(RATIO31) ], RadialGaugeSeriesProperties.prototype, "innerRadiusRatio", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeSeriesProperties.prototype, "outerRadius", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeSeriesProperties.prototype, "innerRadius", 2); __decorateClass2([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeSeriesProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate81(CORNER_MODE) ], RadialGaugeSeriesProperties.prototype, "cornerMode", 2); __decorateClass2([ Validate81(NUMBER21) ], RadialGaugeSeriesProperties.prototype, "spacing", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "scale", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "bar", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "needle", 2); __decorateClass2([ Validate81(FUNCTION19, { optional: true }) ], RadialGaugeSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "secondaryLabel", 2); __decorateClass2([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "tooltip", 2); var import_ag_charts_community244 = (init_main4(), __toCommonJS(main_exports)); var { SectorBox: SectorBox5 } = import_ag_charts_community244._ModuleSupport; function computeClipSector(datum) { const { startAngle, endAngle, clipStartAngle, clipEndAngle, innerRadius, outerRadius } = datum; if (clipStartAngle == null || clipEndAngle == null) return; return new SectorBox5( Math.max(clipStartAngle, startAngle), Math.min(clipEndAngle, endAngle), innerRadius, outerRadius ); } function clipSectorVisibility(startAngle, endAngle, clipSector) { return Math.max(startAngle, clipSector.startAngle) <= Math.min(endAngle, clipSector.endAngle); } function hasClipSector(datum) { return datum.clipStartAngle != null && datum.clipEndAngle != null; } function datumClipSector(datum, zero) { const { clipStartAngle, clipEndAngle, innerRadius, outerRadius } = datum; return new SectorBox5(clipStartAngle, zero ? clipStartAngle : clipEndAngle, innerRadius, outerRadius); } function prepareRadialGaugeSeriesAnimationFunctions(initialLoad, initialStartAngle) { const phase = initialLoad ? "initial" : "update"; const node = { fromFn(sect, datum) { const previousDatum = sect.previousDatum; let { startAngle, endAngle } = previousDatum ?? datum; const previousClipSector = previousDatum != null && hasClipSector(previousDatum) ? datumClipSector(previousDatum, initialLoad) : void 0; const nextClipSector = hasClipSector(datum) ? datumClipSector(datum, initialLoad) : void 0; let clipSector; if (previousClipSector != null && nextClipSector != null) { clipSector = previousClipSector; } else if (previousClipSector == null && nextClipSector != null) { clipSector = nextClipSector; startAngle = datum.startAngle; endAngle = datum.endAngle; } else if (previousClipSector != null && nextClipSector == null) { clipSector = void 0; startAngle = datum.startAngle; endAngle = datum.endAngle; } else if (initialLoad) { endAngle = startAngle; } return { startAngle, endAngle, clipSector, phase }; }, toFn(_sect, datum) { const { startAngle, endAngle } = datum; let clipSector; if (hasClipSector(datum)) { clipSector = datumClipSector(datum, false); } return { startAngle, endAngle, clipSector }; }, applyFn(sect, params) { const { startAngle, endAngle } = params; let { clipSector } = params; if (clipSector != null) { clipSector = new SectorBox5( Math.max(startAngle, clipSector.startAngle), Math.min(endAngle, clipSector.endAngle), clipSector.innerRadius, clipSector.outerRadius ); } const visible = clipSector == null || clipSectorVisibility(startAngle, endAngle, clipSector); sect.startAngle = startAngle; sect.endAngle = endAngle; sect.clipSector = clipSector; sect.visible = visible; } }; const needle = { fromFn(needleNode) { let { angle: rotation } = needleNode.previousDatum ?? needleNode.datum; if (initialLoad) { rotation = initialStartAngle; } return { rotation, phase }; }, toFn(_needleNode, datum) { const { angle: rotation } = datum; return { rotation }; } }; return { node, needle }; } function resetRadialGaugeSeriesResetSectorFunction(_node, datum) { const { startAngle, endAngle } = datum; const clipSector = computeClipSector(datum); const visible = clipSector == null || clipSectorVisibility(startAngle, endAngle, clipSector); return { startAngle, endAngle, clipSector, visible }; } function resetRadialGaugeSeriesResetNeedleFunction(_node, datum) { const { angle: angle2 } = datum; return { rotation: angle2 }; } var verticalAlignFactors3 = { top: 0, middle: 0.5, bottom: 1 }; function formatRadialGaugeLabels(series, selection, opts, innerRadius, datumOverrides) { const { padding, textAlign, verticalAlign } = opts; let labelDatum; let secondaryLabelDatum; selection.each((_node, datum) => { if (datum.label === "primary") { labelDatum = datum; } else if (datum.label === "secondary") { secondaryLabelDatum = datum; } }); if (labelDatum == null) return; const labelText = getLabelText(series, labelDatum, datumOverrides?.label); if (labelText == null) return; const secondaryLabelText = secondaryLabelDatum != null ? getLabelText(series, secondaryLabelDatum, datumOverrides?.secondaryLabel) : void 0; const params = { padding }; const horizontalFactor = textAlign === "center" ? 2 : 1; const verticalFactor = verticalAlign === "middle" ? 2 : 1; const sizeFittingHeight = (height22) => ({ width: Math.sqrt(Math.max(innerRadius ** 2 - (height22 / verticalFactor) ** 2, 0)) * horizontalFactor, height: Math.min(height22, verticalFactor * innerRadius), meta: null }); let labelLayout; let secondaryLabelLayout; let height2; if (secondaryLabelDatum != null && secondaryLabelText != null) { const layout = formatStackedLabels( labelText, labelDatum, secondaryLabelText, secondaryLabelDatum, params, sizeFittingHeight ); labelLayout = layout?.label; secondaryLabelLayout = layout?.secondaryLabel; height2 = layout?.height ?? 0; } else { const layout = formatSingleLabel(labelText, labelDatum, params, sizeFittingHeight); labelLayout = layout?.[0]; secondaryLabelLayout = void 0; height2 = layout?.[0].height ?? 0; } const rectYOffset = height2 * verticalAlignFactors3[verticalAlign]; selection.each((label, datum) => { let layout; if (datum.label === "primary") { layout = labelLayout; } else if (datum.label === "secondary") { layout = secondaryLabelLayout; } if (layout == null) { label.visible = false; return; } label.visible = true; label.text = layout.text; label.fontSize = layout.fontSize; label.lineHeight = layout.lineHeight; label.textAlign = textAlign; label.textBaseline = "middle"; const rectOriginInLabelRect = datum.label === "primary" ? layout.height / 2 : height2 - layout.height / 2; label.y = datum.centerY + rectOriginInLabelRect - rectYOffset; label.x = datum.centerX; }); } var { fromToMotion: fromToMotion3, resetMotion: resetMotion3, SeriesNodePickMode: SeriesNodePickMode15, StateMachine: StateMachine14, createDatumId: createDatumId19, ChartAxisDirection: ChartAxisDirection30, normalizeAngle360: normalizeAngle3607, normalizeAngle360Inclusive: normalizeAngle360Inclusive3, toDegrees: toDegrees2, toRadians: toRadians6, BBox: BBox18, Group: Group19, PointerEvents: PointerEvents10, Selection: Selection15, Sector: Sector6, SectorBox: SectorBox6, Text: Text8, ConicGradient: ConicGradient2, Marker: Marker5, getColorStops: getColorStops22 } = import_ag_charts_community245._ModuleSupport; var targetPlacementRotation = { inside: 90, middle: 0, outside: -90 }; var outsideLabelPlacements = [ { textAlign: "left", textBaseline: "top" }, { textAlign: "right", textBaseline: "top" }, { textAlign: "right", textBaseline: "bottom" }, { textAlign: "left", textBaseline: "bottom" } ]; var insideLabelPlacements = [ { textAlign: "right", textBaseline: "bottom" }, { textAlign: "left", textBaseline: "bottom" }, { textAlign: "left", textBaseline: "top" }, { textAlign: "right", textBaseline: "top" } ]; var RadialGaugeSeries = class extends import_ag_charts_community245._ModuleSupport.Series { constructor(moduleCtx) { super({ moduleCtx, useLabelLayer: true, pickModes: [SeriesNodePickMode15.EXACT_SHAPE_MATCH, SeriesNodePickMode15.NEAREST_NODE] }); this.canHaveAxes = true; this.properties = new RadialGaugeSeriesProperties(); this.centerX = 0; this.centerY = 0; this.radius = 0; this.textAlign = "center"; this.verticalAlign = "middle"; this.scaleGroup = this.contentGroup.appendChild(new Group19({ name: "scaleGroup" })); this.itemGroup = this.contentGroup.appendChild(new Group19({ name: "itemGroup" })); this.itemNeedleGroup = this.contentGroup.appendChild(new Group19({ name: "itemNeedleGroup" })); this.itemTargetGroup = this.contentGroup.appendChild(new Group19({ name: "itemTargetGroup" })); this.itemTargetLabelGroup = this.contentGroup.appendChild(new Group19({ name: "itemTargetLabelGroup" })); this.itemLabelGroup = this.contentGroup.appendChild(new Group19({ name: "itemLabelGroup" })); this.highlightTargetGroup = this.highlightGroup.appendChild( new Group19({ name: "itemTargetLabelGroup" }) ); this.scaleSelection = Selection15.select( this.scaleGroup, () => this.nodeFactory() ); this.datumSelection = Selection15.select( this.itemGroup, () => this.nodeFactory() ); this.needleSelection = Selection15.select( this.itemNeedleGroup, RadialGaugeNeedle ); this.targetSelection = Selection15.select( this.itemTargetGroup, () => this.markerFactory() ); this.targetLabelSelection = Selection15.select(this.itemTargetLabelGroup, Text8); this.labelSelection = Selection15.select( this.itemLabelGroup, Text8 ); this.highlightTargetSelection = Selection15.select(this.highlightTargetGroup, () => this.markerFactory()); this.datumUnion = new DatumUnion(); this.animationState = new StateMachine14("empty", { empty: { update: { target: "ready", action: () => this.animateEmptyUpdateReady() }, reset: "empty", skip: "ready" }, ready: { updateData: "waiting", clear: "clearing", resize: () => this.animateReadyResize(), reset: "empty", skip: "ready" }, waiting: { update: { target: "ready", action: () => this.animateWaitingUpdateReady() }, reset: "empty", skip: "ready" }, clearing: { update: { target: "empty" }, reset: "empty", skip: "ready" } }); this.scaleGroup.pointerEvents = PointerEvents10.None; } get maximumRadius() { return this.properties.outerRadius; } get minimumRadius() { return this.properties.outerRadius; } get hasData() { return this.properties.value != null; } nodeFactory() { return new Sector6(); } markerFactory() { const marker = new Marker5(); marker.size = 1; return marker; } processData() { this.nodeDataRefresh = true; this.animationState.transition("updateData"); } formatLabel(value) { return formatLabel(value, this.axes[ChartAxisDirection30.X]); } createConicGradient(fills, fillMode) { const { centerX, centerY, radius } = this; const { domain, range: range22 } = this.axes[ChartAxisDirection30.X].scale; const [startAngle, endAngle] = range22; const { defaultColorRange } = this.properties; const conicAngle = normalizeAngle3607((startAngle + endAngle) / 2 + Math.PI); const sweepAngle = normalizeAngle360Inclusive3(endAngle - startAngle); const stops = getColorStops22(fills, defaultColorRange, domain, fillMode).map( ({ color, offset: offset4 }) => { offset4 = Math.min(Math.max(offset4, 0), 1); const angle2 = startAngle + sweepAngle * offset4; offset4 = (angle2 - conicAngle) / (2 * Math.PI); offset4 = (offset4 % 1 + 1) % 1; return { offset: offset4, color }; } ); return new ConicGradient2( "oklch", stops, toDegrees2(conicAngle) - 90, new BBox18(centerX - radius, centerY - radius, 2 * radius, 2 * radius) ); } getTargets() { const { properties } = this; const defaultTarget = properties.defaultTarget; return Array.from(properties.targets).map((target) => { const { text: text22 = defaultTarget.text, value = defaultTarget.value ?? 0, shape = defaultTarget.shape ?? "triangle", rotation = defaultTarget.rotation ?? 0, strokeWidth = defaultTarget.strokeWidth ?? 0, placement = defaultTarget.placement ?? "middle", spacing = defaultTarget.spacing ?? 0, size = defaultTarget.size ?? 0, fill = defaultTarget.fill ?? "black", fillOpacity = defaultTarget.fillOpacity ?? 1, stroke: stroke22 = defaultTarget.stroke ?? "black", strokeOpacity = defaultTarget.strokeOpacity ?? 1, lineDash = defaultTarget.lineDash ?? [0], lineDashOffset = defaultTarget.lineDashOffset ?? 0 } = target; const { enabled: labelEnabled = defaultTarget.label.enabled, color: labelColor = defaultTarget.label.color ?? "black", fontStyle: labelFontStyle = defaultTarget.label.fontStyle ?? "normal", fontWeight: labelFontWeight = defaultTarget.label.fontWeight ?? "normal", fontSize: labelFontSize = defaultTarget.label.fontSize, fontFamily: labelFontFamily = defaultTarget.label.fontFamily, spacing: labelSpacing = defaultTarget.label.spacing ?? 0 } = target.label; return { text: text22, value, shape, placement, spacing, size, rotation, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset, label: { enabled: labelEnabled, color: labelColor, fontStyle: labelFontStyle, fontWeight: labelFontWeight, fontSize: labelFontSize, fontFamily: labelFontFamily, spacing: labelSpacing } }; }); } getTargetRadius(target) { const { radius, properties } = this; const { innerRadiusRatio, outerRadiusRatio } = properties; const { placement, spacing, size } = target; const outerRadius = radius * outerRadiusRatio; const innerRadius = radius * innerRadiusRatio; switch (placement) { case "inside": return Math.max(innerRadius - spacing - size / 2, 0); case "outside": return outerRadius + spacing + size / 2; default: return (innerRadius + outerRadius) / 2; } } getTargetLabel(target) { const angleAxis = this.axes[ChartAxisDirection30.X]; const angleScale = angleAxis.scale; const { value, size, placement, label } = target; const { spacing, color: fill, fontStyle, fontWeight, fontSize, fontFamily } = label; const lineHeight = void 0; const angle2 = angleScale.convert(value); const quadrant = normalizeAngle3607(angle2) / (Math.PI / 2) | 0; const offset4 = size / 2 + spacing; let textAlign; let textBaseline; let offsetX; let offsetY; switch (placement) { case "outside": ({ textAlign, textBaseline } = outsideLabelPlacements[quadrant]); offsetX = offset4 * Math.cos(angle2); offsetY = offset4 * Math.sin(angle2); break; case "inside": ({ textAlign, textBaseline } = insideLabelPlacements[quadrant]); offsetX = -offset4 * Math.cos(angle2); offsetY = -offset4 * Math.sin(angle2); break; default: textAlign = "center"; textBaseline = "bottom"; offsetX = 0; offsetY = -offset4; break; } return { offsetX, offsetY, fill, textAlign, textBaseline, fontStyle, fontWeight, fontSize, fontFamily, lineHeight }; } createNodeData() { const { id: seriesId, properties, radius, centerX, centerY } = this; if (!properties.isValid()) return; const angleAxis = this.axes[ChartAxisDirection30.X]; if (angleAxis == null) return; const { value, innerRadiusRatio, outerRadiusRatio, segmentation, cornerRadius, cornerMode, needle, bar, scale: scale2, label, secondaryLabel } = properties; const { outerRadius = radius * outerRadiusRatio, innerRadius = radius * innerRadiusRatio } = properties; const targets = this.getTargets(); const { domain } = angleAxis.scale; const nodeData = []; const targetData = []; const needleData = []; const labelData = []; const scaleData = []; const [startAngle, endAngle] = angleAxis.range; const angleScale = angleAxis.scale; const cornersOnAllItems = cornerMode === "item"; const containerStartAngle = angleScale.convert(domain[0]); const containerEndAngle = angleScale.convert(value); const maxTicks = Math.ceil(normalizeAngle360Inclusive3(containerEndAngle - containerStartAngle) * radius); let segments = segmentation.enabled ? segmentation.interval.getSegments(angleAxis.scale, maxTicks) : void 0; const barFill = !bar.enabled ? "rgba(0,0,0,0)" : bar.fill ?? this.createConicGradient(bar.fills, bar.fillMode); const scaleFill = scale2.fill ?? (bar.enabled && scale2.fills.length === 0 ? scale2.defaultFill : void 0) ?? this.createConicGradient(scale2.fills, scale2.fillMode); if (segments == null && cornersOnAllItems) { const [segmentStart, segmentEnd] = domain; const datum = { value, segmentStart, segmentEnd }; const appliedCornerRadius = Math.min(cornerRadius, (outerRadius - innerRadius) / 2); const angleInset = appliedCornerRadius / ((innerRadius + outerRadius) / 2); nodeData.push({ series: this, itemId: `value`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, centerX, centerY, outerRadius, innerRadius, startAngle: containerStartAngle - angleInset, endAngle: containerEndAngle + angleInset, clipStartAngle: void 0, clipEndAngle: void 0, startCornerRadius: cornerRadius, endCornerRadius: cornerRadius, fill: barFill }); scaleData.push({ series: this, itemId: `scale`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, centerX, centerY, outerRadius, innerRadius, startAngle: startAngle - angleInset, endAngle: endAngle + angleInset, clipStartAngle: void 0, clipEndAngle: void 0, startCornerRadius: cornerRadius, endCornerRadius: cornerRadius, fill: scaleFill }); } else { segments ?? (segments = domain); for (let i = 0; i < segments.length - 1; i++) { const segmentStart = segments[i]; const segmentEnd = segments[i + 1]; const datum = { value, segmentStart, segmentEnd }; const isStart = i === 0; const isEnd = i === segments.length - 2; const itemStartAngle = angleScale.convert(segmentStart); const itemEndAngle = angleScale.convert(segmentEnd); nodeData.push({ series: this, itemId: `value-${i}`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, centerX, centerY, outerRadius, innerRadius, startAngle: itemStartAngle, endAngle: itemEndAngle, clipStartAngle: containerStartAngle, clipEndAngle: containerEndAngle, startCornerRadius: cornersOnAllItems || isStart ? cornerRadius : 0, endCornerRadius: cornersOnAllItems || isEnd ? cornerRadius : 0, fill: barFill }); scaleData.push({ series: this, itemId: `scale-${i}`, datum, datumIndex: { type: 0 /* Node */ }, type: 0, centerX, centerY, outerRadius, innerRadius, startAngle: itemStartAngle, endAngle: itemEndAngle, clipStartAngle: void 0, clipEndAngle: void 0, startCornerRadius: cornersOnAllItems || isStart ? cornerRadius : 0, endCornerRadius: cornersOnAllItems || isEnd ? cornerRadius : 0, fill: scaleFill }); } } if (!needle.enabled && label.enabled) { const { text: text22, color: fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter = (params) => this.formatLabel(params.value) } = label; labelData.push({ label: "primary", centerX, centerY, text: text22, value, fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter }); } if (!needle.enabled && secondaryLabel.enabled) { const { text: text22, color: fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter } = secondaryLabel; labelData.push({ label: "secondary", centerX, centerY, text: text22, value, fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter }); } if (needle.enabled) { let needleRadius = needle.radiusRatio != null ? radius * needle.radiusRatio : innerRadius; needleRadius = Math.max(needleRadius - needle.spacing, 0); const needleAngle = angleScale.convert(value); needleData.push({ centerX, centerY, radius: needleRadius, angle: needleAngle, series: this }); } for (let i = 0; i < targets.length; i += 1) { const target = targets[i]; const { value: targetValue, text: text22, size, shape, fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = target; if (targetValue < Math.min(...domain) || targetValue > Math.max(...domain)) { continue; } const targetRadius = this.getTargetRadius(target); const targetAngle = angleScale.convert(targetValue); const targetRotation = toRadians6(target.rotation + targetPlacementRotation[target.placement]); targetData.push({ series: this, itemId: `target-${i}`, midPoint: { x: targetRadius * Math.cos(targetAngle) + centerX, y: targetRadius * Math.sin(targetAngle) + centerY }, datum: { value: targetValue }, datumIndex: { type: 1, index: i }, type: 1, value: targetValue, text: text22, centerX, centerY, shape, radius: targetRadius, angle: targetAngle, rotation: targetRotation, size, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset, label: this.getTargetLabel(target) }); } return { itemId: seriesId, nodeData, needleData, targetData, labelData, scaleData }; } updateSelections(resize) { if (this.nodeDataRefresh || resize) { this.contextNodeData = this.createNodeData(); this.nodeDataRefresh = false; } } highlightDatum(node) { if (node != null && node.series === this && node.type === 1) { return node; } } update({ seriesRect }) { const { datumSelection, labelSelection, needleSelection, targetSelection, targetLabelSelection, scaleSelection, highlightTargetSelection } = this; const resize = this.checkResize(seriesRect); this.updateSelections(resize); this.contentGroup.visible = this.visible; this.contentGroup.opacity = this.getOpacity(); const nodeData = this.contextNodeData?.nodeData ?? []; const labelData = this.contextNodeData?.labelData ?? []; const needleData = this.contextNodeData?.needleData ?? []; const targetData = this.contextNodeData?.targetData ?? []; const scaleData = this.contextNodeData?.scaleData ?? []; const highlightTargetDatum = this.highlightDatum(this.ctx.highlightManager.getActiveHighlight()); this.scaleSelection = this.updateScaleSelection({ scaleData, scaleSelection }); this.updateScaleNodes({ scaleSelection }); this.needleSelection = this.updateNeedleSelection({ needleData, needleSelection }); this.updateNeedleNodes({ needleSelection }); this.targetSelection = this.updateTargetSelection({ targetData, targetSelection }); this.updateTargetNodes({ targetSelection, isHighlight: false }); this.targetLabelSelection = this.updateTargetLabelSelection({ targetData, targetLabelSelection }); this.updateTargetLabelNodes({ targetLabelSelection }); this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection }); this.updateDatumNodes({ datumSelection }); this.labelSelection = this.updateLabelSelection({ labelData, labelSelection }); this.updateLabelNodes({ labelSelection }); this.highlightTargetSelection = this.updateTargetSelection({ targetData: highlightTargetDatum != null ? [highlightTargetDatum] : [], targetSelection: highlightTargetSelection }); this.updateTargetNodes({ targetSelection: highlightTargetSelection, isHighlight: true }); if (resize) { this.animationState.transition("resize"); } this.animationState.transition("update"); } updateDatumSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => { return createDatumId19(opts.nodeData.length, datum.itemId); }); } updateDatumNodes(opts) { const { datumSelection } = opts; const { ctx, properties } = this; const { bar, segmentation } = properties; const sectorSpacing = segmentation.spacing ?? 0; const { fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = bar; const strokeWidth = this.getStrokeWidth(bar.strokeWidth); const animationDisabled = ctx.animationManager.isSkipped(); datumSelection.each((sector, datum) => { const { centerX, centerY, innerRadius, outerRadius, startCornerRadius, endCornerRadius, fill } = datum; sector.centerX = centerX; sector.centerY = centerY; sector.innerRadius = innerRadius; sector.outerRadius = outerRadius; sector.pointerEvents = this.properties.bar.enabled ? import_ag_charts_community245._ModuleSupport.PointerEvents.All : import_ag_charts_community245._ModuleSupport.PointerEvents.None; sector.fill = fill; sector.fillOpacity = fillOpacity; sector.stroke = stroke22; sector.strokeOpacity = strokeOpacity; sector.strokeWidth = strokeWidth; sector.lineDash = lineDash; sector.lineDashOffset = lineDashOffset; sector.startOuterCornerRadius = startCornerRadius; sector.startInnerCornerRadius = startCornerRadius; sector.endOuterCornerRadius = endCornerRadius; sector.endInnerCornerRadius = endCornerRadius; sector.radialEdgeInset = (sectorSpacing + sector.strokeWidth) / 2; sector.concentricEdgeInset = sector.strokeWidth / 2; if (animationDisabled || sector.previousDatum == null) { sector.setProperties(resetRadialGaugeSeriesResetSectorFunction(sector, datum)); } }); this.datumUnion.update(datumSelection, this.itemGroup, import_ag_charts_community245._ModuleSupport.Sector, (node, first2, last) => { node.clipSector ?? (node.clipSector = new SectorBox6(NaN, NaN, NaN, NaN)); node.centerX = first2.centerX; node.centerY = first2.centerY; node.outerRadius = node.clipSector.outerRadius = first2.outerRadius; node.innerRadius = node.clipSector.innerRadius = first2.innerRadius; node.startAngle = node.clipSector.startAngle = first2.startAngle; node.startInnerCornerRadius = first2.startInnerCornerRadius; node.startOuterCornerRadius = first2.startOuterCornerRadius; node.endAngle = last.endAngle; node.clipSector.endAngle = last.clipSector?.endAngle ?? last.endAngle; node.endInnerCornerRadius = last.endInnerCornerRadius; node.endOuterCornerRadius = last.endOuterCornerRadius; node.pointerEvents = import_ag_charts_community245._ModuleSupport.PointerEvents.None; }); } updateScaleSelection(opts) { return opts.scaleSelection.update(opts.scaleData, void 0, (datum) => { return createDatumId19(opts.scaleData.length, datum.itemId); }); } updateScaleNodes(opts) { const { scaleSelection } = opts; const { scale: scale2, segmentation } = this.properties; const sectorSpacing = segmentation.spacing ?? 0; const { fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = scale2; scaleSelection.each((sector, datum) => { const { centerX, centerY, innerRadius, outerRadius, startCornerRadius, endCornerRadius, fill } = datum; sector.centerX = centerX; sector.centerY = centerY; sector.innerRadius = innerRadius; sector.outerRadius = outerRadius; sector.fill = fill; sector.fillOpacity = fillOpacity; sector.stroke = stroke22; sector.strokeOpacity = strokeOpacity; sector.strokeWidth = strokeWidth; sector.lineDash = lineDash; sector.lineDashOffset = lineDashOffset; sector.startOuterCornerRadius = startCornerRadius; sector.startInnerCornerRadius = startCornerRadius; sector.endOuterCornerRadius = endCornerRadius; sector.endInnerCornerRadius = endCornerRadius; sector.radialEdgeInset = (sectorSpacing + sector.strokeWidth) / 2; sector.concentricEdgeInset = sector.strokeWidth / 2; sector.setProperties(resetRadialGaugeSeriesResetSectorFunction(sector, datum)); }); } updateNeedleSelection(opts) { return opts.needleSelection.update(opts.needleData, void 0, () => createDatumId19([])); } updateNeedleNodes(opts) { const { needleSelection } = opts; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.needle; const animationDisabled = this.ctx.animationManager.isSkipped(); needleSelection.each((needle, datum) => { const { centerX, centerY, radius } = datum; const scale2 = radius * 2; needle.d = RadialGaugeNeedle.defaultPathData; needle.fill = fill; needle.fillOpacity = fillOpacity; needle.stroke = stroke22; needle.strokeOpacity = strokeOpacity; needle.strokeWidth = strokeWidth / scale2; needle.lineDash = lineDash.map((d) => d / scale2); needle.lineDashOffset = lineDashOffset / scale2; needle.translationX = centerX; needle.translationY = centerY; needle.scalingX = scale2; needle.scalingY = scale2; if (animationDisabled) { needle.setProperties(resetRadialGaugeSeriesResetNeedleFunction(needle, datum)); } }); } updateTargetSelection(opts) { return opts.targetSelection.update(opts.targetData, void 0, (target) => target.itemId); } updateTargetNodes(opts) { const { targetSelection, isHighlight } = opts; const highlightStyle = isHighlight ? this.properties.highlightStyle.item : void 0; targetSelection.each((target, datum) => { const { centerX, centerY, angle: angle2, radius, shape, size, rotation, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = datum; target.shape = shape === "line" ? lineMarker : shape; target.size = size; target.fill = highlightStyle?.fill ?? fill; target.fillOpacity = highlightStyle?.fillOpacity ?? fillOpacity; target.stroke = highlightStyle?.stroke ?? stroke22; target.strokeOpacity = highlightStyle?.strokeOpacity ?? strokeOpacity; target.strokeWidth = highlightStyle?.strokeWidth ?? strokeWidth; target.lineDash = highlightStyle?.lineDash ?? lineDash; target.lineDashOffset = highlightStyle?.lineDashOffset ?? lineDashOffset; target.translationX = centerX + radius * Math.cos(angle2); target.translationY = centerY + radius * Math.sin(angle2); target.rotation = angle2 + rotation; }); } updateTargetLabelSelection(opts) { return opts.targetLabelSelection.update(opts.targetData, void 0, (target) => target.itemId); } updateTargetLabelNodes(opts) { const { targetLabelSelection } = opts; targetLabelSelection.each((label, target) => { const { centerX, centerY, radius, angle: angle2, text: text22 } = target; const { offsetX, offsetY, fill, fontStyle, fontWeight, fontSize, fontFamily, textAlign, textBaseline } = target.label; if (text22 == null) { label.visible = false; return; } label.visible = true; label.x = centerX + radius * Math.cos(angle2) + offsetX; label.y = centerY + radius * Math.sin(angle2) + offsetY; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textAlign = textAlign; label.textBaseline = textBaseline; }); } updateLabelSelection(opts) { return opts.labelSelection.update(opts.labelData, void 0, (datum) => datum.label); } updateLabelNodes(opts) { const { labelSelection } = opts; const animationDisabled = this.ctx.animationManager.isSkipped(); labelSelection.each((label, datum) => { label.fill = datum.fill; label.fontStyle = datum.fontStyle; label.fontWeight = datum.fontWeight; label.fontFamily = datum.fontFamily; }); if (animationDisabled || this.labelsHaveExplicitText()) { this.formatLabelText(); } } labelsHaveExplicitText() { for (const { datum } of this.labelSelection) { if (datum.text == null) { return false; } } return true; } formatLabelText(datum) { const angleAxis = this.axes[ChartAxisDirection30.X]; if (angleAxis == null) return; const { labelSelection, radius, textAlign, verticalAlign } = this; const { spacing: padding, innerRadiusRatio } = this.properties; formatRadialGaugeLabels( this, labelSelection, { padding, textAlign, verticalAlign }, radius * innerRadiusRatio, datum ); } resetAllAnimation() { this.ctx.animationManager.stopByAnimationGroupId(this.id); resetMotion3([this.datumSelection], resetRadialGaugeSeriesResetSectorFunction); resetMotion3([this.needleSelection], resetRadialGaugeSeriesResetNeedleFunction); this.formatLabelText(); } resetAnimation(phase) { if (phase === "initial") { this.animationState.transition("reset"); } else if (phase === "ready") { this.animationState.transition("skip"); } } animateLabelText(params = {}) { const { animationManager } = this.ctx; let labelFrom; let labelTo; let secondaryLabelFrom; let secondaryLabelTo; this.labelSelection.each((label, datum) => { label.opacity = 1; if (datum.label === "primary") { labelFrom = label.previousDatum?.value ?? params.from ?? datum.value; labelTo = datum.value; } else if (datum.label === "secondary") { secondaryLabelFrom = label.previousDatum?.value ?? params.from ?? datum.value; secondaryLabelTo = datum.value; } }); if (this.labelsHaveExplicitText()) { } else if (labelTo == null || secondaryLabelTo == null) { this.formatLabelText(); } else if (labelFrom === labelTo && secondaryLabelFrom === secondaryLabelTo) { this.formatLabelText({ label: labelTo, secondaryLabel: secondaryLabelTo }); } else { const animationId = `${this.id}_labels`; animationManager.animate({ id: animationId, groupId: "label", from: { label: labelFrom, secondaryLabel: secondaryLabelFrom }, to: { label: labelTo, secondaryLabel: secondaryLabelTo }, phase: params.phase ?? "update", onUpdate: (datum) => this.formatLabelText(datum) }); } } animateEmptyUpdateReady() { const { animationManager } = this.ctx; const { node, needle } = prepareRadialGaugeSeriesAnimationFunctions( true, this.axes[ChartAxisDirection30.X]?.range[0] ?? 0 ); fromToMotion3(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId); fromToMotion3(this.id, "needle", animationManager, [this.needleSelection], needle, () => "needle"); fromToMotion3( this.id, "label", animationManager, [this.labelSelection], fadeInFns, (_label, datum) => datum.label ); this.animateLabelText({ from: this.axes[ChartAxisDirection30.X]?.scale.domain[0] ?? 0, phase: "initial" }); } animateWaitingUpdateReady() { const { animationManager } = this.ctx; const { node, needle } = prepareRadialGaugeSeriesAnimationFunctions( false, this.axes[ChartAxisDirection30.X]?.range[0] ?? 0 ); fromToMotion3(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId); fromToMotion3(this.id, "needle", animationManager, [this.needleSelection], needle, () => "needle"); this.animateLabelText(); } animateReadyResize() { this.resetAllAnimation(); } getSeriesDomain() { return [NaN, NaN]; } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } getLegendData() { return []; } getTooltipContent(nodeDatum) { const { id: seriesId, properties } = this; const { tooltip } = properties; if (!properties.isValid()) return; const { value = properties.value, text: text22 = properties.label.text } = parseUnknownGaugeNodeDatum(nodeDatum); return tooltip.formatTooltip( { data: [{ label: text22, fallbackLabel: "Value", value: this.formatLabel(value) }] }, { seriesId, title: void 0, datum: void 0, value } ); } pickNodeClosestDatum(point) { return pickGaugeNearestDatum(this, point); } pickFocus(opts) { return pickGaugeFocus(this, opts); } getCaptionText() { const { value } = this.properties; const description = []; description.push(this.formatLabel(value)); this.labelSelection.each((_label, datum) => { const text22 = getLabelText(this, datum); if (text22 != null) { description.push(text22); } }); return description.join(". "); } }; RadialGaugeSeries.className = "RadialGaugeSeries"; RadialGaugeSeries.type = "radial-gauge"; var { FONT_SIZE_RATIO: FONT_SIZE_RATIO22, ThemeSymbols: { DEFAULT_HIERARCHY_FILLS: DEFAULT_HIERARCHY_FILLS3, DEFAULT_GAUGE_SERIES_COLOR_RANGE: DEFAULT_GAUGE_SERIES_COLOR_RANGE22 }, ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE10 } } = import_ag_charts_community246._ModuleSupport; var RadialGaugeModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["gauge"], identifier: "radial-gauge", moduleFactory: (ctx) => new RadialGaugeSeries(ctx), tooltipDefaults: { range: 10 }, defaultAxes: [ { type: POLAR_AXIS_TYPE10.ANGLE_NUMBER, line: { enabled: false } }, { type: POLAR_AXIS_TYPE10.RADIUS_NUMBER, line: { enabled: false } } ], themeTemplate: { minWidth: 200, minHeight: 200, tooltip: { enabled: false }, series: { outerRadiusRatio: 1, innerRadiusRatio: 0.8, bar: { strokeWidth: 0 }, segmentation: { enabled: false, interval: {}, spacing: 2 }, // @ts-expect-error Private defaultTarget: { fill: { $ref: "foregroundColor" }, stroke: { $ref: "foregroundColor" }, size: 10, shape: "triangle", placement: "outside", spacing: 5, label: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "textColor" }, spacing: 5 } }, needle: { enabled: false, fill: { $ref: "foregroundColor" }, spacing: 10 }, label: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: 56, minimumFontSize: 18 / 56, fontFamily: { $ref: "fontFamily" }, color: { $ref: "textColor" } }, secondaryLabel: { enabled: true, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [FONT_SIZE_RATIO22.LARGE] }, minimumFontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "subtleTextColor" } } }, axes: { [POLAR_AXIS_TYPE10.ANGLE_NUMBER]: { startAngle: 270, endAngle: 270 + 180, nice: false, line: { enabled: false } } } }, paletteFactory(params) { const { takeColors, colorsCount, userPalette, themeTemplateParameters } = params; const { fills } = takeColors(colorsCount); const defaultColorRange = themeTemplateParameters.get(DEFAULT_GAUGE_SERIES_COLOR_RANGE22); const hierarchyFills = themeTemplateParameters.get(DEFAULT_HIERARCHY_FILLS3); const colorRange = userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]]; return { scale: { defaultFill: hierarchyFills?.[1], stroke: hierarchyFills?.[2] }, defaultColorRange: defaultColorStops(colorRange) }; } }; var import_ag_charts_community251 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community249 = (init_main4(), __toCommonJS(main_exports)); var AGGREGATION_THRESHOLD4 = 1e3; function aggregationContainsTopIndex(xValues, d0, d1, indexData, maxRange, datumIndex) { const xValue = xValues[datumIndex]; if (xValue == null) return false; const xRatio = xRatioForDatumIndex(xValue, d0, d1); const aggIndex = aggregationIndexForXRatio(xRatio, maxRange); return datumIndex === indexData[aggIndex + Y_MAX2]; } function aggregationContainsBottomIndex(xValues, d0, d1, indexData, maxRange, datumIndex) { const xValue = xValues[datumIndex]; if (xValue == null) return false; const xRatio = xRatioForDatumIndex(xValue, d0, d1); const aggIndex = aggregationIndexForXRatio(xRatio, maxRange); return datumIndex === indexData[aggIndex + Y_MIN2]; } function aggregateData(xValues, highValues, lowValues, domain) { if (xValues.length < AGGREGATION_THRESHOLD4) return; const [d0, d1] = aggregationDomain(domain); let maxRange = maxRangeFittingPoints(xValues); const { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, maxRange); let topIndices = []; let bottomIndices = []; for (let datumIndex = 0; datumIndex < xValues.length; datumIndex += 1) { if (aggregationContainsTopIndex(xValues, d0, d1, indexData, maxRange, datumIndex)) { topIndices.push(datumIndex); } if (aggregationContainsBottomIndex(xValues, d0, d1, indexData, maxRange, datumIndex)) { bottomIndices.push(datumIndex); } } const filters = [{ maxRange, topIndices, bottomIndices }]; while (maxRange > 64) { ({ maxRange } = compactAggregationIndices(indexData, valueData, maxRange, { inPlace: true })); topIndices = topIndices.filter(aggregationContainsTopIndex.bind(null, xValues, d0, d1, indexData, maxRange)); bottomIndices = bottomIndices.filter( aggregationContainsBottomIndex.bind(null, xValues, d0, d1, indexData, maxRange) ); filters.push({ maxRange, topIndices, bottomIndices }); } filters.reverse(); return filters; } var import_ag_charts_community247 = (init_main4(), __toCommonJS(main_exports)); var { CartesianSeriesProperties: CartesianSeriesProperties22, InterpolationProperties: InterpolationProperties2, SeriesMarker: SeriesMarker22, SeriesTooltip: SeriesTooltip19, Validate: Validate82, BOOLEAN: BOOLEAN33, COLOR_STRING: COLOR_STRING26, LINE_DASH: LINE_DASH222, OBJECT: OBJECT42, PLACEMENT: PLACEMENT2, POSITIVE_NUMBER: POSITIVE_NUMBER34, RATIO: RATIO32, STRING: STRING39, DropShadow: DropShadow3, Label: Label14 } = import_ag_charts_community247._ModuleSupport; var RangeAreaSeriesLabel = class extends Label14 { constructor() { super(...arguments); this.placement = "outside"; this.padding = 6; } }; __decorateClass2([ Validate82(PLACEMENT2) ], RangeAreaSeriesLabel.prototype, "placement", 2); __decorateClass2([ Validate82(POSITIVE_NUMBER34) ], RangeAreaSeriesLabel.prototype, "padding", 2); var RangeAreaProperties = class extends CartesianSeriesProperties22 { constructor() { super(...arguments); this.fill = "#99CCFF"; this.fillOpacity = 1; this.stroke = "#99CCFF"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.interpolation = new InterpolationProperties2(); this.shadow = new DropShadow3().set({ enabled: false }); this.marker = new SeriesMarker22(); this.label = new RangeAreaSeriesLabel(); this.tooltip = new SeriesTooltip19(); this.connectMissingData = false; } }; __decorateClass2([ Validate82(STRING39) ], RangeAreaProperties.prototype, "xKey", 2); __decorateClass2([ Validate82(STRING39) ], RangeAreaProperties.prototype, "yLowKey", 2); __decorateClass2([ Validate82(STRING39) ], RangeAreaProperties.prototype, "yHighKey", 2); __decorateClass2([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "xName", 2); __decorateClass2([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "yName", 2); __decorateClass2([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "yLowName", 2); __decorateClass2([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "yHighName", 2); __decorateClass2([ Validate82(COLOR_STRING26) ], RangeAreaProperties.prototype, "fill", 2); __decorateClass2([ Validate82(RATIO32) ], RangeAreaProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate82(COLOR_STRING26) ], RangeAreaProperties.prototype, "stroke", 2); __decorateClass2([ Validate82(POSITIVE_NUMBER34) ], RangeAreaProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate82(RATIO32) ], RangeAreaProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate82(LINE_DASH222) ], RangeAreaProperties.prototype, "lineDash", 2); __decorateClass2([ Validate82(POSITIVE_NUMBER34) ], RangeAreaProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "interpolation", 2); __decorateClass2([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "shadow", 2); __decorateClass2([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "marker", 2); __decorateClass2([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "label", 2); __decorateClass2([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "tooltip", 2); __decorateClass2([ Validate82(BOOLEAN33) ], RangeAreaProperties.prototype, "connectMissingData", 2); var import_ag_charts_community248 = (init_main4(), __toCommonJS(main_exports)); var { CollapseMode: CollapseMode2, isScaleValid: isScaleValid2, pairUpSpans: pairUpSpans2, prepareAreaFillAnimationFns: prepareAreaFillAnimationFns2, plotInterpolatedLinePathStroke: plotInterpolatedLinePathStroke2, prepareLinePathPropertyAnimation: prepareLinePathPropertyAnimation2, areScalingEqual: areScalingEqual2 } = import_ag_charts_community248._ModuleSupport; function prepareRangeAreaPathStrokeAnimationFns(status, highSpans, lowSpans, visibleToggleMode) { const removePhaseFn = (ratio2, path) => { plotInterpolatedLinePathStroke2(ratio2, path, highSpans.removed); plotInterpolatedLinePathStroke2(ratio2, path, lowSpans.removed); }; const updatePhaseFn = (ratio2, path) => { plotInterpolatedLinePathStroke2(ratio2, path, highSpans.moved); plotInterpolatedLinePathStroke2(ratio2, path, lowSpans.moved); }; const addPhaseFn = (ratio2, path) => { plotInterpolatedLinePathStroke2(ratio2, path, highSpans.added); plotInterpolatedLinePathStroke2(ratio2, path, lowSpans.added); }; const pathProperties = prepareLinePathPropertyAnimation2(status, visibleToggleMode); return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties }; } function prepareRangeAreaPathAnimation(newData, oldData, diff8) { const isCategoryBased = newData.scales.x?.type === "category"; const wasCategoryBased = oldData.scales.x?.type === "category"; if (isCategoryBased !== wasCategoryBased || !isScaleValid2(newData.scales.x) || !isScaleValid2(oldData.scales.x)) { return; } let status = "updated"; if (oldData.visible && !newData.visible) { status = "removed"; } else if (!oldData.visible && newData.visible) { status = "added"; } const fillSpans = pairUpSpans2( { scales: newData.scales, data: newData.fillData.spans }, { scales: oldData.scales, data: oldData.fillData.spans }, CollapseMode2.Split ); if (fillSpans == null) return; const fillPhantomSpans = pairUpSpans2( { scales: newData.scales, data: newData.fillData.phantomSpans }, { scales: oldData.scales, data: oldData.fillData.phantomSpans }, CollapseMode2.Split ); if (fillPhantomSpans == null) return; const highStrokeSpans = pairUpSpans2( { scales: newData.scales, data: newData.highStrokeData.spans }, { scales: oldData.scales, data: oldData.highStrokeData.spans }, CollapseMode2.Split ); if (highStrokeSpans == null) return; const lowStrokeSpans = pairUpSpans2( { scales: newData.scales, data: newData.lowStrokeData.spans }, { scales: oldData.scales, data: oldData.lowStrokeData.spans }, CollapseMode2.Split ); if (lowStrokeSpans == null) return; const fadeMode = "fade"; const fill = prepareAreaFillAnimationFns2(status, fillSpans, fillPhantomSpans, fadeMode); const stroke22 = prepareRangeAreaPathStrokeAnimationFns(status, highStrokeSpans, lowStrokeSpans, fadeMode); const hasMotion = (diff8?.changed ?? true) || !areScalingEqual2(newData.scales.x, oldData.scales.x) || !areScalingEqual2(newData.scales.y, oldData.scales.y) || status !== "updated"; return { status, fill, stroke: stroke22, hasMotion }; } var { valueProperty: valueProperty16, keyProperty: keyProperty8, ChartAxisDirection: ChartAxisDirection31, mergeDefaults: mergeDefaults5, updateLabelNode: updateLabelNode22, fixNumericExtent: fixNumericExtent8, buildResetPathFn: buildResetPathFn2, resetLabelFn: resetLabelFn4, resetMarkerFn: resetMarkerFn22, resetMarkerPositionFn: resetMarkerPositionFn2, pathSwipeInAnimation: pathSwipeInAnimation2, resetMotion: resetMotion4, markerSwipeScaleInAnimation: markerSwipeScaleInAnimation2, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation5, animationValidation: animationValidation7, diff: diff6, updateClipPath: updateClipPath2, computeMarkerFocusBounds: computeMarkerFocusBounds3, plotAreaPathFill: plotAreaPathFill2, plotLinePathStroke: plotLinePathStroke2, interpolatePoints: interpolatePoints2, pathFadeInAnimation: pathFadeInAnimation2, markerFadeInAnimation: markerFadeInAnimation22, fromToMotion: fromToMotion4, pathMotion: pathMotion2, extent: extent22, createDatumId: createDatumId20, PointerEvents: PointerEvents11, Group: Group20, BBox: BBox19, ContinuousScale: ContinuousScale7, OrdinalTimeScale: OrdinalTimeScale5, findMinMax: findMinMax3 } = import_ag_charts_community249._ModuleSupport; var RangeAreaSeriesNodeEvent = class extends import_ag_charts_community249._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.xKey = series.properties.xKey; this.yLowKey = series.properties.yLowKey; this.yHighKey = series.properties.yHighKey; } }; var RangeAreaSeries = class extends import_ag_charts_community249._ModuleSupport.CartesianSeries { constructor(moduleCtx) { super({ moduleCtx, hasMarkers: true, pathsPerSeries: ["fill", "stroke"], pickModes: [import_ag_charts_community249._ModuleSupport.SeriesNodePickMode.AXIS_ALIGNED], directionKeys: { [ChartAxisDirection31.X]: ["xKey"], [ChartAxisDirection31.Y]: ["yLowKey", "yHighKey"] }, directionNames: { [ChartAxisDirection31.X]: ["xName"], [ChartAxisDirection31.Y]: ["yLowName", "yHighName", "yName"] }, animationResetFns: { path: buildResetPathFn2({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }), label: resetLabelFn4, marker: (node, datum) => ({ ...resetMarkerFn22(node), ...resetMarkerPositionFn2(node, datum) }) } }); this.properties = new RangeAreaProperties(); this.NodeEvent = RangeAreaSeriesNodeEvent; this.dataAggregationFilters = void 0; } async processData(dataController) { if (!this.properties.isValid()) return; const { xKey, yLowKey, yHighKey } = this.properties; const xScale = this.axes[ChartAxisDirection31.X]?.scale; const yScale = this.axes[ChartAxisDirection31.Y]?.scale; const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const extraProps = []; const animationEnabled = !this.ctx.animationManager.isSkipped(); if (!this.ctx.animationManager.isSkipped() && this.processedData) { extraProps.push(diff6(this.id, this.processedData)); } if (animationEnabled) { extraProps.push(animationValidation7()); } const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, { props: [ keyProperty8(xKey, xScaleType, { id: `xValue` }), valueProperty16(yLowKey, yScaleType, { id: `yLowValue` }), valueProperty16(yHighKey, yScaleType, { id: `yHighValue` }), ...extraProps ] }); this.dataAggregationFilters = this.aggregateData(dataModel, processedData); this.animationState.transition("updateData"); } aggregateData(dataModel, processedData) { const xAxis = this.axes[ChartAxisDirection31.X]; if (xAxis == null || !(ContinuousScale7.is(xAxis.scale) || OrdinalTimeScale5.is(xAxis.scale))) return; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const yHighValues = dataModel.resolveColumnById(this, `yHighValue`, processedData); const yLowValues = dataModel.resolveColumnById(this, `yLowValue`, processedData); const { index } = dataModel.resolveProcessedDataDefById(this, `xValue`); const domain = processedData.domain.keys[index]; return aggregateData(xValues, yHighValues, yLowValues, domain); } xCoordinateRange(xValue) { const x = this.axes[ChartAxisDirection31.X].scale.convert(xValue); return [x, x]; } yCoordinateRange(yValues) { const y = this.axes[ChartAxisDirection31.Y].scale.convert(yValues[0]); return [y, y]; } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (!(processedData && dataModel)) return []; const { domain: { keys: [keys] } } = processedData; if (direction === ChartAxisDirection31.X) { const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`); if (keyDef?.def.type === "key" && keyDef.def.valueType === "category") { return keys; } return fixNumericExtent8(extent22(keys)); } else { const yExtent = this.domainForClippedRange( ChartAxisDirection31.Y, ["yHighValue", "yLowValue"], "xValue", true ); const fixedYExtent = findMinMax3(yExtent); return fixNumericExtent8(fixedYExtent); } } getSeriesRange(_direction, visibleRange) { return this.domainForVisibleRange( ChartAxisDirection31.Y, ["yHighValue", "yLowValue"], "xValue", visibleRange, true ); } createNodeData() { const { data, dataModel, processedData, axes } = this; const xAxis = axes[ChartAxisDirection31.X]; const yAxis = axes[ChartAxisDirection31.Y]; if (!(data && xAxis && yAxis && dataModel && processedData)) return; const xScale = xAxis.scale; const yScale = yAxis.scale; const { xKey, yLowKey, yHighKey, connectMissingData, marker, interpolation } = this.properties; const rawData = processedData.dataSources.get(this.id) ?? []; const xOffset = (xScale.bandwidth ?? 0) / 2; const xValues = dataModel.resolveKeysById(this, "xValue", processedData); const yHighValues = dataModel.resolveColumnById(this, "yHighValue", processedData); const yLowValues = dataModel.resolveColumnById(this, "yLowValue", processedData); const xPosition = (index) => xScale.convert(xValues[index]) + xOffset; const labelData = []; const markerData = []; const spanPoints = []; const handleDatumPoint = (datumIndex, yHighValue, yLowValue) => { const datum = rawData[datumIndex]; const xValue = xValues[datumIndex]; if (xValue == null) return; const currentSpanPoints = spanPoints[spanPoints.length - 1]; if (Number.isFinite(yHighValue) && Number.isFinite(yLowValue)) { const appendMarker = (id, yValue, y) => { markerData.push({ index: datumIndex, series: this, itemId: id, datum, datumIndex, midPoint: { x, y }, yHighValue, yLowValue, xValue, xKey, yLowKey, yHighKey, point: { x, y, size }, enabled: true }); const highLabelDatum = this.createLabelData({ datumIndex, point: { x, y }, value: yValue, yLowValue, yHighValue, itemId: id, inverted, datum, series: this }); labelData.push(highLabelDatum); }; const inverted = yLowValue > yHighValue; const x = xPosition(datumIndex); const yHighCoordinate = yScale.convert(yHighValue); const yLowCoordinate = yScale.convert(yLowValue); const { size } = marker; appendMarker("high", yHighValue, yHighCoordinate); appendMarker("low", yLowValue, yLowCoordinate); const spanPoint = { high: { point: { x, y: yHighCoordinate }, xDatum: xValue, yDatum: yHighValue }, low: { point: { x, y: yLowCoordinate }, xDatum: xValue, yDatum: yLowValue } }; if (Array.isArray(currentSpanPoints)) { currentSpanPoints.push(spanPoint); } else if (currentSpanPoints != null) { currentSpanPoints.skip += 1; spanPoints.push([spanPoint]); } else { spanPoints.push([spanPoint]); } } else if (!connectMissingData) { if (Array.isArray(currentSpanPoints) || currentSpanPoints == null) { spanPoints.push({ skip: 0 }); } else { currentSpanPoints.skip += 1; } } }; const { dataAggregationFilters } = this; const [r0, r1] = xScale.range; const range22 = r1 - r0; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range22); const topIndices = dataAggregationFilter?.topIndices; const bottomIndices = dataAggregationFilter?.bottomIndices; let [start2, end2] = this.visibleRange("xValue", xAxis.range, topIndices); start2 = Math.max(start2 - 1, 0); end2 = Math.min(end2 + 1, topIndices?.length ?? xValues.length); if (processedData.input.count < 1e3) { start2 = 0; end2 = processedData.input.count; } for (let i = start2; i < end2; i += 1) { const topDatumIndex = topIndices?.[i] ?? i; const bottomDatumIndex = bottomIndices?.[i] ?? i; handleDatumPoint(topDatumIndex, yHighValues[topDatumIndex], yLowValues[bottomDatumIndex]); } const highSpans = spanPoints.flatMap((p) => { if (!Array.isArray(p)) return []; const highPoints = p.map((d) => d.high); return interpolatePoints2(highPoints, interpolation); }); const lowSpans = spanPoints.flatMap((p) => { if (!Array.isArray(p)) return []; const lowPoints = p.map((d) => d.low); return interpolatePoints2(lowPoints, interpolation); }); const context = { itemId: `${yLowKey}-${yHighKey}`, labelData, nodeData: markerData, fillData: { itemId: "high", spans: highSpans, phantomSpans: lowSpans }, highStrokeData: { itemId: "high", spans: highSpans }, lowStrokeData: { itemId: "low", spans: lowSpans }, scales: this.calculateScaling(), visible: this.visible }; return context; } createLabelData({ datumIndex, point, value, itemId, inverted, datum, series }) { const { xKey, yLowKey, yHighKey, xName, yName, yLowName, yHighName, label } = this.properties; const { placement, padding = 10 } = label; let actualItemId = itemId; if (inverted) { actualItemId = itemId === "low" ? "high" : "low"; } const direction = placement === "outside" && actualItemId === "high" || placement === "inside" && actualItemId === "low" ? -1 : 1; return { x: point.x, y: point.y + padding * direction, series, itemId, datum, datumIndex, text: this.getLabelText(label, { value, datum, itemId, xKey, yLowKey, yHighKey, xName, yLowName, yHighName, yName }), textAlign: "center", textBaseline: direction === -1 ? "bottom" : "top" }; } isPathOrSelectionDirty() { return this.properties.marker.isDirty(); } updatePathNodes(opts) { const { opacity, visible, animationEnabled } = opts; const [fill, stroke22] = opts.paths; const strokeWidth = this.getStrokeWidth(this.properties.strokeWidth); stroke22.setProperties({ fill: void 0, lineCap: "round", lineJoin: "round", pointerEvents: PointerEvents11.None, stroke: this.properties.stroke, strokeWidth, strokeOpacity: this.properties.strokeOpacity, lineDash: this.properties.lineDash, lineDashOffset: this.properties.lineDashOffset, opacity, visible: visible || animationEnabled }); fill.setProperties({ stroke: void 0, lineJoin: "round", pointerEvents: PointerEvents11.None, fill: this.properties.fill, fillOpacity: this.properties.fillOpacity, lineDash: this.properties.lineDash, lineDashOffset: this.properties.lineDashOffset, strokeOpacity: this.properties.strokeOpacity, fillShadow: this.properties.shadow, strokeWidth, opacity, visible: visible || animationEnabled }); updateClipPath2(this, stroke22); updateClipPath2(this, fill); } updatePaths(opts) { this.updateAreaPaths(opts.paths, opts.contextData); } updateAreaPaths(paths, contextData) { for (const path of paths) { path.visible = contextData.visible; } if (contextData.visible) { this.updateFillPath(paths, contextData); this.updateStrokePath(paths, contextData); } else { for (const path of paths) { path.path.clear(); path.markDirty(); } } } updateFillPath(paths, contextData) { const [fill] = paths; fill.path.clear(); plotAreaPathFill2(fill, contextData.fillData); fill.markDirty(); } updateStrokePath(paths, contextData) { const [, stroke22] = paths; stroke22.path.clear(); plotLinePathStroke2(stroke22, contextData.highStrokeData.spans); plotLinePathStroke2(stroke22, contextData.lowStrokeData.spans); stroke22.markDirty(); } updateMarkerSelection(opts) { const { nodeData, markerSelection } = opts; if (this.properties.marker.isDirty()) { markerSelection.clear(); markerSelection.cleanup(); } return markerSelection.update(this.properties.marker.enabled ? nodeData : []); } getMarkerItemBaseStyle(highlighted) { const { properties } = this; const { marker } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { shape: marker.shape, size: marker.size, fill: highlightStyle?.fill ?? marker.fill, fillOpacity: highlightStyle?.fillOpacity ?? marker.fillOpacity, stroke: highlightStyle?.stroke ?? marker.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(marker.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? marker.strokeOpacity, lineDash: highlightStyle?.lineDash ?? marker.lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? marker.lineDashOffset }; } getMarkerItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yHighKey, yLowKey, marker } = properties; const { itemStyler } = marker; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId20(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, xKey, yHighKey, yLowKey, highlighted, ...format }); }); } updateMarkerNodes(opts) { const { markerSelection, isHighlight: highlighted } = opts; const { xKey, yLowKey, yHighKey, marker, fill, stroke: stroke22, strokeWidth, fillOpacity, strokeOpacity } = this.properties; const baseStyle = mergeDefaults5(highlighted && this.properties.highlightStyle.item, marker.getStyle(), { fill, fillOpacity, stroke: stroke22, strokeWidth, strokeOpacity }); markerSelection.each((node, datum) => { this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yHighKey, yLowKey }, baseStyle); }); if (!highlighted) { this.properties.marker.markClean(); } } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; return labelSelection.update(labelData, (text22) => { text22.pointerEvents = PointerEvents11.None; }); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode22(textNode, this.properties.label, datum); }); } getHighlightLabelData(labelData, highlightedItem) { const labelItems = labelData.filter((ld) => ld.datum === highlightedItem.datum); return labelItems.length > 0 ? labelItems : void 0; } getHighlightData(nodeData, highlightedItem) { const highlightItems = nodeData.filter((nodeDatum) => nodeDatum.datum === highlightedItem.datum); return highlightItems.length > 0 ? highlightItems : void 0; } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, axes, properties } = this; const { xName, yName, yLowKey, yLowName, xKey, yHighKey, yHighName, tooltip } = properties; const xAxis = axes[ChartAxisDirection31.X]; const yAxis = axes[ChartAxisDirection31.Y]; if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const yHighValue = dataModel.resolveColumnById(this, `yHighValue`, processedData)[datumIndex]; const yLowValue = dataModel.resolveColumnById(this, `yLowValue`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getMarkerItemBaseStyle(false); Object.assign(format, this.getMarkerItemStyleOverrides(String(datumIndex), datumIndex, format, false)); const value = `${yAxis.formatDatum(yLowValue)} - ${yAxis.formatDatum(yHighValue)}`; return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), symbol: this.legendItemSymbol(), data: [{ label: yName, fallbackLabel: `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`, value }] }, { seriesId, datum, title: yName, itemId: nodeDatum.itemId, xName, yName, yLowKey, yLowName, xKey, yHighKey, yHighName, ...format } ); } legendItemSymbol() { const { fill, stroke: stroke22, strokeWidth, strokeOpacity, lineDash, marker } = this.properties; return { marker: { shape: marker.shape, fill: marker.fill ?? fill, stroke: marker.stroke ?? stroke22, fillOpacity: marker.fillOpacity, strokeOpacity: marker.strokeOpacity, strokeWidth: marker.strokeWidth, lineDash: marker.lineDash, lineDashOffset: marker.lineDashOffset }, line: { stroke: stroke22, strokeOpacity, strokeWidth, lineDash } }; } getLegendData(legendType) { if (legendType !== "category") { return []; } const { id: seriesId, visible } = this; const { yLowKey, yHighKey, yName, yLowName, yHighName, showInLegend } = this.properties; const legendItemText = yName ?? `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`; const itemId = `${yLowKey}-${yHighKey}`; return [ { legendType: "category", id: seriesId, itemId, seriesId, enabled: visible, label: { text: `${legendItemText}` }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } isLabelEnabled() { return this.properties.label.enabled; } onDataChange() { } nodeFactory() { return new Group20(); } animateEmptyUpdateReady(animationData) { const { markerSelection, labelSelection, contextData, paths } = animationData; const { animationManager } = this.ctx; this.updateAreaPaths(paths, contextData); pathSwipeInAnimation2(this, animationManager, ...paths); resetMotion4([markerSelection], resetMarkerPositionFn2); markerSwipeScaleInAnimation2(this, animationManager, markerSelection); seriesLabelFadeInAnimation5(this, "labels", animationManager, labelSelection); } animateReadyResize(animationData) { const { contextData, paths } = animationData; this.updateAreaPaths(paths, contextData); super.animateReadyResize(animationData); } animateWaitingUpdateReady(animationData) { const { animationManager } = this.ctx; const { markerSelection, labelSelection, contextData, paths, previousContextData } = animationData; const [fill, stroke22] = paths; if (fill == null && stroke22 == null) return; this.resetMarkerAnimation(animationData); this.resetLabelAnimation(animationData); const update = () => { this.resetPathAnimation(animationData); this.updateAreaPaths(paths, contextData); }; const skip = () => { animationManager.skipCurrentBatch(); update(); }; if (contextData == null || previousContextData == null) { update(); markerFadeInAnimation22(this, animationManager, "added", markerSelection); pathFadeInAnimation2(this, "fill_path_properties", animationManager, "add", fill); pathFadeInAnimation2(this, "stroke_path_properties", animationManager, "add", stroke22); seriesLabelFadeInAnimation5(this, "labels", animationManager, labelSelection); return; } const fns = prepareRangeAreaPathAnimation( contextData, previousContextData, this.processedData?.reduced?.diff?.[this.id] ); if (fns === void 0) { skip(); return; } else if (fns.status === "no-op") { return; } fromToMotion4(this.id, "fill_path_properties", animationManager, [fill], fns.fill.pathProperties); fromToMotion4(this.id, "stroke_path_properties", animationManager, [stroke22], fns.stroke.pathProperties); if (fns.status === "added") { this.updateAreaPaths(paths, contextData); } else if (fns.status === "removed") { this.updateAreaPaths(paths, previousContextData); } else { pathMotion2(this.id, "fill_path_update", animationManager, [fill], fns.fill.path); pathMotion2(this.id, "stroke_path_update", animationManager, [stroke22], fns.stroke.path); } if (fns.hasMotion) { markerFadeInAnimation22(this, animationManager, void 0, markerSelection); seriesLabelFadeInAnimation5(this, "labels", animationManager, labelSelection); } this.ctx.animationManager.animate({ id: this.id, groupId: "reset_after_animation", phase: "trailing", from: {}, to: {}, onComplete: () => this.updateAreaPaths(paths, contextData) }); } getFormattedMarkerStyle(datum) { const { xKey, yLowKey, yHighKey } = this.properties; return this.getMarkerStyle(this.properties.marker, { datum, xKey, yLowKey, yHighKey, highlighted: true }); } computeFocusBounds(opts) { const hiBox = computeMarkerFocusBounds3(this, opts); const loBox = computeMarkerFocusBounds3(this, { ...opts, datumIndex: opts.datumIndex + 1 }); if (hiBox && loBox) { return BBox19.merge([hiBox, loBox]); } return void 0; } computeFocusDatumIndex(opts, nodeData) { const newOpts = { ...opts, datumIndex: opts.datumIndex + opts.datumIndexDelta, datumIndexDelta: opts.datumIndexDelta * 2 }; return super.computeFocusDatumIndex(newOpts, nodeData); } }; RangeAreaSeries.className = "RangeAreaSeries"; RangeAreaSeries.type = "range-area"; var import_ag_charts_community250 = (init_main4(), __toCommonJS(main_exports)); var RANGE_AREA_SERIES_THEME = { series: { fillOpacity: 0.7, nodeClickRange: "nearest", marker: { enabled: false, size: 6, strokeWidth: 2 }, label: { enabled: false, placement: "outside", padding: 10, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" } }, interpolation: { type: "linear", tension: 1, position: "end" } }, axes: { [import_ag_charts_community250._ModuleSupport.ThemeConstants.CARTESIAN_AXIS_TYPE.NUMBER]: { crosshair: { enabled: true } } } }; var { markerPaletteFactory: markerPaletteFactory22, ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE10, CARTESIAN_POSITION: CARTESIAN_POSITION6 } } = import_ag_charts_community251._ModuleSupport; var RangeAreaModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "range-area", moduleFactory: (ctx) => new RangeAreaSeries(ctx), tooltipDefaults: { range: "nearest" }, defaultAxes: [ { type: CARTESIAN_AXIS_TYPE10.NUMBER, position: CARTESIAN_POSITION6.LEFT }, { type: CARTESIAN_AXIS_TYPE10.CATEGORY, position: CARTESIAN_POSITION6.BOTTOM } ], themeTemplate: RANGE_AREA_SERIES_THEME, paletteFactory: (params) => { const { marker } = markerPaletteFactory22(params); return { fill: marker.fill, stroke: marker.stroke, marker }; } }; var import_ag_charts_community255 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community253 = (init_main4(), __toCommonJS(main_exports)); var AGGREGATION_THRESHOLD5 = 1e3; var PRECISION2 = 5; function aggregateRangeBarData(xValues, highValues, lowValues, domain) { if (xValues.length < AGGREGATION_THRESHOLD5) return; const [d0, d1] = aggregationDomain(domain); let maxRange = maxRangeFittingPoints(xValues, PRECISION2); let { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, maxRange); const filters = [{ maxRange, indexData }]; while (maxRange > 64) { ({ indexData, valueData, maxRange } = compactAggregationIndices(indexData, valueData, maxRange)); filters.push({ maxRange, indexData }); } filters.reverse(); return filters; } var import_ag_charts_community252 = (init_main4(), __toCommonJS(main_exports)); var { AbstractBarSeriesProperties: AbstractBarSeriesProperties5, SeriesTooltip: SeriesTooltip20, Validate: Validate83, COLOR_STRING: COLOR_STRING27, FUNCTION: FUNCTION20, LINE_DASH: LINE_DASH23, OBJECT: OBJECT43, PLACEMENT: PLACEMENT22, POSITIVE_NUMBER: POSITIVE_NUMBER35, RATIO: RATIO33, STRING: STRING40, BOOLEAN: BOOLEAN34, DropShadow: DropShadow4, Label: Label15 } = import_ag_charts_community252._ModuleSupport; var RangeBarSeriesLabel = class extends Label15 { constructor() { super(...arguments); this.placement = "inside"; this.padding = 6; } }; __decorateClass2([ Validate83(PLACEMENT22) ], RangeBarSeriesLabel.prototype, "placement", 2); __decorateClass2([ Validate83(POSITIVE_NUMBER35) ], RangeBarSeriesLabel.prototype, "padding", 2); var RangeBarProperties = class extends AbstractBarSeriesProperties5 { constructor() { super(...arguments); this.fill = "#99CCFF"; this.fillOpacity = 1; this.stroke = "#99CCFF"; this.strokeWidth = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.cornerRadius = 0; this.shadow = new DropShadow4().set({ enabled: false }); this.label = new RangeBarSeriesLabel(); this.tooltip = new SeriesTooltip20(); this.fastDataProcessing = false; } }; __decorateClass2([ Validate83(STRING40) ], RangeBarProperties.prototype, "xKey", 2); __decorateClass2([ Validate83(STRING40) ], RangeBarProperties.prototype, "yLowKey", 2); __decorateClass2([ Validate83(STRING40) ], RangeBarProperties.prototype, "yHighKey", 2); __decorateClass2([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "xName", 2); __decorateClass2([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "yName", 2); __decorateClass2([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "yLowName", 2); __decorateClass2([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "yHighName", 2); __decorateClass2([ Validate83(COLOR_STRING27) ], RangeBarProperties.prototype, "fill", 2); __decorateClass2([ Validate83(RATIO33) ], RangeBarProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate83(COLOR_STRING27) ], RangeBarProperties.prototype, "stroke", 2); __decorateClass2([ Validate83(POSITIVE_NUMBER35) ], RangeBarProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate83(RATIO33) ], RangeBarProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate83(LINE_DASH23) ], RangeBarProperties.prototype, "lineDash", 2); __decorateClass2([ Validate83(POSITIVE_NUMBER35) ], RangeBarProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate83(POSITIVE_NUMBER35) ], RangeBarProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate83(FUNCTION20, { optional: true }) ], RangeBarProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate83(OBJECT43) ], RangeBarProperties.prototype, "shadow", 2); __decorateClass2([ Validate83(OBJECT43) ], RangeBarProperties.prototype, "label", 2); __decorateClass2([ Validate83(OBJECT43) ], RangeBarProperties.prototype, "tooltip", 2); __decorateClass2([ Validate83(BOOLEAN34) ], RangeBarProperties.prototype, "fastDataProcessing", 2); var { SeriesNodePickMode: SeriesNodePickMode16, valueProperty: valueProperty17, keyProperty: keyProperty9, ChartAxisDirection: ChartAxisDirection32, checkCrisp: checkCrisp22, updateLabelNode: updateLabelNode3, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL4, LARGEST_KEY_INTERVAL: LARGEST_KEY_INTERVAL22, diff: diff7, prepareBarAnimationFunctions: prepareBarAnimationFunctions22, midpointStartingBarPosition: midpointStartingBarPosition22, resetBarSelectionsFn: resetBarSelectionsFn22, fixNumericExtent: fixNumericExtent9, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation6, resetLabelFn: resetLabelFn5, animationValidation: animationValidation8, computeBarFocusBounds: computeBarFocusBounds5, visibleRangeIndices: visibleRangeIndices22, createDatumId: createDatumId21, ContinuousScale: ContinuousScale8, OrdinalTimeScale: OrdinalTimeScale6, Rect: Rect7, PointerEvents: PointerEvents12, motion: motion9, applyShapeStyle: applyShapeStyle10, findMinMax: findMinMax4 } = import_ag_charts_community253._ModuleSupport; var RangeBarSeriesNodeEvent = class extends import_ag_charts_community253._ModuleSupport.SeriesNodeEvent { constructor(type, nativeEvent, datum, series) { super(type, nativeEvent, datum, series); this.xKey = series.properties.xKey; this.yLowKey = series.properties.yLowKey; this.yHighKey = series.properties.yHighKey; } }; var RangeBarSeries = class extends import_ag_charts_community253._ModuleSupport.AbstractBarSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [SeriesNodePickMode16.AXIS_ALIGNED, SeriesNodePickMode16.EXACT_SHAPE_MATCH], hasHighlightedLabels: true, directionKeys: { x: ["xKey"], y: ["yLowKey", "yHighKey"] }, directionNames: { x: ["xName"], y: ["yLowName", "yHighName", "yName"] }, datumSelectionGarbageCollection: false, animationResetFns: { datum: resetBarSelectionsFn22, label: resetLabelFn5 } }); this.properties = new RangeBarProperties(); this.dataAggregationFilters = void 0; this.NodeEvent = RangeBarSeriesNodeEvent; } async processData(dataController) { if (!this.properties.isValid()) { return; } const { xKey, yLowKey, yHighKey, fastDataProcessing } = this.properties; const grouped = !fastDataProcessing; const xScale = this.getCategoryAxis()?.scale; const yScale = this.getValueAxis()?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const extraProps = []; if (!this.ctx.animationManager.isSkipped()) { if (this.processedData) { extraProps.push(diff7(this.id, this.processedData)); } extraProps.push(animationValidation8()); } const visibleProps = this.visible ? {} : { forceValue: 0 }; const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, { props: [ keyProperty9(xKey, xScaleType, { id: "xValue" }), valueProperty17(yLowKey, yScaleType, { id: `yLowValue`, invalidValue: null, ...visibleProps }), valueProperty17(yHighKey, yScaleType, { id: `yHighValue`, invalidValue: null, ...visibleProps }), ...isContinuousX ? [SMALLEST_KEY_INTERVAL4, LARGEST_KEY_INTERVAL22] : [], ...extraProps ], groupByKeys: grouped }); this.smallestDataInterval = processedData.reduced?.smallestKeyInterval; this.largestDataInterval = processedData.reduced?.largestKeyInterval; this.dataAggregationFilters = this.aggregateData(dataModel, processedData); this.animationState.transition("updateData"); } aggregateData(dataModel, processedData) { if (processedData.type !== "grouped") return; const xAxis = this.axes[ChartAxisDirection32.X]; if (xAxis == null || !(ContinuousScale8.is(xAxis.scale) || OrdinalTimeScale6.is(xAxis.scale))) return; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const yHighValues = dataModel.resolveColumnById(this, `yHighValue`, processedData); const yLowValues = dataModel.resolveColumnById(this, `yLowValue`, processedData); const { index } = dataModel.resolveProcessedDataDefById(this, `xValue`); const domain = processedData.domain.keys[index]; return aggregateRangeBarData(xValues, yHighValues, yLowValues, domain); } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (!processedData || !dataModel) return []; const { keys: [keys] } = processedData.domain; if (direction === this.getCategoryDirection()) { const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`); if (keyDef?.def.type === "key" && keyDef?.def.valueType === "category") { return keys; } return this.padBandExtent(keys); } else { const yExtent = this.domainForClippedRange( ChartAxisDirection32.Y, ["yHighValue", "yLowValue"], "xValue", true ); const fixedYExtent = findMinMax4(yExtent); return fixNumericExtent9(fixedYExtent); } } getSeriesRange(_direction, visibleRange) { return this.domainForVisibleRange( ChartAxisDirection32.Y, ["yHighValue", "yLowValue"], "xValue", visibleRange, true ); } createNodeData() { const { data, dataModel, groupScale, processedData, visible } = this; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!(data && xAxis && yAxis && dataModel && processedData?.dataSources)) return; const xScale = xAxis.scale; const yScale = yAxis.scale; const barAlongX = this.getBarDirection() === ChartAxisDirection32.X; const { xKey, yLowKey, yHighKey, strokeWidth } = this.properties; const itemId = `${yLowKey}-${yHighKey}`; const context = { itemId, nodeData: [], labelData: [], scales: this.calculateScaling(), visible: this.visible }; if (!visible) return context; const rawData = processedData.dataSources.get(this.id) ?? []; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const yLowValues = dataModel.resolveColumnById(this, `yLowValue`, processedData); const yHighValues = dataModel.resolveColumnById(this, `yHighValue`, processedData); const { barWidth: effectiveBarWidth, groupIndex } = this.updateGroupScale(xAxis); const barOffset = ContinuousScale8.is(xScale) ? effectiveBarWidth * -0.5 : 0; const groupOffset = groupScale.convert(String(groupIndex)); const defaultCrisp = checkCrisp22( xAxis?.scale, xAxis?.visibleRange, this.smallestDataInterval, this.largestDataInterval ); const xPosition = (datumIndex) => Math.round(xScale.convert(xValues[datumIndex])) + groupOffset + barOffset; const handleDatum = (datumIndex, groupedDataIndex, x, width2, yLow, yHigh, crisp) => { const datum = rawData[datumIndex]; const xDatum = xValues[datumIndex]; if (xDatum == null) return; const rawLowValue = yLowValues[datumIndex]; const rawHighValue = yHighValues[datumIndex]; if (!Number.isFinite(rawLowValue?.valueOf()) || !Number.isFinite(rawHighValue?.valueOf())) return; const [yLowValue, yHighValue] = rawLowValue < rawHighValue ? [rawLowValue, rawHighValue] : [rawHighValue, rawLowValue]; const y = Math.round(yScale.convert(yHigh)); const bottomY = Math.round(yScale.convert(yLow)); const height2 = Math.max(strokeWidth, Math.abs(bottomY - y)); const rect = { x: barAlongX ? Math.min(y, bottomY) : x, y: barAlongX ? x : Math.min(y, bottomY), width: barAlongX ? height2 : width2, height: barAlongX ? width2 : height2 }; const nodeMidPoint = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }; const labelData = this.createLabelData({ datumIndex, rect, barAlongX, yLowValue, yHighValue, datum, series: this }); const nodeDatum = { index: groupedDataIndex, valueIndex: datumIndex, series: this, itemId, datum, datumIndex, xValue: xDatum, yLowValue: rawLowValue, yHighValue: rawHighValue, yLowKey, yHighKey, xKey, x: rect.x, y: rect.y, width: rect.width, height: rect.height, midPoint: nodeMidPoint, crisp, labels: labelData }; context.nodeData.push(nodeDatum); context.labelData.push(...labelData); }; const { dataAggregationFilters } = this; const [r0, r1] = xScale.range; const range22 = r1 - r0; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range22); if (dataAggregationFilter != null) { const { maxRange, indexData } = dataAggregationFilter; const [start2, end2] = visibleRangeIndices22(maxRange, xAxis.range, (index) => { const aggIndex = index * SPAN3; const xMinIndex = indexData[aggIndex + X_MIN2]; const xMaxIndex = indexData[aggIndex + X_MAX2]; if (xMinIndex === -1) return; const midDatumIndex = (xMinIndex + xMaxIndex) / 2 | 0; return [xPosition(midDatumIndex), xPosition(xMaxIndex) + effectiveBarWidth]; }); for (let i = start2; i < end2; i += 1) { const aggIndex = i * SPAN3; const xMinIndex = indexData[aggIndex + X_MIN2]; const xMaxIndex = indexData[aggIndex + X_MAX2]; const yMinIndex = indexData[aggIndex + Y_MIN2]; const yMaxIndex = indexData[aggIndex + Y_MAX2]; if (xMinIndex === -1) continue; const midDatumIndex = (xMinIndex + xMaxIndex) / 2 | 0; const xValue = xValues[midDatumIndex]; if (xValue == null) continue; const x = xPosition(midDatumIndex); const width2 = Math.abs(xPosition(xMinIndex) - xPosition(xMaxIndex)) + effectiveBarWidth; const yLow = yLowValues[yMinIndex]; const yHigh = yHighValues[yMaxIndex]; handleDatum(midDatumIndex, 0, x, width2, yLow, yHigh, false); } } else if (processedData.type === "ungrouped") { let [start2, end2] = visibleRangeIndices22(rawData.length, xAxis.range, (index) => { const x = xPosition(index); return [x, effectiveBarWidth]; }); if (processedData.input.count < 1e3) { start2 = 0; end2 = processedData.input.count; } for (let datumIndex = start2; datumIndex < end2; datumIndex += 1) { const x = xPosition(datumIndex); const width2 = effectiveBarWidth; const yLow = yLowValues[datumIndex]; const yHigh = yHighValues[datumIndex]; handleDatum(datumIndex, 0, x, width2, yLow, yHigh, defaultCrisp); } } else { for (const { datumIndex, groupIndex: groupDataIndex } of dataModel.forEachGroupDatum(this, processedData)) { const x = xPosition(datumIndex); const width2 = effectiveBarWidth; const yLow = yLowValues[datumIndex]; const yHigh = yHighValues[datumIndex]; handleDatum(datumIndex, groupDataIndex, x, width2, yLow, yHigh, defaultCrisp); } } return context; } createLabelData({ datumIndex, rect, barAlongX, yLowValue, yHighValue, datum, series }) { const { xKey, yLowKey, yHighKey, xName, yLowName, yHighName, yName, label } = this.properties; const labelParams = { datum, xKey, yLowKey, yHighKey, xName, yLowName, yHighName, yName }; const { placement, padding } = label; const paddingDirection = placement === "outside" ? 1 : -1; const labelPadding = padding * paddingDirection; const yLowLabel = { datumIndex, x: rect.x + (barAlongX ? -labelPadding : rect.width / 2), y: rect.y + (barAlongX ? rect.height / 2 : rect.height + labelPadding), textAlign: barAlongX ? "left" : "center", textBaseline: barAlongX ? "middle" : "bottom", text: this.getLabelText(label, { itemId: "low", value: yLowValue, ...labelParams }), itemId: "low", datum, series }; const yHighLabel = { datumIndex, x: rect.x + (barAlongX ? rect.width + labelPadding : rect.width / 2), y: rect.y + (barAlongX ? rect.height / 2 : -labelPadding), textAlign: barAlongX ? "right" : "center", textBaseline: barAlongX ? "middle" : "top", text: this.getLabelText(label, { itemId: "high", value: yHighValue, ...labelParams }), itemId: "high", datum, series }; if (placement === "outside") { yLowLabel.textAlign = barAlongX ? "right" : "center"; yLowLabel.textBaseline = barAlongX ? "middle" : "top"; yHighLabel.textAlign = barAlongX ? "left" : "center"; yHighLabel.textBaseline = barAlongX ? "middle" : "bottom"; } return [yLowLabel, yHighLabel]; } nodeFactory() { return new Rect7(); } updateDatumSelection(opts) { const { nodeData, datumSelection } = opts; const data = nodeData ?? []; return datumSelection.update(data, void 0, (datum) => this.getDatumId(datum)); } getItemBaseStyle(highlighted) { const { properties } = this; const { cornerRadius } = properties; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? properties.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke ?? properties.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity, lineDash: highlightStyle?.lineDash ?? properties.lineDash ?? [], lineDashOffset: highlightStyle?.lineDashOffset ?? properties.lineDashOffset, cornerRadius }; } getItemStyleOverrides(datumId, datum, format, highlighted) { const { id: seriesId, properties } = this; const { xKey, yHighKey, yLowKey, itemStyler } = properties; if (itemStyler == null) return; return this.cachedDatumCallback(createDatumId21(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, xKey, yHighKey, yLowKey, highlighted, ...format }); }); } updateDatumNodes(opts) { const { datumSelection, isHighlight } = opts; const categoryAlongX = this.getCategoryDirection() === ChartAxisDirection32.X; const style = this.getItemBaseStyle(isHighlight); datumSelection.each((rect, datum) => { const overrides = this.getItemStyleOverrides(String(datum.datumIndex), datum.datum, style, isHighlight); applyShapeStyle10(rect, style, overrides); rect.cornerRadius = overrides?.cornerRadius ?? style.cornerRadius; rect.visible = categoryAlongX ? datum.width > 0 : datum.height > 0; rect.crisp = datum.crisp; }); } getHighlightLabelData(labelData, highlightedItem) { const labelItems = labelData.filter((ld) => ld.datum === highlightedItem.datum); return labelItems.length > 0 ? labelItems : void 0; } updateLabelSelection(opts) { const labelData = this.properties.label.enabled ? opts.labelData : []; return opts.labelSelection.update(labelData, (text22) => { text22.pointerEvents = PointerEvents12.None; }); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode3(textNode, this.properties.label, datum); }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { xKey, xName, yName, yLowKey, yHighKey, yLowName, yHighName, tooltip } = properties; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis) { return; } const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const yHighValue = dataModel.resolveColumnById(this, `yHighValue`, processedData)[datumIndex]; const yLowValue = dataModel.resolveColumnById(this, `yLowValue`, processedData)[datumIndex]; if (xValue == null) return; const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(String(datumIndex), datum, format, false)); const value = `${yAxis.formatDatum(yLowValue)} - ${yAxis.formatDatum(yHighValue)}`; return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), symbol: this.legendItemSymbol(), data: [{ label: yName, fallbackLabel: `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`, value }] }, { seriesId, datum, title: yName, xKey, xName, yName, yLowKey, yHighKey, yLowName, yHighName, ...format } ); } legendItemSymbol() { const { fill, stroke: stroke22, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { marker: { fill, stroke: stroke22, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (legendType !== "category") { return []; } const { id: seriesId, visible } = this; const { yName, yLowName, yHighName, yLowKey, yHighKey, showInLegend } = this.properties; const legendItemText = yName ?? `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`; const itemId = `${yLowKey}-${yHighKey}`; return [ { legendType: "category", id: seriesId, itemId, seriesId, enabled: visible, label: { text: `${legendItemText}` }, symbol: this.legendItemSymbol(), hideInLegend: !showInLegend } ]; } animateEmptyUpdateReady({ datumSelection, labelSelection }) { const fns = prepareBarAnimationFunctions22(midpointStartingBarPosition22(this.isVertical(), "normal")); motion9.fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], fns); seriesLabelFadeInAnimation6(this, "labels", this.ctx.animationManager, labelSelection); } animateWaitingUpdateReady(data) { const { datumSelection: datumSelections, labelSelection: labelSelections } = data; const { processedData } = this; const dataDiff = processedData?.reduced?.diff?.[this.id]; this.ctx.animationManager.stopByAnimationGroupId(this.id); const fns = prepareBarAnimationFunctions22(midpointStartingBarPosition22(this.isVertical(), "fade")); motion9.fromToMotion( this.id, "datums", this.ctx.animationManager, [datumSelections], fns, (_, datum) => this.getDatumId(datum), dataDiff ); seriesLabelFadeInAnimation6(this, "labels", this.ctx.animationManager, labelSelections); } getDatumId(datum) { return `${datum.xValue}-${datum.valueIndex}`; } isLabelEnabled() { return this.properties.label.enabled; } onDataChange() { } computeFocusBounds({ datumIndex }) { return computeBarFocusBounds5(this, this.contextNodeData?.nodeData[datumIndex]); } }; RangeBarSeries.className = "RangeBarSeries"; RangeBarSeries.type = "range-bar"; var import_ag_charts_community254 = (init_main4(), __toCommonJS(main_exports)); var RANGE_BAR_SERIES_THEME = { series: { direction: "vertical", strokeWidth: 0, label: { enabled: false, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" }, placement: "inside" } }, axes: { [import_ag_charts_community254._ModuleSupport.ThemeConstants.CARTESIAN_AXIS_TYPE.NUMBER]: { crosshair: { enabled: true } } } }; var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE11, CARTESIAN_POSITION: CARTESIAN_POSITION7 } = import_ag_charts_community255._ModuleSupport.ThemeConstants; var RangeBarModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "range-bar", moduleFactory: (ctx) => new RangeBarSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: import_ag_charts_community255._ModuleSupport.swapAxisCondition( [ { type: CARTESIAN_AXIS_TYPE11.NUMBER, position: CARTESIAN_POSITION7.LEFT }, { type: CARTESIAN_AXIS_TYPE11.CATEGORY, position: CARTESIAN_POSITION7.BOTTOM } ], (series) => series?.direction === "horizontal" ), themeTemplate: RANGE_BAR_SERIES_THEME, paletteFactory: ({ takeColors }) => { const { fills: [fill], strokes: [stroke22] } = takeColors(1); return { fill, stroke: stroke22 }; }, groupable: true }; var import_ag_charts_community259 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community258 = (init_main4(), __toCommonJS(main_exports)); function sortNodesByY(column) { column.nodes.sort((a, b) => Math.round((a.datum.y - b.datum.y) * 100) / 100 || -(a.datum.size - b.datum.size)); } function justifyNodesAcrossColumn({ nodes, size }, { seriesRectHeight, nodeSpacing, sizeScale }) { const nodesHeight = seriesRectHeight * size * sizeScale; let y = (seriesRectHeight - (nodesHeight + nodeSpacing * (nodes.length - 1))) / 2; nodes.forEach(({ datum: node }) => { const height2 = seriesRectHeight * node.size * sizeScale; node.y = y; node.height = height2; y += height2 + nodeSpacing; }); } function separateNodesInColumn(column, layout) { const { nodes } = column; const { seriesRectHeight, nodeSpacing } = layout; sortNodesByY(column); let totalShift = 0; let currentTop = 0; for (const { datum: node } of nodes) { const shift = Math.max(currentTop - node.y, 0); node.y += shift; totalShift += shift; currentTop = node.y + node.height + nodeSpacing; } const lastNodeBottom = currentTop - nodeSpacing; if (lastNodeBottom < seriesRectHeight) { return totalShift > 0; } let currentBottom = seriesRectHeight; for (let i = nodes.length - 1; i >= 0; i -= 1) { const { datum: node } = nodes[i]; const nodeBottom = node.y + node.height; const shift = Math.min(currentBottom - nodeBottom, 0); node.y += shift; totalShift += shift; currentBottom = node.y - nodeSpacing; } return true; } function hasCrossOver(x00, y00, x01, y01, x10, y10, x11, y11) { const recM0 = (x01 - x00) / (y01 - y00); const recM1 = (x11 - x10) / (y11 - y10); const x = ((y10 - y00) * (recM0 * recM1) + x00 * recM1 - x10 * recM0) / (recM1 - recM0); if (x00 < x01) { return x > x00 && x < Math.min(x01, x11); } else { return x < x00 && x > Math.max(x01, x11); } } function removeColumnCrossoversInDirection(column, getLinks) { let didShift = false; const singleCrossoverColumns = column.nodes.filter((node) => getLinks(node).length === 1); let didRemoveCrossover = true; for (let runs = 0; didRemoveCrossover && runs < singleCrossoverColumns.length; runs += 1) { didRemoveCrossover = false; for (let i = 0; i < singleCrossoverColumns.length - 1; i += 1) { const { datum: node } = singleCrossoverColumns[i]; const nodeAfter = getLinks(singleCrossoverColumns[i])[0].node.datum; const { datum: otherNode } = singleCrossoverColumns[i + 1]; const otherNodeAfter = getLinks(singleCrossoverColumns[i + 1])[0].node.datum; const crossover = hasCrossOver( node.x, node.y, nodeAfter.x, nodeAfter.y, otherNode.x, otherNode.y, otherNodeAfter.x, otherNodeAfter.y ) || hasCrossOver( node.x, node.y + node.height / 2, nodeAfter.x, nodeAfter.y + nodeAfter.height / 2, otherNode.x, otherNode.y + otherNode.height / 2, otherNodeAfter.x, otherNodeAfter.y + otherNodeAfter.height / 2 ) || hasCrossOver( node.x, node.y + node.height, nodeAfter.x, nodeAfter.y + nodeAfter.height, otherNode.x, otherNode.y + otherNode.height, otherNodeAfter.x, otherNodeAfter.y + otherNodeAfter.height ); if (!crossover) continue; const current = singleCrossoverColumns[i]; singleCrossoverColumns[i] = singleCrossoverColumns[i + 1]; singleCrossoverColumns[i + 1] = current; const y = node.y; node.y = otherNode.y + otherNode.height - node.height; otherNode.y = y; didShift = true; didRemoveCrossover = true; } } return didShift; } function removeColumnCrossovers(column) { let didShift = false; sortNodesByY(column); didShift = removeColumnCrossoversInDirection(column, (node) => node.linksBefore) || didShift; didShift = removeColumnCrossoversInDirection(column, (node) => node.linksAfter) || didShift; return didShift; } function weightedNodeY(links) { if (links.length === 0) return; let totalYValues = 0; let totalSize = 0; for (const { node: { datum: node } } of links) { totalYValues += node.y * node.size; totalSize += node.size; } return totalYValues / totalSize; } function layoutColumn(column, layout, weight, direction) { column.nodes.forEach(({ datum: node, linksBefore, linksAfter }) => { const forwardLinks = direction === 1 ? linksBefore : linksAfter; const backwardsLinks = direction === 1 ? linksAfter : linksBefore; const nextY = weightedNodeY(forwardLinks); if (nextY != null) { const nodeWeight = backwardsLinks.length !== 0 ? weight : 1; node.y = node.y + (nextY - node.y) * nodeWeight; } }); return separateNodesInColumn(column, layout); } function layoutColumnsForward(columns, layout, weight) { let didShift = false; for (const column of columns) { didShift = layoutColumn(column, layout, weight, 1) || didShift; } return didShift; } function layoutColumnsBackwards(columns, layout, weight) { let didShift = false; for (let i = columns.length - 1; i >= 0; i -= 1) { didShift = layoutColumn(columns[i], layout, weight, -1) || didShift; } return didShift; } function removeColumnsCrossovers(columns) { let didShift = false; for (let i = columns.length - 1; i >= 0; i -= 1) { didShift = removeColumnCrossovers(columns[i]) || didShift; } return didShift; } function layoutColumns(columns, layout) { columns.forEach((column) => { justifyNodesAcrossColumn(column, layout); }); let didLayoutColumnsBackwards = false; for (let i = 0; i < 6; i += 1) { const didLayoutColumnsForward = layoutColumnsForward(columns, layout, 1); didLayoutColumnsBackwards = layoutColumnsBackwards(columns, layout, 0.5); const didRemoveColumnCrossovers = removeColumnsCrossovers(columns); if (!didLayoutColumnsForward && !didLayoutColumnsBackwards && !didRemoveColumnCrossovers) { break; } } if (didLayoutColumnsBackwards) { layoutColumnsForward(columns, layout, 1); removeColumnsCrossovers(columns); } } var import_ag_charts_community256 = (init_main4(), __toCommonJS(main_exports)); var { BBox: BBox20, Path: Path13, ScenePathChangeDetection: ScenePathChangeDetection9, splitBezier: splitBezier2 } = import_ag_charts_community256._ModuleSupport; function offsetTrivialCubicBezier(path, p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, offset4) { let tx, ty; if (p1y !== p0y && p3y !== p2y) { const slope1 = -(p1x - p0x) / (p1y - p0y); const slope2 = -(p3x - p2x) / (p3y - p2y); tx = (p2y - p0y + slope1 * p0x - slope2 * p2x) / (slope1 - slope2); ty = slope1 * (tx - p0x) + p0y; } else if (p1y === p0y && p3y !== p2y) { tx = p0x; const slope2 = -(p3x - p2x) / (p3y - p2y); ty = slope2 * (tx - p3x) + p3y; } else if (p1y !== p0y && p3y === p2y) { tx = p3x; const slope1 = -(p1x - p0x) / (p1y - p0y); ty = slope1 * (tx - p0x) + p0y; } else { throw new Error("Offsetting flat bezier curve"); } const d0 = Math.hypot(p0y - ty, p0x - tx); const s0 = (d0 + offset4) / d0; const d1 = Math.hypot(p3y - ty, p3x - tx); const s1 = (d1 + offset4) / d1; const q1x = tx + (p1x - tx) * s0; const q1y = ty + (p1y - ty) * s0; const q2x = tx + (p2x - tx) * s1; const q2y = ty + (p2y - ty) * s1; const q3x = tx + (p3x - tx) * s1; const q3y = ty + (p3y - ty) * s1; path.cubicCurveTo(q1x, q1y, q2x, q2y, q3x, q3y); } var SankeyLink = class extends Path13 { constructor() { super(...arguments); this.x1 = 0; this.x2 = 0; this.y1 = 0; this.y2 = 0; this.height = 0; this.inset = 0; } computeBBox() { const x = Math.min(this.x1, this.x2); const width2 = Math.max(this.x1, this.x2) - x; const y = Math.min(this.y1, this.y2); const height2 = Math.max(this.y1, this.y2) - y + this.height; return new BBox20(x, y, width2, height2); } updatePath() { const { path, inset } = this; path.clear(); const x1 = this.x1 + inset; const x2 = this.x2 - inset; const y1 = this.y1 + inset; const y2 = this.y2 + inset; const height2 = this.height - 2 * inset; if (height2 < 0 || x1 > x2) return; const p0x = x1; const p0y = y1 + height2 / 2; const p1x = (x1 + x2) / 2; const p1y = y1 + height2 / 2; const p2x = (x1 + x2) / 2; const p2y = y2 + height2 / 2; const p3x = x2; const p3y = y2 + height2 / 2; path.moveTo(p0x, p0y - height2 / 2); if (Math.abs(this.y2 - this.y1) < 1 || this.x2 - this.x1 < this.height * Math.SQRT2) { path.cubicCurveTo(p1x, p1y - height2 / 2, p2x, p2y - height2 / 2, p3x, p3y - height2 / 2); path.lineTo(p3x, p3y + height2 / 2); path.cubicCurveTo(p2x, p2y + height2 / 2, p1x, p1y + height2 / 2, p0x, p0y + height2 / 2); } else { const [a, b] = splitBezier2(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, 0.5); const offset4 = (y2 > y1 ? 1 : -1) * height2 / 2; offsetTrivialCubicBezier(path, a[0].x, a[0].y, a[1].x, a[1].y, a[2].x, a[2].y, a[3].x, a[3].y, offset4); offsetTrivialCubicBezier(path, b[0].x, b[0].y, b[1].x, b[1].y, b[2].x, b[2].y, b[3].x, b[3].y, -offset4); path.lineTo(p3x, p3y + height2 / 2); offsetTrivialCubicBezier(path, b[3].x, b[3].y, b[2].x, b[2].y, b[1].x, b[1].y, b[0].x, b[0].y, offset4); offsetTrivialCubicBezier(path, a[3].x, a[3].y, a[2].x, a[2].y, a[1].x, a[1].y, a[0].x, a[0].y, -offset4); } path.closePath(); } }; __decorateClass2([ ScenePathChangeDetection9() ], SankeyLink.prototype, "x1", 2); __decorateClass2([ ScenePathChangeDetection9() ], SankeyLink.prototype, "x2", 2); __decorateClass2([ ScenePathChangeDetection9() ], SankeyLink.prototype, "y1", 2); __decorateClass2([ ScenePathChangeDetection9() ], SankeyLink.prototype, "y2", 2); __decorateClass2([ ScenePathChangeDetection9() ], SankeyLink.prototype, "height", 2); __decorateClass2([ ScenePathChangeDetection9() ], SankeyLink.prototype, "inset", 2); var import_ag_charts_community257 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties27, SeriesTooltip: SeriesTooltip21, SeriesProperties: SeriesProperties13, ARRAY: ARRAY12, COLOR_STRING: COLOR_STRING28, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY12, FUNCTION: FUNCTION21, LINE_DASH: LINE_DASH24, OBJECT: OBJECT44, POSITIVE_NUMBER: POSITIVE_NUMBER36, RATIO: RATIO34, STRING: STRING41, UNION: UNION17, Validate: Validate84, Label: Label16 } = import_ag_charts_community257._ModuleSupport; var ALIGNMENT = UNION17(["left", "right", "center", "justify"], "a justification value"); var SankeySeriesLabelProperties = class extends Label16 { constructor() { super(...arguments); this.spacing = 1; } }; __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesLabelProperties.prototype, "spacing", 2); var SankeySeriesLinkProperties = class extends BaseProperties27 { constructor() { super(...arguments); this.fill = void 0; this.fillOpacity = 1; this.stroke = void 0; this.strokeOpacity = 1; this.strokeWidth = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesLinkProperties.prototype, "fill", 2); __decorateClass2([ Validate84(RATIO34) ], SankeySeriesLinkProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesLinkProperties.prototype, "stroke", 2); __decorateClass2([ Validate84(RATIO34) ], SankeySeriesLinkProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesLinkProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate84(LINE_DASH24) ], SankeySeriesLinkProperties.prototype, "lineDash", 2); __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesLinkProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate84(FUNCTION21, { optional: true }) ], SankeySeriesLinkProperties.prototype, "itemStyler", 2); var SankeySeriesNodeProperties = class extends BaseProperties27 { constructor() { super(...arguments); this.spacing = 1; this.width = 1; this.alignment = "justify"; this.fill = void 0; this.fillOpacity = 1; this.stroke = void 0; this.strokeOpacity = 1; this.strokeWidth = 1; this.lineDash = [0]; this.lineDashOffset = 0; } }; __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "spacing", 2); __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "width", 2); __decorateClass2([ Validate84(ALIGNMENT) ], SankeySeriesNodeProperties.prototype, "alignment", 2); __decorateClass2([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesNodeProperties.prototype, "fill", 2); __decorateClass2([ Validate84(RATIO34) ], SankeySeriesNodeProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesNodeProperties.prototype, "stroke", 2); __decorateClass2([ Validate84(RATIO34) ], SankeySeriesNodeProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate84(LINE_DASH24) ], SankeySeriesNodeProperties.prototype, "lineDash", 2); __decorateClass2([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "lineDashOffset", 2); __decorateClass2([ Validate84(FUNCTION21, { optional: true }) ], SankeySeriesNodeProperties.prototype, "itemStyler", 2); var SankeySeriesProperties = class extends SeriesProperties13 { constructor() { super(...arguments); this.nodes = void 0; this.idKey = ""; this.idName = void 0; this.labelKey = void 0; this.labelName = void 0; this.sizeKey = void 0; this.sizeName = void 0; this.fills = []; this.strokes = []; this.label = new SankeySeriesLabelProperties(); this.link = new SankeySeriesLinkProperties(); this.node = new SankeySeriesNodeProperties(); this.tooltip = new SeriesTooltip21(); } }; __decorateClass2([ Validate84(ARRAY12, { optional: true }) ], SankeySeriesProperties.prototype, "nodes", 2); __decorateClass2([ Validate84(STRING41) ], SankeySeriesProperties.prototype, "fromKey", 2); __decorateClass2([ Validate84(STRING41) ], SankeySeriesProperties.prototype, "toKey", 2); __decorateClass2([ Validate84(STRING41) ], SankeySeriesProperties.prototype, "idKey", 2); __decorateClass2([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "idName", 2); __decorateClass2([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "labelName", 2); __decorateClass2([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "sizeKey", 2); __decorateClass2([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "sizeName", 2); __decorateClass2([ Validate84(COLOR_STRING_ARRAY12) ], SankeySeriesProperties.prototype, "fills", 2); __decorateClass2([ Validate84(COLOR_STRING_ARRAY12) ], SankeySeriesProperties.prototype, "strokes", 2); __decorateClass2([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "label", 2); __decorateClass2([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "link", 2); __decorateClass2([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "node", 2); __decorateClass2([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "tooltip", 2); var { Transformable: Transformable3, applyShapeStyle: applyShapeStyle11, SeriesNodePickMode: SeriesNodePickMode17, CachedTextMeasurerPool: CachedTextMeasurerPool11, TextWrapper: TextWrapper6, TextUtils: TextUtils8, createDatumId: createDatumId222, Rect: Rect8, BBox: BBox21 } = import_ag_charts_community258._ModuleSupport; var SankeySeries = class extends FlowProportionSeries { constructor(moduleCtx) { super({ moduleCtx, pickModes: [SeriesNodePickMode17.NEAREST_NODE, SeriesNodePickMode17.EXACT_SHAPE_MATCH] }); this.properties = new SankeySeriesProperties(); } isLabelEnabled() { return (this.properties.labelKey != null || this.nodes == null) && this.properties.label.enabled; } linkFactory() { return new SankeyLink(); } nodeFactory() { return new Rect8(); } createNodeData() { const { id: seriesId, _nodeDataDependencies: { seriesRectWidth, seriesRectHeight } = { seriesRectWidth: 0, seriesRectHeight: 0 } } = this; const { fromKey, toKey, sizeKey, label: { spacing: labelSpacing }, node: { spacing: nodeSpacing, width: nodeWidth, alignment } } = this.properties; const { nodeGraph: baseNodeGraph, links, maxPathLength } = this.getNodeGraph( (node) => ({ ...node, x: NaN, y: NaN, width: nodeWidth, height: NaN }), (link) => ({ ...link, x1: NaN, x2: NaN, y1: NaN, y2: NaN, height: NaN }), { includeCircularReferences: false } ); const nodeGraph = baseNodeGraph; const inset = this.isLabelEnabled() ? (seriesRectWidth - nodeWidth) * (1 - maxPathLength / (maxPathLength + 1)) : 0; const columnWidth = (seriesRectWidth - nodeWidth - 2 * inset) / (maxPathLength - 1); const columns = []; for (let index = 0; index < maxPathLength; index += 1) { const x = inset + index * columnWidth; columns.push({ index, size: 0, nodes: [], x }); } nodeGraph.forEach((graphNode) => { const { datum: node, linksBefore, linksAfter, maxPathLengthBefore, maxPathLengthAfter } = graphNode; const size = Math.max( linksBefore.reduce((acc, { link }) => acc + link.size, 0), linksAfter.reduce((acc, { link }) => acc + link.size, 0) ); if (linksBefore.length === 0 && linksAfter.length === 0 || size === 0) { graphNode.columnIndex = -1; return; } let column; switch (alignment) { case "left": column = columns[maxPathLengthBefore]; break; case "right": column = columns[maxPathLength - 1 - maxPathLengthAfter]; break; case "center": { if (linksBefore.length !== 0) { column = columns[maxPathLengthBefore]; } else if (linksAfter.length !== 0) { const columnIndex = linksAfter.reduce( (acc, link) => Math.min(acc, link.node.maxPathLengthBefore), maxPathLength ) - 1; column = columns[columnIndex]; } else { column = columns[0]; } break; } case "justify": { column = linksAfter.length === 0 ? columns[maxPathLength - 1] : columns[maxPathLengthBefore]; break; } } node.x = column.x; node.size = size; const label = this.getLabelText(this.properties.label, { datum: node.datum, value: node.label, fromKey, toKey, sizeKey, size }); node.label = String(label); column.nodes.push(graphNode); column.size += size; graphNode.columnIndex = column.index; }); nodeGraph.forEach((graphNode) => { let closestColumnIndex = Infinity; let maxSizeOfClosestNodesAfter = 0; graphNode.linksAfter.forEach((link) => { const node = link.node; const { columnIndex } = node; if (columnIndex < closestColumnIndex) { closestColumnIndex = columnIndex; maxSizeOfClosestNodesAfter = node.datum.size; } else if (columnIndex === closestColumnIndex) { maxSizeOfClosestNodesAfter = Math.max(maxSizeOfClosestNodesAfter, node.datum.size); } }); graphNode.closestColumnIndex = closestColumnIndex; graphNode.maxSizeOfClosestNodesAfter = maxSizeOfClosestNodesAfter; }); const sizeScale = columns.reduce((acc, { size, nodes }) => { const columnSizeScale = (1 - (nodes.length - 1) * (nodeSpacing / seriesRectHeight)) / size; return Math.min(acc, columnSizeScale); }, Infinity); for (let i = columns.length - 1; i >= 0; i -= 1) { const nodes = columns[i].nodes; nodes.sort( (a, b) => a.closestColumnIndex - b.closestColumnIndex || a.maxSizeOfClosestNodesAfter - b.maxSizeOfClosestNodesAfter || a.datum.size - b.datum.size ); } layoutColumns(columns, { seriesRectHeight, nodeSpacing, sizeScale }); let hasNegativeNodeHeight = false; nodeGraph.forEach(({ datum: node, linksBefore, linksAfter }) => { hasNegativeNodeHeight || (hasNegativeNodeHeight = node.height < 0); const bottom = node.y + node.height; const sortNodes = (l) => { return l.sort((a, b) => { const aNode = a.node.datum; const bNode = b.node.datum; const aBottom = aNode.y + aNode.height; const bBottom = bNode.y + bNode.height; const dAngleTop = Math.atan2(aNode.y - node.y, Math.abs(aNode.x - node.x)) - Math.atan2(bNode.y - node.y, Math.abs(bNode.x - node.x)); const dAngleBottom = Math.atan2(aBottom - bottom, Math.abs(aNode.x - node.x)) - Math.atan2(bBottom - bottom, Math.abs(bNode.x - node.x)); return dAngleTop + dAngleBottom; }); }; let y2 = node.y; sortNodes(linksBefore).forEach(({ link }) => { link.y2 = y2; y2 += link.size * seriesRectHeight * sizeScale; }); let y1 = node.y; sortNodes(linksAfter).forEach(({ link }) => { link.y1 = y1; y1 += link.size * seriesRectHeight * sizeScale; }); }); if (hasNegativeNodeHeight) { logger_exports2.warnOnce( "There was insufficient space to display the Sankey Series. Reduce the node spacing, or provide a larger container." ); return; } const nodeData = []; const labelData = []; const { fontSize } = this.properties.label; const canvasFont = this.properties.label.getFont(); columns.forEach((column, index) => { const leading = index === 0; const trailing = index === columns.length - 1; let bottom = -Infinity; column.nodes.sort((a, b) => a.datum.y - b.datum.y); column.nodes.forEach(({ datum: node }) => { node.midPoint = { x: node.x + node.width / 2, y: node.y + node.height / 2 }; nodeData.push(node); if (node.label == null) return; const x = leading ? node.x - labelSpacing : node.x + node.width + labelSpacing; const y = node.y + node.height / 2; let text22; if (!leading && !trailing) { const y12 = y - TextUtils8.getLineHeight(fontSize); const y2 = y + TextUtils8.getLineHeight(fontSize); let maxX = seriesRectWidth; nodeGraph.forEach(({ datum }) => { const intersectsLabel = datum.x > node.x && Math.max(datum.y, y12) <= Math.min(datum.y + datum.height, y2); if (intersectsLabel) { maxX = Math.min(maxX, datum.x - labelSpacing); } }); const maxWidth = maxX - node.x - 2 * labelSpacing; text22 = TextWrapper6.wrapText(node.label, { maxWidth, maxHeight: node.height, font: this.properties.label, textWrap: "never", overflow: "hide" }); } if (text22 == null || text22 === "") { const labelInset = leading || trailing ? labelSpacing : labelSpacing * 2; text22 = TextWrapper6.wrapText(node.label, { maxWidth: columnWidth - labelInset, maxHeight: node.height, font: this.properties.label, textWrap: "never" }); } if (text22 === "") return; const { height: height2 } = CachedTextMeasurerPool11.measureText(text22, { font: canvasFont, textAlign: "left", textBaseline: "middle" }); const y0 = y - height2 / 2; const y1 = y + height2 / 2; if (y0 >= bottom) { labelData.push({ x, y, leading, text: text22 }); bottom = y1; } }); }); links.forEach((link) => { const { fromNode, toNode, size } = link; link.height = seriesRectHeight * size * sizeScale; link.x1 = fromNode.x + nodeWidth; link.x2 = toNode.x; link.midPoint = { x: (link.x1 + link.x2) / 2, y: (link.y1 + link.y2) / 2 + link.height / 2 }; nodeData.push(link); }); return { itemId: seriesId, nodeData, labelData }; } updateLabelSelection(opts) { const labels = this.isLabelEnabled() ? opts.labelData : []; return opts.labelSelection.update(labels); } updateLabelNodes(opts) { const { labelSelection } = opts; const { color: fill, fontStyle, fontWeight, fontSize, fontFamily } = this.properties.label; labelSelection.each((label, { x, y, leading, text: text22 }) => { label.visible = true; label.x = x; label.y = y; label.text = text22; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textAlign = leading ? "right" : "left"; label.textBaseline = "middle"; }); } updateNodeSelection(opts) { return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId222([datum.type, datum.id])); } getBaseNodeStyle(highlighted) { const { properties } = this; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = properties.node; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? fill, fillOpacity: highlightStyle?.fillOpacity ?? fillOpacity, stroke: highlightStyle?.stroke ?? stroke22, strokeOpacity: highlightStyle?.strokeOpacity ?? strokeOpacity, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.node.strokeWidth), lineDash: highlightStyle?.lineDash ?? lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? lineDashOffset }; } getNodeStyleOverrides(datumId, datum, datumIndex, size, label, format, highlighted) { const { id: seriesId, properties } = this; const { fills, strokes } = properties; const { itemStyler } = properties.node; const fill = format.fill ?? fills[datumIndex % fills.length]; const stroke22 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId222(datumId, highlighted ? "highlight" : "node"), () => { const { fillOpacity = 1, strokeOpacity = 1, strokeWidth = 0, lineDash = [], lineDashOffset = 0 } = format; return itemStyler({ seriesId, datum, highlighted, label, size, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateNodeNodes(opts) { const { datumSelection, isHighlight } = opts; const style = this.getBaseNodeStyle(isHighlight); datumSelection.each((rect, datum) => { const { datumIndex, size, label } = datum; const overrides = this.getNodeStyleOverrides( String(datumIndex), datum, datumIndex.index, size, label, style, isHighlight ); rect.x = datum.x; rect.y = datum.y; rect.width = Math.max(datum.width, 0); rect.height = Math.max(datum.height, 0); applyShapeStyle11(rect, style, overrides); }); } updateLinkSelection(opts) { return opts.datumSelection.update( opts.nodeData, void 0, (datum) => createDatumId222([datum.type, datum.index, datum.fromNode.id, datum.toNode.id]) ); } getBaseLinkStyle(highlighted) { const { properties } = this; const { fill, fillOpacity, stroke: stroke22, strokeOpacity, lineDash, lineDashOffset } = properties.link; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; return { fill: highlightStyle?.fill ?? fill, fillOpacity: highlightStyle?.fillOpacity ?? fillOpacity, stroke: highlightStyle?.stroke ?? stroke22, strokeOpacity: highlightStyle?.strokeOpacity ?? strokeOpacity, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.link.strokeWidth), lineDash: highlightStyle?.lineDash ?? lineDash, lineDashOffset: highlightStyle?.lineDashOffset ?? lineDashOffset }; } getLinkStyleOverrides(datumId, datum, datumIndex, format, highlighted) { const { id: seriesId, properties } = this; const { fills, strokes } = properties; const { itemStyler } = properties.link; const fill = format.fill ?? fills[datumIndex % fills.length]; const stroke22 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId222(datumId, highlighted ? "highlight" : "node"), () => { const { fillOpacity = 1, strokeOpacity = 1, strokeWidth = 0, lineDash = [], lineDashOffset = 0 } = format; return itemStyler({ seriesId, datum, highlighted, fill, fillOpacity, stroke: stroke22, strokeOpacity, strokeWidth, lineDash, lineDashOffset }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateLinkNodes(opts) { const { datumSelection, isHighlight } = opts; const style = this.getBaseLinkStyle(isHighlight); datumSelection.each((link, datum) => { const { datumIndex } = datum; const fromNodeDatumIndex = datum.fromNode.datumIndex; const overrides = this.getLinkStyleOverrides( String(datumIndex), datum, fromNodeDatumIndex.index, style, isHighlight ); link.x1 = datum.x1; link.y1 = datum.y1; link.x2 = datum.x2; link.y2 = datum.y2; link.height = datum.height; applyShapeStyle11(link, style, overrides); link.inset = link.strokeWidth / 2; }); } getTooltipContent(seriesDatum) { const { id: seriesId, linksProcessedData, nodesProcessedData, properties } = this; const { fromKey, toKey, sizeKey, sizeName, tooltip } = properties; const { datumIndex } = seriesDatum; const nodeIndex = seriesDatum.type === 0 ? seriesDatum.fromNode.index : seriesDatum.index; const title = seriesDatum.type === 0 ? `${seriesDatum.fromNode.label} - ${seriesDatum.toNode.label}` : seriesDatum.label; const datum = datumIndex.type === 0 ? linksProcessedData?.dataSources.get(this.id)?.[datumIndex.index] : nodesProcessedData?.dataSources.get(this.id)?.[datumIndex.index]; const size = seriesDatum.size; let format; if (seriesDatum.type === 0) { const fromNodeDatumIndex = seriesDatum.fromNode.datumIndex; const linkFormat = this.getBaseLinkStyle(false); Object.assign( linkFormat, this.getLinkStyleOverrides(String(datumIndex), datum, fromNodeDatumIndex.index, linkFormat, false) ); format = linkFormat; } else { const label = seriesDatum.label; const nodeFormat = this.getBaseNodeStyle(false); Object.assign( nodeFormat, this.getNodeStyleOverrides(String(datumIndex), datum, datumIndex.index, size, label, nodeFormat, false) ); format = nodeFormat; } return tooltip.formatTooltip( { title, symbol: this.legendItemSymbol(seriesDatum.type, nodeIndex, format), data: sizeKey != null ? [{ label: sizeName, fallbackLabel: sizeKey, value: String(size) }] : [] }, { seriesId, datum, title, fromKey, toKey, sizeKey, sizeName, size, ...format } ); } computeFocusBounds(node) { if (node instanceof Rect8) { const { x, y, width: width2, height: height2 } = node; const bbox = new BBox21(x, y, width2, height2); return Transformable3.toCanvas(this.contentGroup, bbox); } return node; } }; SankeySeries.className = "SankeySeries"; SankeySeries.type = "sankey"; var SankeyModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["flow-proportion"], solo: true, identifier: "sankey", moduleFactory: (ctx) => new SankeySeries(ctx), tooltipDefaults: { range: "exact" }, themeTemplate: { seriesArea: { padding: { top: 10, bottom: 10 } }, series: { highlightStyle: { series: { dimOpacity: 0.2 } }, label: { fontFamily: { $ref: "fontFamily" }, fontSize: { $ref: "fontSize" }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "textColor" }, spacing: 10 }, node: { spacing: 20, width: 10, strokeWidth: 0 }, link: { fillOpacity: 0.5, strokeWidth: 0 } }, legend: { enabled: false, toggleSeries: false } }, paletteFactory({ takeColors, colorsCount }) { return takeColors(colorsCount); } }; var import_ag_charts_community262 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community261 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community260 = (init_main4(), __toCommonJS(main_exports)); var { HierarchySeriesProperties: HierarchySeriesProperties2, HighlightStyle: HighlightStyle2, SeriesTooltip: SeriesTooltip222, Validate: Validate85, COLOR_STRING: COLOR_STRING29, FUNCTION: FUNCTION222, NUMBER: NUMBER222, OBJECT: OBJECT45, POSITIVE_NUMBER: POSITIVE_NUMBER37, RATIO: RATIO35, STRING: STRING42 } = import_ag_charts_community260._ModuleSupport; var SunburstSeriesTileHighlightStyle = class extends HighlightStyle2 { constructor() { super(...arguments); this.label = new AutoSizedLabel(); this.secondaryLabel = new AutoSizedLabel(); } }; __decorateClass2([ Validate85(STRING42, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "fill", 2); __decorateClass2([ Validate85(RATIO35, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "fillOpacity", 2); __decorateClass2([ Validate85(COLOR_STRING29, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "stroke", 2); __decorateClass2([ Validate85(POSITIVE_NUMBER37, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "strokeWidth", 2); __decorateClass2([ Validate85(RATIO35, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass2([ Validate85(OBJECT45) ], SunburstSeriesTileHighlightStyle.prototype, "label", 2); __decorateClass2([ Validate85(OBJECT45) ], SunburstSeriesTileHighlightStyle.prototype, "secondaryLabel", 2); var SunburstSeriesProperties = class extends HierarchySeriesProperties2 { constructor() { super(...arguments); this.fillOpacity = 1; this.strokeWidth = 0; this.strokeOpacity = 1; this.cornerRadius = 0; this.highlightStyle = new SunburstSeriesTileHighlightStyle(); this.label = new AutoSizedLabel(); this.secondaryLabel = new AutoSizedSecondaryLabel(); this.tooltip = new SeriesTooltip222(); } }; __decorateClass2([ Validate85(STRING42, { optional: true }) ], SunburstSeriesProperties.prototype, "sizeName", 2); __decorateClass2([ Validate85(STRING42, { optional: true }) ], SunburstSeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate85(STRING42, { optional: true }) ], SunburstSeriesProperties.prototype, "secondaryLabelKey", 2); __decorateClass2([ Validate85(RATIO35) ], SunburstSeriesProperties.prototype, "fillOpacity", 2); __decorateClass2([ Validate85(POSITIVE_NUMBER37) ], SunburstSeriesProperties.prototype, "strokeWidth", 2); __decorateClass2([ Validate85(RATIO35) ], SunburstSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass2([ Validate85(POSITIVE_NUMBER37) ], SunburstSeriesProperties.prototype, "cornerRadius", 2); __decorateClass2([ Validate85(NUMBER222, { optional: true }) ], SunburstSeriesProperties.prototype, "sectorSpacing", 2); __decorateClass2([ Validate85(NUMBER222, { optional: true }) ], SunburstSeriesProperties.prototype, "padding", 2); __decorateClass2([ Validate85(FUNCTION222, { optional: true }) ], SunburstSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "highlightStyle", 2); __decorateClass2([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "label", 2); __decorateClass2([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "secondaryLabel", 2); __decorateClass2([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "tooltip", 2); var { fromToMotion: fromToMotion5, normalizeAngle360: normalizeAngle3608, createDatumId: createDatumId23, Sector: Sector7, Group: Group21, ScalableGroup: ScalableGroup22, Selection: Selection16, TransformableText: TransformableText22, applyShapeStyle: applyShapeStyle12 } = import_ag_charts_community261._ModuleSupport; var SunburstNode = class extends import_ag_charts_community261._ModuleSupport.HierarchyNode { constructor() { super(...arguments); this.label = void 0; this.secondaryLabel = void 0; this.contentHeight = 0; this.bbox = void 0; this.startAngle = 0; this.endAngle = 0; } }; function setAngleData(node, startAngle = 0, angleScale = 2 * Math.PI / node.sumSize) { for (const child of node.children) { const endAngle = startAngle + child.sumSize * angleScale; child.startAngle = startAngle; child.endAngle = endAngle; setAngleData(child, startAngle, angleScale); startAngle = endAngle; } } var SunburstSeries = class extends import_ag_charts_community261._ModuleSupport.HierarchySeries { constructor() { super(...arguments); this.NodeClass = SunburstNode; this.properties = new SunburstSeriesProperties(); this.scalingGroup = this.contentGroup.appendChild(new ScalableGroup22()); this.sectorGroup = this.scalingGroup.appendChild(new Group21()); this.sectorLabelGroup = this.scalingGroup.appendChild(new Group21()); this.highlightSectorGroup = this.scalingGroup.appendChild(new Group21()); this.datumSelection = Selection16.select(this.sectorGroup, Sector7); this.labelSelection = Selection16.select( this.sectorLabelGroup, Group21 ); this.highlightSelection = Selection16.select( this.highlightSectorGroup, Sector7 ); } processData() { super.processData(); setAngleData(this.rootNode); } updateSelections() { const highlightedNode = this.ctx.highlightManager?.getActiveHighlight(); this.highlightSelection.update( highlightedNode != null ? [highlightedNode] : [], void 0, (node) => this.getDatumId(node) ); if (!this.nodeDataRefresh) return; this.nodeDataRefresh = false; const { chart } = this; if (chart == null) return; const seriesRect = chart.seriesRect; if (seriesRect == null) return; const descendants = Array.from(this.rootNode); const updateLabelGroup = (group) => { group.append([ new TransformableText22({ tag: 0 /* Primary */ }), new TransformableText22({ tag: 1 /* Secondary */ }) ]); }; this.datumSelection.update(descendants, void 0, (node) => this.getDatumId(node)); this.labelSelection.update(descendants, updateLabelGroup, (node) => this.getDatumId(node)); } getItemBaseStyle(highlighted) { const { properties } = this; const highlightStyle = highlighted ? properties.highlightStyle : void 0; return { fill: highlightStyle?.fill, fillOpacity: highlightStyle?.fillOpacity ?? properties.fillOpacity, stroke: highlightStyle?.stroke, strokeWidth: highlightStyle?.strokeWidth ?? this.getStrokeWidth(properties.strokeWidth), strokeOpacity: highlightStyle?.strokeOpacity ?? properties.strokeOpacity }; } getItemStyleOverrides(datumId, datum, depth, colorValue, format, highlighted) { const { id: seriesId, properties, colorScale } = this; const { fills, strokes, itemStyler } = properties; const rootIndex = datumId[0]; const fill = format.fill ?? fills[rootIndex % fills.length]; const stroke22 = format.stroke ?? strokes[rootIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = colorValue != null ? colorScale.convert(colorValue) : fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId23(datumId.join(":"), highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, depth, highlighted, fill, stroke: stroke22, ...format }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateNodes() { const { chart, data, maxDepth } = this; if (chart == null || data == null) { return; } const { width: width2, height: height2 } = chart.seriesRect; const { sectorSpacing = 0, padding = 0, cornerRadius, childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName } = this.properties; this.contentGroup.translationX = width2 / 2; this.contentGroup.translationY = height2 / 2; const baseInset = sectorSpacing * 0.5; const radius = Math.min(width2, height2) / 2; const radiusScale = radius / (maxDepth + 1); const angleOffset = -Math.PI / 2; this.rootNode?.walk((node) => { const { startAngle, endAngle } = node; if (node.depth != null) { const midAngle = (startAngle + endAngle) / 2 + angleOffset; const midRadius = (node.depth + 0.5) * radiusScale; node.midPoint.x = Math.cos(midAngle) * midRadius; node.midPoint.y = Math.sin(midAngle) * midRadius; } }); this.rootNode?.walk((node) => { const { datum, depth, startAngle, endAngle, parent, sumSize } = node; node.label = void 0; node.secondaryLabel = void 0; node.contentHeight = 0; let labelValue; if (datum != null && depth != null && labelKey != null) { const value = datum[labelKey]; labelValue = this.getLabelText(this.properties.label, { depth, datum, childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName, value }); } if (labelValue === "") { labelValue = void 0; } let secondaryLabelValue; if (datum != null && depth != null && secondaryLabelKey != null) { const value = datum[secondaryLabelKey]; secondaryLabelValue = this.getLabelText(this.properties.secondaryLabel, { depth, datum, childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName, value }); } if (secondaryLabelValue === "") { secondaryLabelValue = void 0; } if (depth == null) return; const innerRadius = depth * radiusScale + baseInset; const outerRadius = (depth + 1) * radiusScale - baseInset; const innerAngleOffset = innerRadius > baseInset ? baseInset / innerRadius : baseInset; const outerAngleOffset = outerRadius > baseInset ? baseInset / outerRadius : baseInset; const innerStartAngle = startAngle + innerAngleOffset; const innerEndAngle = endAngle + innerAngleOffset; const deltaInnerAngle = innerEndAngle - innerStartAngle; const outerStartAngle = startAngle + outerAngleOffset; const outerEndAngle = endAngle + outerAngleOffset; const deltaOuterAngle = outerEndAngle - outerStartAngle; const sizeFittingHeight = (labelHeight2) => { const isCenterCircle = depth === 0 && parent?.sumSize === sumSize; if (isCenterCircle) { const labelWidth2 = 2 * Math.sqrt(outerRadius ** 2 - (labelHeight2 * 0.5) ** 2); return { width: labelWidth2, height: labelHeight2, meta: 0 /* CenterCircle */ }; } const parallelHeight = labelHeight2; const availableWidthUntilItHitsTheOuterRadius = 2 * Math.sqrt(outerRadius ** 2 - (innerRadius + parallelHeight) ** 2); const availableWidthUntilItHitsTheStraightEdges = deltaInnerAngle < Math.PI ? 2 * innerRadius * Math.tan(deltaInnerAngle * 0.5) : Infinity; const parallelWidth = Math.min( availableWidthUntilItHitsTheOuterRadius, availableWidthUntilItHitsTheStraightEdges ); const maxPerpendicularAngle = Math.PI / 4; let perpendicularHeight; let perpendicularWidth; if (depth === 0) { perpendicularHeight = labelHeight2; perpendicularWidth = Math.sqrt(outerRadius ** 2 - (perpendicularHeight / 2) ** 2) - labelHeight2 / (2 * Math.tan(deltaOuterAngle * 0.5)); } else if (normalizeAngle3608(deltaInnerAngle) < maxPerpendicularAngle) { perpendicularHeight = 2 * innerRadius * Math.tan(deltaInnerAngle * 0.5); perpendicularWidth = Math.sqrt(outerRadius ** 2 - (perpendicularHeight / 2) ** 2) - innerRadius; } else { perpendicularWidth = 0; perpendicularHeight = 0; } return parallelWidth >= perpendicularWidth ? { width: parallelWidth, height: parallelHeight, meta: 1 /* Parallel */ } : { width: perpendicularWidth, height: perpendicularHeight, meta: 2 /* Perpendicular */ }; }; const formatting = formatLabels( labelValue, this.properties.label, secondaryLabelValue, this.properties.secondaryLabel, { padding }, sizeFittingHeight ); if (formatting == null) return; const { width: labelWidth, height: labelHeight, meta: labelPlacement, label, secondaryLabel } = formatting; const theta = angleOffset + (startAngle + endAngle) / 2; const top = Math.sin(theta) >= 0; const right = Math.cos(theta) >= 0; const circleQuarter = (top ? 3 : 12) & (right ? 6 : 9); let labelRadius; switch (labelPlacement) { case 0: labelRadius = 0; break; case 1: { const opticalCentering = 0.58; const idealRadius = outerRadius - (radiusScale - labelHeight) * opticalCentering; const maximumRadius = Math.sqrt((outerRadius - padding) ** 2 - (labelWidth / 2) ** 2); labelRadius = Math.min(idealRadius, maximumRadius); break; } case 2: if (depth === 0) { const minimumRadius = labelHeight / (2 * Math.tan(deltaInnerAngle * 0.5)) + labelWidth * 0.5; const maximumRadius = Math.sqrt(outerRadius ** 2 - (labelHeight * 0.5) ** 2) - labelWidth * 0.5; labelRadius = (minimumRadius + maximumRadius) * 0.5; } else { labelRadius = (innerRadius + outerRadius) * 0.5; } break; } if (label != null) { const { fontStyle = "normal", fontFamily, fontWeight = "normal", color = "black" } = this.properties.label; node.label = { ...label, fontStyle, fontFamily, fontWeight, color, labelPlacement, circleQuarter, radius: labelRadius, theta }; } if (secondaryLabel != null) { const { fontStyle = "normal", fontFamily, fontWeight = "normal", color = "black" } = this.properties.secondaryLabel; node.secondaryLabel = { ...secondaryLabel, fontStyle, fontFamily, fontWeight, color, labelPlacement, circleQuarter, radius: labelRadius, theta }; } node.contentHeight = formatting.height; }); const updateSector = (nodeDatum, sector, style, highlighted) => { const { datum, datumIndex, depth, colorValue, startAngle, endAngle } = nodeDatum; if (depth == null) { sector.visible = false; return; } sector.visible = true; const overrides = this.getItemStyleOverrides(datumIndex, datum, depth, colorValue, style, highlighted); const strokeWidth = overrides.strokeWidth ?? style.strokeWidth; applyShapeStyle12(sector, style, overrides); sector.centerX = 0; sector.centerY = 0; sector.innerRadius = depth * radiusScale; sector.outerRadius = (depth + 1) * radiusScale; sector.startAngle = startAngle + angleOffset; sector.endAngle = endAngle + angleOffset; sector.inset = baseInset + strokeWidth * 0.5; sector.cornerRadius = cornerRadius; }; const baseFormat = this.getItemBaseStyle(false); this.datumSelection.each((sector, datum) => { updateSector(datum, sector, baseFormat, false); }); const highlightFormat = this.getItemBaseStyle(true); this.highlightSelection.each((rect, datum) => { updateSector(datum, rect, highlightFormat, true); }); const updateText = (node, text22, tag, highlighted) => { const { depth, contentHeight } = node; const primary = tag === 0; const label = primary ? node.label : node.secondaryLabel; if (depth == null || label == null) { text22.visible = false; return; } const { labelPlacement, circleQuarter, radius: textRadius, theta } = label; let highlightedColor; if (highlighted) { const highlightedLabelStyle = primary ? this.properties.highlightStyle.label : this.properties.highlightStyle.secondaryLabel; highlightedColor = highlightedLabelStyle.color; } text22.text = label.text; text22.fontSize = label.fontSize; text22.lineHeight = label.lineHeight; text22.fontStyle = label.fontStyle; text22.fontFamily = label.fontFamily; text22.fontWeight = label.fontWeight; text22.fill = highlightedColor ?? label.color; switch (labelPlacement) { case 0: text22.textAlign = "center"; text22.textBaseline = "top"; text22.translationX = 0; text22.translationY = (primary ? 0 : contentHeight - label.height) - contentHeight * 0.5; text22.rotation = 0; break; case 1: { const topHalf = (circleQuarter & 3) !== 0; const translationRadius = primary === !topHalf ? textRadius : textRadius - (contentHeight - label.height); text22.textAlign = "center"; text22.textBaseline = topHalf ? "bottom" : "top"; text22.translationX = Math.cos(theta) * translationRadius; text22.translationY = Math.sin(theta) * translationRadius; text22.rotation = topHalf ? theta - Math.PI * 0.5 : theta + Math.PI * 0.5; break; } case 2: { const rightHalf = (circleQuarter & 6) !== 0; const translation = primary === !rightHalf ? (contentHeight - label.height) * 0.5 : (label.height - contentHeight) * 0.5; text22.textAlign = "center"; text22.textBaseline = "middle"; text22.translationX = Math.cos(theta) * textRadius + Math.cos(theta + Math.PI / 2) * translation; text22.translationY = Math.sin(theta) * textRadius + Math.sin(theta + Math.PI / 2) * translation; text22.rotation = rightHalf ? theta : theta + Math.PI; break; } } text22.visible = true; }; const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); this.labelSelection.selectByClass(TransformableText22).forEach((text22) => { updateText(text22.datum, text22, text22.tag, text22.datum === highlightedDatum); }); } getTooltipContent(nodeDatum) { const { id: seriesId, properties } = this; const { labelKey, secondaryLabelKey, childrenKey, sizeKey, sizeName, colorKey, colorName, tooltip } = properties; const { datum, datumIndex, depth } = nodeDatum; if (datum == null || depth == null) return; const data = []; const datumSize = sizeKey != null ? datum[sizeKey] : void 0; if (datumSize != null) { data.push({ label: sizeName, fallbackLabel: sizeKey, value: datumSize }); } const datumColor = colorKey != null ? datum[colorKey] : void 0; if (datumColor != null) { data.push({ label: colorName, fallbackLabel: colorKey, value: datumColor }); } const format = this.getItemBaseStyle(false); Object.assign(format, this.getItemStyleOverrides(datumIndex, datum, depth, datumColor, format, false)); const color = format.fill; return tooltip.formatTooltip( { title: labelKey != null ? datum[labelKey] : void 0, symbol: { marker: { shape: "square", fill: color, fillOpacity: 1, stroke: void 0, strokeWidth: 0, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0 } }, data }, { seriesId, datum, title: void 0, depth, labelKey, secondaryLabelKey, childrenKey, sizeKey, sizeName, colorKey, colorName, ...format } ); } createNodeData() { return void 0; } pickNodeClosestDatum(point) { return this.pickNodeNearestDistantObject(point, this.datumSelection.selectByClass(Sector7)); } animateEmptyUpdateReady() { fromToMotion5(this.id, "nodes", this.ctx.animationManager, [this.scalingGroup], { toFn() { return { scalingX: 1, scalingY: 1 }; }, fromFn() { return { scalingX: 0, scalingY: 0 }; } }); } computeFocusBounds(node) { return node; } }; SunburstSeries.className = "SunburstSeries"; SunburstSeries.type = "sunburst"; var { FONT_SIZE_RATIO: FONT_SIZE_RATIO3, ThemeSymbols: { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE5 } } = import_ag_charts_community262._ModuleSupport; var SunburstModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["hierarchy"], identifier: "sunburst", moduleFactory: (ctx) => new SunburstSeries(ctx), tooltipDefaults: { range: "exact" }, solo: true, themeTemplate: { series: { label: { fontFamily: { $ref: "fontFamily" }, fontSize: { $rem: [FONT_SIZE_RATIO3.LARGE] }, minimumFontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 9 / 12] }] }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" }, overflowStrategy: "ellipsis", wrapping: "never", spacing: 2 }, secondaryLabel: { fontFamily: { $ref: "fontFamily" }, fontSize: { $rem: [FONT_SIZE_RATIO3.SMALLEST] }, minimumFontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 7 / 12] }] }, fontWeight: { $ref: "fontWeight" }, color: { $ref: "backgroundColor" }, overflowStrategy: "ellipsis", wrapping: "never" }, sectorSpacing: 2, padding: 3, highlightStyle: { label: { color: { $ref: "backgroundColor" } }, secondaryLabel: { color: { $ref: "backgroundColor" } }, fill: "rgba(255,255,255, 0.33)", stroke: `rgba(0, 0, 0, 0.4)`, strokeWidth: 2 } }, gradientLegend: { enabled: true } }, paletteFactory: ({ takeColors, colorsCount, themeTemplateParameters }) => { const { fills, strokes } = takeColors(colorsCount); const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE5); return { fills, strokes, colorRange: defaultColorRange }; } }; var import_ag_charts_community265 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community264 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community263 = (init_main4(), __toCommonJS(main_exports)); var { BaseProperties: BaseProperties28, HierarchySeriesProperties: HierarchySeriesProperties22, HighlightStyle: HighlightStyle22, SeriesTooltip: SeriesTooltip23, Validate: Validate86, BOOLEAN: BOOLEAN35, COLOR_STRING: COLOR_STRING30, FUNCTION: FUNCTION23, NUMBER: NUMBER23, OBJECT: OBJECT46, POSITIVE_NUMBER: POSITIVE_NUMBER38, RATIO: RATIO36, STRING: STRING43, STRING_ARRAY: STRING_ARRAY2, TEXT_ALIGN: TEXT_ALIGN3, VERTICAL_ALIGN: VERTICAL_ALIGN22, Label: Label17 } = import_ag_charts_community263._ModuleSupport; var TreemapGroupLabel = class extends Label17 { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass2([ Validate86(NUMBER23) ], TreemapGroupLabel.prototype, "spacing", 2); var TreemapSeriesGroup = class extends BaseProperties28 { constructor() { super(...arguments); this.fillOpacity = 1; this.strokeWidth = 1; this.strokeOpacity = 1; this.cornerRadius = 0; this.textAlign = "center"; this.gap = 0; this.padding = 0; this.interactive = true; this.label = new TreemapGroupLabel(); } }; __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesGroup.prototype, "fill", 2); __decorateClass2([ Validate86(RATIO36) ], TreemapSeriesGroup.prototype, "fillOpacity", 2); __decorateClass2([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesGroup.prototype, "stroke", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "strokeWidth", 2); __decorateClass2([ Validate86(RATIO36) ], TreemapSeriesGroup.prototype, "strokeOpacity", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "cornerRadius", 2); __decorateClass2([ Validate86(TEXT_ALIGN3) ], TreemapSeriesGroup.prototype, "textAlign", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "gap", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "padding", 2); __decorateClass2([ Validate86(BOOLEAN35) ], TreemapSeriesGroup.prototype, "interactive", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesGroup.prototype, "label", 2); var TreemapSeriesTile = class extends BaseProperties28 { constructor() { super(...arguments); this.fillOpacity = 1; this.strokeWidth = 1; this.strokeOpacity = 1; this.cornerRadius = 0; this.textAlign = "center"; this.verticalAlign = "middle"; this.gap = 0; this.padding = 0; this.label = new AutoSizedLabel(); this.secondaryLabel = new AutoSizedSecondaryLabel(); } }; __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesTile.prototype, "fill", 2); __decorateClass2([ Validate86(RATIO36) ], TreemapSeriesTile.prototype, "fillOpacity", 2); __decorateClass2([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesTile.prototype, "stroke", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38, { optional: true }) ], TreemapSeriesTile.prototype, "strokeWidth", 2); __decorateClass2([ Validate86(RATIO36) ], TreemapSeriesTile.prototype, "strokeOpacity", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesTile.prototype, "cornerRadius", 2); __decorateClass2([ Validate86(TEXT_ALIGN3) ], TreemapSeriesTile.prototype, "textAlign", 2); __decorateClass2([ Validate86(VERTICAL_ALIGN22) ], TreemapSeriesTile.prototype, "verticalAlign", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesTile.prototype, "gap", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesTile.prototype, "padding", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesTile.prototype, "label", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesTile.prototype, "secondaryLabel", 2); var TreemapSeriesGroupHighlightStyle = class extends BaseProperties28 { constructor() { super(...arguments); this.label = new AutoSizedLabel(); } }; __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "fill", 2); __decorateClass2([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "fillOpacity", 2); __decorateClass2([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "stroke", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "strokeWidth", 2); __decorateClass2([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesGroupHighlightStyle.prototype, "label", 2); var TreemapSeriesTileHighlightStyle = class extends BaseProperties28 { constructor() { super(...arguments); this.label = new AutoSizedLabel(); this.secondaryLabel = new AutoSizedSecondaryLabel(); } }; __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "fill", 2); __decorateClass2([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "fillOpacity", 2); __decorateClass2([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "stroke", 2); __decorateClass2([ Validate86(POSITIVE_NUMBER38, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "strokeWidth", 2); __decorateClass2([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesTileHighlightStyle.prototype, "label", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesTileHighlightStyle.prototype, "secondaryLabel", 2); var TreemapSeriesHighlightStyle = class extends HighlightStyle22 { constructor() { super(...arguments); this.group = new TreemapSeriesGroupHighlightStyle(); this.tile = new TreemapSeriesTileHighlightStyle(); } }; __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesHighlightStyle.prototype, "group", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesHighlightStyle.prototype, "tile", 2); var TreemapSeriesProperties = class extends HierarchySeriesProperties22 { constructor() { super(...arguments); this.highlightStyle = new TreemapSeriesHighlightStyle(); this.tooltip = new SeriesTooltip23(); this.group = new TreemapSeriesGroup(); this.tile = new TreemapSeriesTile(); this.undocumentedGroupFills = []; this.undocumentedGroupStrokes = []; } }; __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesProperties.prototype, "sizeName", 2); __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesProperties.prototype, "labelKey", 2); __decorateClass2([ Validate86(STRING43, { optional: true }) ], TreemapSeriesProperties.prototype, "secondaryLabelKey", 2); __decorateClass2([ Validate86(FUNCTION23, { optional: true }) ], TreemapSeriesProperties.prototype, "itemStyler", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "highlightStyle", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "tooltip", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "group", 2); __decorateClass2([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "tile", 2); __decorateClass2([ Validate86(STRING_ARRAY2) ], TreemapSeriesProperties.prototype, "undocumentedGroupFills", 2); __decorateClass2([ Validate86(STRING_ARRAY2) ], TreemapSeriesProperties.prototype, "undocumentedGroupStrokes", 2); var { TextUtils: TextUtils9, TextWrapper: TextWrapper7, isNumberEqual: isNumberEqual10, createDatumId: createDatumId24, Rect: Rect9, Group: Group222, BBox: BBox222, Selection: Selection17, Text: Text9, Transformable: Transformable4, applyShapeStyle: applyShapeStyle13 } = import_ag_charts_community264._ModuleSupport; var TreemapNode = class extends import_ag_charts_community264._ModuleSupport.HierarchyNode { constructor() { super(...arguments); this.labelValue = void 0; this.secondaryLabelValue = void 0; this.label = void 0; this.secondaryLabel = void 0; this.bbox = void 0; this.padding = void 0; } }; var tempText = new Text9(); function getTextSize(text22, style) { const { fontStyle, fontWeight, fontSize, fontFamily } = style; tempText.setProperties({ text: text22, fontStyle, fontWeight, fontSize, fontFamily, textAlign: "left", textBaseline: "top" }); const { width: width2, height: height2 } = tempText.getBBox(); return { width: width2, height: height2 }; } function nodeSize(node) { return node.children.length > 0 ? node.sumSize - node.sizeValue : node.sizeValue; } var textAlignFactors2 = { left: 0, center: 0.5, right: 1 }; var verticalAlignFactors4 = { top: 0, middle: 0.5, bottom: 1 }; var DistantGroup = class extends import_ag_charts_community264._ModuleSupport.Group { distanceSquared(x, y) { return this.getBBox().distanceSquared(x, y); } }; var TreemapSeries = class extends import_ag_charts_community264._ModuleSupport.HierarchySeries { constructor() { super(...arguments); this.NodeClass = TreemapNode; this.properties = new TreemapSeriesProperties(); this.rectGroup = this.contentGroup.appendChild(new Group222()); this.datumSelection = Selection17.select(this.rectGroup, Rect9); this.labelSelection = Selection17.select(this.labelGroup, Group222); this.highlightSelection = Selection17.select( this.rectGroup, Rect9 ); } groupTitleHeight(node, bbox) { const { labelValue } = node; const { label: font22 } = this.properties.group; const heightRatioThreshold = 3; if (labelValue == null) { return; } else if (font22.fontSize > bbox.width / heightRatioThreshold || font22.fontSize > bbox.height / heightRatioThreshold) { return; } else { const { height: fontHeight } = getTextSize(labelValue, font22); return Math.max(fontHeight, font22.fontSize); } } getNodePadding(node, bbox) { if (node.parent == null) { return { top: 0, right: 0, bottom: 0, left: 0 }; } else if (node.children.length === 0) { const { padding: padding2 } = this.properties.tile; return { top: padding2, right: padding2, bottom: padding2, left: padding2 }; } const { label: { spacing }, padding } = this.properties.group; const fontHeight = this.groupTitleHeight(node, bbox); const titleHeight = fontHeight != null ? fontHeight + spacing : 0; return { top: padding + titleHeight, right: padding, bottom: padding, left: padding }; } sortChildren({ children }) { const sortedChildrenIndices = Array.from(children, (_, i) => i).filter((i) => nodeSize(children[i]) > 0).sort((aIndex, bIndex) => nodeSize(children[bIndex]) - nodeSize(children[aIndex])); const childAt = (i) => { const sortedIndex = sortedChildrenIndices[i]; return children[sortedIndex]; }; return { sortedChildrenIndices, childAt }; } /** * Squarified Treemap algorithm * https://www.win.tue.nl/~vanwijk/stm.pdf */ squarify(node, bbox) { const { datum, children } = node; if (bbox.width <= 0 || bbox.height <= 0) { node.bbox = void 0; node.padding = void 0; node.midPoint.x = NaN; node.midPoint.y = NaN; return; } const padding = datum != null ? this.getNodePadding(node, bbox) : { top: 0, right: 0, bottom: 0, left: 0 }; if (node.parent == null) { node.bbox = void 0; node.padding = void 0; node.midPoint.x = NaN; node.midPoint.y = NaN; } else { node.bbox = bbox; node.padding = padding; node.midPoint.x = bbox.x + bbox.width / 2; node.midPoint.y = bbox.y; } const { sortedChildrenIndices, childAt } = this.sortChildren(node); const allLeafNodes = sortedChildrenIndices.every((sortedIndex) => children[sortedIndex].children.length === 0); const targetTileAspectRatio = 1; const width2 = bbox.width - padding.left - padding.right; const height2 = bbox.height - padding.top - padding.bottom; if (width2 <= 0 || height2 <= 0) return; const numChildren = sortedChildrenIndices.length; let stackSum = 0; let startIndex = 0; let minRatioDiff = Infinity; let partitionSum = sortedChildrenIndices.reduce((sum2, sortedIndex) => sum2 + nodeSize(children[sortedIndex]), 0); const innerBox = new BBox222(bbox.x + padding.left, bbox.y + padding.top, width2, height2); const partition = innerBox.clone(); let i = 0; while (i < numChildren) { const value = nodeSize(childAt(i)); const firstValue = nodeSize(childAt(startIndex)); const isVertical2 = partition.width < partition.height; stackSum += value; const partThickness = isVertical2 ? partition.height : partition.width; const partLength = isVertical2 ? partition.width : partition.height; const firstTileLength = partLength * firstValue / stackSum; let stackThickness = partThickness * stackSum / partitionSum; const ratio2 = Math.max(firstTileLength, stackThickness) / Math.min(firstTileLength, stackThickness); const diff8 = Math.abs(targetTileAspectRatio - ratio2); if (diff8 < minRatioDiff) { minRatioDiff = diff8; i++; continue; } stackSum -= value; stackThickness = partThickness * stackSum / partitionSum; let start22 = isVertical2 ? partition.x : partition.y; for (let j = startIndex; j < i; j++) { const child = childAt(j); const childSize = nodeSize(child); const x = isVertical2 ? start22 : partition.x; const y = isVertical2 ? partition.y : start22; const length2 = partLength * childSize / stackSum; const stackWidth = isVertical2 ? length2 : stackThickness; const stackHeight = isVertical2 ? stackThickness : length2; const childBbox = new BBox222(x, y, stackWidth, stackHeight); this.applyGap(innerBox, childBbox, allLeafNodes); this.squarify(child, childBbox); partitionSum -= childSize; start22 += length2; } if (isVertical2) { partition.y += stackThickness; partition.height -= stackThickness; } else { partition.x += stackThickness; partition.width -= stackThickness; } startIndex = i; stackSum = 0; minRatioDiff = Infinity; } const isVertical = partition.width < partition.height; let start2 = isVertical ? partition.x : partition.y; for (let childIdx = startIndex; childIdx < numChildren; childIdx++) { const child = childAt(childIdx); const x = isVertical ? start2 : partition.x; const y = isVertical ? partition.y : start2; const part = nodeSize(child) / partitionSum; const childWidth = partition.width * (isVertical ? part : 1); const childHeight = partition.height * (isVertical ? 1 : part); const childBox = new BBox222(x, y, childWidth, childHeight); this.applyGap(innerBox, childBox, allLeafNodes); this.squarify(child, childBox); start2 += isVertical ? childWidth : childHeight; } } applyGap(innerBox, childBox, allLeafNodes) { const gap = allLeafNodes ? this.properties.tile.gap * 0.5 : this.properties.group.gap * 0.5; const getBounds = (box) => ({ left: box.x, top: box.y, right: box.x + box.width, bottom: box.y + box.height }); const innerBounds = getBounds(innerBox); const childBounds = getBounds(childBox); const sides = ["top", "right", "bottom", "left"]; sides.forEach((side) => { if (!isNumberEqual10(innerBounds[side], childBounds[side])) { childBox.shrink(gap, side); } }); } createNodeData() { return void 0; } getGroupBaseStyle(highlighted) { const { properties } = this; const { group } = properties; const highlightStyle = highlighted ? properties.highlightStyle.group : void 0; return { fill: highlightStyle?.fill ?? group.fill, fillOpacity: highlightStyle?.fillOpacity ?? group.fillOpacity, stroke: highlightStyle?.stroke ?? group.stroke, strokeWidth: highlightStyle?.strokeWidth ?? group.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? group.strokeOpacity }; } getGroupStyleOverrides(datumId, datum, depth, format, highlighted) { const { id: seriesId, properties } = this; const { undocumentedGroupFills, undocumentedGroupStrokes, itemStyler } = properties; const fill = format.fill ?? undocumentedGroupFills[Math.min(depth ?? 0, undocumentedGroupFills.length)]; const stroke22 = format.stroke ?? undocumentedGroupStrokes[Math.min(depth ?? 0, undocumentedGroupStrokes.length)]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId24(datumId.join(":"), highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, depth, highlighted, fill, stroke: stroke22, ...format }); } ); Object.assign(overrides, itemStyle); } return overrides; } getTileBaseStyle(highlighted) { const { properties } = this; const { tile } = properties; const highlightStyle = highlighted ? properties.highlightStyle.tile : void 0; return { fill: highlightStyle?.fill ?? tile.fill, fillOpacity: highlightStyle?.fillOpacity ?? tile.fillOpacity, stroke: highlightStyle?.stroke ?? tile.stroke, strokeWidth: highlightStyle?.strokeWidth ?? tile.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? tile.strokeOpacity }; } getTileStyleOverrides(datumId, datum, depth, colorValue, format, highlighted) { const { id: seriesId, properties, colorScale } = this; const { fills, strokes, itemStyler } = properties; const rootIndex = datumId[0]; const fill = format.fill ?? fills[rootIndex % fills.length]; const stroke22 = format.stroke ?? strokes[rootIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = colorValue != null ? colorScale.convert(colorValue) : fill; overrides.stroke = stroke22; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId24(datumId.join(":"), highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, depth, highlighted, fill, stroke: stroke22, ...format }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateSelections() { let highlightedNode = this.ctx.highlightManager?.getActiveHighlight(); if (highlightedNode != null && !this.properties.group.interactive && highlightedNode.children.length !== 0) { highlightedNode = void 0; } this.highlightSelection.update( highlightedNode != null ? [highlightedNode] : [], void 0, (node) => this.getDatumId(node) ); if (!this.nodeDataRefresh) { return; } this.nodeDataRefresh = false; const { seriesRect } = this.chart ?? {}; if (!seriesRect) return; const descendants = Array.from(this.rootNode); const updateLabelGroup = (group) => { group.append([new Text9({ tag: 0 /* Primary */ }), new Text9({ tag: 1 /* Secondary */ })]); }; this.datumSelection.update(descendants, void 0, (node) => this.getDatumId(node)); this.labelSelection.update(descendants, updateLabelGroup, (node) => this.getDatumId(node)); } updateNodes() { const { rootNode, data } = this; const { childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName, highlightStyle, tile, group } = this.properties; const { seriesRect } = this.chart ?? {}; if (!seriesRect || !data) return; this.rootNode?.walk((node) => { const { datum, depth, children } = node; const isLeaf = children.length === 0; const labelStyle = isLeaf ? tile.label : group.label; let labelValue; if (datum != null && depth != null && labelKey != null) { const value = datum[labelKey]; labelValue = this.getLabelText(labelStyle, { depth, datum, childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName, value }); } if (labelValue === "") { labelValue = void 0; } let secondaryLabelValue; if (isLeaf && datum != null && depth != null && secondaryLabelKey != null) { const value = datum[secondaryLabelKey]; secondaryLabelValue = this.getLabelText(tile.secondaryLabel, { depth, datum, childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName, value }); } if (secondaryLabelValue === "") { secondaryLabelValue = void 0; } node.labelValue = labelValue; node.secondaryLabelValue = secondaryLabelValue; }); const { width: width2, height: height2 } = seriesRect; this.squarify(rootNode, new BBox222(0, 0, width2, height2)); this.rootNode?.walk((node) => { const { bbox, children, labelValue, secondaryLabelValue } = node; node.label = void 0; node.secondaryLabel = void 0; if (bbox == null) return; if (children.length === 0) { const layout = { width: bbox.width, height: bbox.height, meta: null }; const formatting = formatLabels( labelValue, this.properties.tile.label, secondaryLabelValue, this.properties.tile.secondaryLabel, { padding: tile.padding }, () => layout ); if (formatting == null) { return; } const { height: labelHeight, label, secondaryLabel } = formatting; const { textAlign, verticalAlign, padding } = tile; const textAlignFactor = textAlignFactors2[textAlign] ?? 0.5; const labelX = bbox.x + padding + (bbox.width - 2 * padding) * textAlignFactor; const verticalAlignFactor = verticalAlignFactors4[verticalAlign] ?? 0.5; const labelYStart = bbox.y + padding + labelHeight * 0.5 + (bbox.height - 2 * padding - labelHeight) * verticalAlignFactor; if (label != null) { const { fontStyle = "normal", fontFamily, fontWeight = "normal", color = "black" } = this.properties.tile.label; node.label = { text: label.text, fontSize: label.fontSize, lineHeight: label.lineHeight, fontStyle, fontFamily, fontWeight, color, textAlign, verticalAlign: "middle", x: labelX, y: labelYStart - (labelHeight - label.height) * 0.5 }; } if (secondaryLabel != null) { const { fontStyle = "normal", fontFamily, fontWeight = "normal", color = "black" } = this.properties.tile.secondaryLabel; node.secondaryLabel = { text: secondaryLabel.text, fontSize: secondaryLabel.fontSize, lineHeight: secondaryLabel.fontSize, fontStyle, fontFamily, fontWeight, color, textAlign, verticalAlign: "middle", x: labelX, y: labelYStart + (labelHeight - secondaryLabel.height) * 0.5 }; } } else if (labelValue == null) { return; } else { const { padding, textAlign } = group; const groupTitleHeight = this.groupTitleHeight(node, bbox); if (groupTitleHeight == null) return; const innerWidth = bbox.width - 2 * padding; const text22 = TextWrapper7.wrapText(labelValue, { maxWidth: bbox.width - 2 * padding, font: group.label, textWrap: "never" }); const textAlignFactor = textAlignFactors2[textAlign] ?? 0.5; const { fontStyle = "normal", fontFamily, fontWeight = "normal", color = "black" } = this.properties.group.label; node.label = { text: text22, fontSize: group.label.fontSize, lineHeight: TextUtils9.getLineHeight(group.label.fontSize), fontStyle, fontFamily, fontWeight, color, textAlign, verticalAlign: "middle", x: bbox.x + padding + innerWidth * textAlignFactor, y: bbox.y + padding + groupTitleHeight * 0.5 }; } }); const updateRectFn = (node, rect, groupStyle, tileStyle, highlighted) => { const { bbox } = node; if (bbox == null) { rect.visible = false; return; } const { datum, depth = -1, datumIndex, colorValue } = node; const isLeaf = node.children.length === 0; const style = isLeaf ? tileStyle : groupStyle; const overrides = isLeaf ? this.getTileStyleOverrides(datumIndex, datum, depth, colorValue, style, highlighted) : this.getGroupStyleOverrides(datumIndex, datum, depth, style, highlighted); rect.crisp = true; applyShapeStyle13(rect, style, overrides); rect.cornerRadius = isLeaf ? tile.cornerRadius : group.cornerRadius; rect.zIndex = [0, depth, highlighted ? 1 : 0]; const onlyLeaves = node.parent?.children.every((n) => n.children.length === 0); const parentBbox = node.parent != null ? node.parent.bbox : void 0; const parentPadding = node.parent != null ? node.parent.padding : void 0; if (onlyLeaves === true && parentBbox != null && parentPadding != null) { rect.clipBBox = bbox; rect.x = parentBbox.x + parentPadding.left; rect.y = parentBbox.y + parentPadding.top; rect.width = parentBbox.width - (parentPadding.left + parentPadding.right); rect.height = parentBbox.height - (parentPadding.top + parentPadding.bottom); } else { rect.clipBBox = void 0; rect.x = bbox.x; rect.y = bbox.y; rect.width = bbox.width; rect.height = bbox.height; } rect.visible = true; }; const baseGroupFormat = this.getGroupBaseStyle(false); const baseTileFormat = this.getTileBaseStyle(false); this.datumSelection.each((rect, datum) => updateRectFn(datum, rect, baseGroupFormat, baseTileFormat, false)); const highlightGroupFormat = this.getGroupBaseStyle(true); const highlightTileFormat = this.getTileBaseStyle(true); this.highlightSelection.each((rect, datum) => { updateRectFn(datum, rect, highlightGroupFormat, highlightTileFormat, true); }); const updateLabelFn = (node, text22, tag, highlighted) => { const isLeaf = node.children.length === 0; const label = tag === 0 ? node.label : node.secondaryLabel; if (label == null) { text22.visible = false; return; } let highlightedColor; if (highlighted) { const { tile: hTitle, group: hGroup } = highlightStyle; highlightedColor = hTitle.secondaryLabel.color; if (!isLeaf) { highlightedColor = hGroup.label.color; } else if (tag === 0) { highlightedColor = hTitle.label.color; } } text22.text = label.text; text22.fontSize = label.fontSize; text22.lineHeight = label.lineHeight; text22.fontStyle = label.fontStyle; text22.fontFamily = label.fontFamily; text22.fontWeight = label.fontWeight; text22.fill = highlightedColor ?? label.color; text22.textAlign = label.textAlign; text22.textBaseline = label.verticalAlign; text22.x = label.x; text22.y = label.y; text22.visible = true; text22.zIndex = 1; }; const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); this.labelSelection.selectByClass(Text9).forEach((text22) => { updateLabelFn(text22.datum, text22, text22.tag, text22.datum === highlightedDatum); }); } pickNodeClosestDatum(point) { const exactMatch = this.pickNodeExactShape(point); if (exactMatch !== void 0) { return exactMatch; } return this.pickNodeNearestDistantObject(point, this.datumSelection.nodes()); } getTooltipContent(nodeDatum) { const { id: seriesId, properties } = this; const { labelKey, secondaryLabelKey, childrenKey, sizeKey, sizeName, colorKey, colorName, tooltip } = properties; const { datum, datumIndex, depth, children } = nodeDatum; if (datum == null || depth == null) return; const isLeaf = children.length === 0; const data = []; const datumSize = sizeKey != null ? datum[sizeKey] : void 0; if (datumSize != null) { data.push({ label: sizeName, fallbackLabel: sizeKey, value: datumSize }); } const datumColor = colorKey != null ? datum[colorKey] : void 0; if (datumColor != null) { data.push({ label: colorName, fallbackLabel: colorKey, value: datumColor }); } let format; if (isLeaf) { format = this.getTileBaseStyle(false); Object.assign(format, this.getTileStyleOverrides(datumIndex, datum, depth, datumColor, format, false)); } else { format = this.getGroupBaseStyle(false); Object.assign(format, this.getGroupStyleOverrides(datumIndex, datum, depth, format, false)); } const color = format.fill; const symbol = isLeaf ? { marker: { shape: "square", fill: color, fillOpacity: 1, stroke: void 0, strokeWidth: 0, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0 } } : void 0; return tooltip.formatTooltip( { title: labelKey != null ? datum[labelKey] : void 0, symbol, data }, { seriesId, datum, title: void 0, depth, labelKey, secondaryLabelKey, childrenKey, sizeKey, sizeName, colorKey, colorName, ...format } ); } computeFocusBounds(node) { return Transformable4.toCanvas(this.contentGroup, node.getBBox()); } }; TreemapSeries.className = "TreemapSeries"; TreemapSeries.type = "treemap"; var { FONT_SIZE_RATIO: FONT_SIZE_RATIO4, ThemeSymbols: { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE6, DEFAULT_HIERARCHY_FILLS: DEFAULT_HIERARCHY_FILLS4, DEFAULT_HIERARCHY_STROKES: DEFAULT_HIERARCHY_STROKES22 } } = import_ag_charts_community265._ModuleSupport; var TreemapModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["hierarchy"], identifier: "treemap", moduleFactory: (ctx) => new TreemapSeries(ctx), tooltipDefaults: { range: "exact" }, solo: true, themeTemplate: { series: { group: { label: { enabled: true, color: { $ref: "textColor" }, fontStyle: void 0, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, spacing: 4 }, fill: void 0, // Override default fill stroke: void 0, // Override default stroke strokeWidth: 1, padding: 4, gap: 2, textAlign: "left" }, tile: { label: { enabled: true, color: { $ref: "backgroundColor" }, fontStyle: void 0, fontWeight: { $ref: "fontWeight" }, fontSize: { $rem: [1.5] }, minimumFontSize: { $rem: [FONT_SIZE_RATIO4.SMALLER] }, fontFamily: { $ref: "fontFamily" }, wrapping: "on-space", overflowStrategy: "ellipsis", spacing: 2 }, secondaryLabel: { enabled: true, color: { $ref: "backgroundColor" }, fontStyle: void 0, fontWeight: void 0, fontSize: { $ref: "fontSize" }, minimumFontSize: { $rem: [FONT_SIZE_RATIO4.SMALLER] }, fontFamily: { $ref: "fontFamily" }, wrapping: "never", overflowStrategy: "ellipsis" }, fill: void 0, // Override default fill stroke: void 0, // Override default stroke strokeWidth: 0, padding: 3, gap: 1 }, // Override defaults highlightStyle: { group: { label: { color: { $ref: "textColor" } }, fill: "rgba(255,255,255, 0.33)", stroke: `rgba(0, 0, 0, 0.4)`, strokeWidth: 2 }, tile: { label: { color: { $ref: "backgroundColor" } }, secondaryLabel: { color: { $ref: "backgroundColor" } }, fill: "rgba(255,255,255, 0.33)", stroke: `rgba(0, 0, 0, 0.4)`, strokeWidth: 2 } } }, gradientLegend: { enabled: true } }, paletteFactory: ({ takeColors, colorsCount, themeTemplateParameters }) => { const { fills, strokes } = takeColors(colorsCount); const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE6); const groupFills = themeTemplateParameters.get(DEFAULT_HIERARCHY_FILLS4); const groupStrokes = themeTemplateParameters.get(DEFAULT_HIERARCHY_STROKES22); return { fills, strokes, colorRange: defaultColorRange, undocumentedGroupFills: groupFills, undocumentedGroupStrokes: groupStrokes }; } }; var import_ag_charts_community269 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community267 = (init_main4(), __toCommonJS(main_exports)); var import_ag_charts_community266 = (init_main4(), __toCommonJS(main_exports)); var { AbstractBarSeriesProperties: AbstractBarSeriesProperties6, BaseProperties: BaseProperties29, PropertiesArray: PropertiesArray8, SeriesTooltip: SeriesTooltip24, Validate: Validate87, BOOLEAN: BOOLEAN36, COLOR_STRING: COLOR_STRING31, FUNCTION: FUNCTION24, LINE_DASH: LINE_DASH25, NUMBER: NUMBER24, OBJECT: OBJECT47, OBJECT_ARRAY: OBJECT_ARRAY3, POSITIVE_NUMBER: POSITIVE_NUMBER39, RATIO: RATIO37, STRING: STRING44, UNION: UNION18, DropShadow: DropShadow5, Label: Label18 } = import_ag_charts_community266._ModuleSupport; var WaterfallSeriesTotal = class extends BaseProperties29 { }; __decorateClass2([ Validate87(UNION18(["subtotal", "total"], "a total type")) ], WaterfallSeriesTotal.prototype, "totalType", 2); __decorateClass2([ Validate87(NUMBER24) ], WaterfallSeriesTotal.prototype, "index", 2); __decorateClass2([ Validate87(STRING44) ], WaterfallSeriesTotal.prototype, "axisLabel", 2); var WaterfallSeriesItemTooltip = class extends BaseProperties29 { }; __decorateClass2([ Validate87(FUNCTION24, { optional: true }) ], WaterfallSeriesItemTooltip.prototype, "renderer", 2); var WaterfallSeriesLabel = class extends Label18 { constructor() { super(...arguments); this.placement = "outside-end"; this.padding = 6; } }; __decorateClass2([ Validate87(UNION18(["inside-center", "inside-start", "inside-end", "outside-start", "outside-end"], "a placement")) ], WaterfallSeriesLabel.prototype, "placement", 2); __decorateClass2([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesLabel.prototype, "padding", 2); var WaterfallSeriesItem = class extends BaseProperties29 { constructor() { super(...arguments); this.fill = "#c16068"; this.stroke = "#c16068"; this.fillOpacity = 1; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.strokeWidth = 1; this.cornerRadius = 0; this.shadow = new DropShadow5().set({ enabled: false }); this.label = new WaterfallSeriesLabel(); this.tooltip = new WaterfallSeriesItemTooltip(); } }; __decorateClass2([ Validate87(STRING44, { optional: true }) ], WaterfallSeriesItem.prototype, "name", 2); __decorateClass2([ Validate87(COLOR_STRING31) ], WaterfallSeriesItem.prototype, "fill", 2); __decorateClass2([ Validate87(COLOR_STRING31) ], WaterfallSeriesItem.prototype, "stroke", 2); __decorateClass2([ Validate87(RATIO37) ], WaterfallSeriesItem.prototype, "fillOpacity", 2); __decorateClass2([ Validate87(RATIO37) ], WaterfallSeriesItem.prototype, "strokeOpacity", 2); __decorateClass2([ Validate87(LINE_DASH25) ], WaterfallSeriesItem.prototype, "lineDash", 2); __decorateClass2([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesItem.prototype, "lineDashOffset", 2); __decorateClass2([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesItem.prototype, "strokeWidth", 2); __decorateClass2([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesItem.prototype, "cornerRadius", 2); __decorateClass2([ Validate87(FUNCTION24, { optional: true }) ], WaterfallSeriesItem.prototype, "itemStyler", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesItem.prototype, "shadow", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesItem.prototype, "label", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesItem.prototype, "tooltip", 2); var WaterfallSeriesConnectorLine = class extends BaseProperties29 { constructor() { super(...arguments); this.enabled = true; this.stroke = "black"; this.strokeOpacity = 1; this.lineDash = [0]; this.lineDashOffset = 0; this.strokeWidth = 2; } }; __decorateClass2([ Validate87(BOOLEAN36) ], WaterfallSeriesConnectorLine.prototype, "enabled", 2); __decorateClass2([ Validate87(COLOR_STRING31) ], WaterfallSeriesConnectorLine.prototype, "stroke", 2); __decorateClass2([ Validate87(RATIO37) ], WaterfallSeriesConnectorLine.prototype, "strokeOpacity", 2); __decorateClass2([ Validate87(LINE_DASH25) ], WaterfallSeriesConnectorLine.prototype, "lineDash", 2); __decorateClass2([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesConnectorLine.prototype, "lineDashOffset", 2); __decorateClass2([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesConnectorLine.prototype, "strokeWidth", 2); var WaterfallSeriesItems = class extends BaseProperties29 { constructor() { super(...arguments); this.positive = new WaterfallSeriesItem(); this.negative = new WaterfallSeriesItem(); this.total = new WaterfallSeriesItem(); } }; __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesItems.prototype, "positive", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesItems.prototype, "negative", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesItems.prototype, "total", 2); var WaterfallSeriesProperties = class extends AbstractBarSeriesProperties6 { constructor() { super(...arguments); this.item = new WaterfallSeriesItems(); this.totals = new PropertiesArray8(WaterfallSeriesTotal); this.line = new WaterfallSeriesConnectorLine(); this.tooltip = new SeriesTooltip24(); } }; __decorateClass2([ Validate87(STRING44) ], WaterfallSeriesProperties.prototype, "xKey", 2); __decorateClass2([ Validate87(STRING44) ], WaterfallSeriesProperties.prototype, "yKey", 2); __decorateClass2([ Validate87(STRING44, { optional: true }) ], WaterfallSeriesProperties.prototype, "xName", 2); __decorateClass2([ Validate87(STRING44, { optional: true }) ], WaterfallSeriesProperties.prototype, "yName", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesProperties.prototype, "item", 2); __decorateClass2([ Validate87(OBJECT_ARRAY3) ], WaterfallSeriesProperties.prototype, "totals", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesProperties.prototype, "line", 2); __decorateClass2([ Validate87(OBJECT47) ], WaterfallSeriesProperties.prototype, "tooltip", 2); var { adjustLabelPlacement: adjustLabelPlacement2, SeriesNodePickMode: SeriesNodePickMode18, fixNumericExtent: fixNumericExtent10, valueProperty: valueProperty18, keyProperty: keyProperty10, accumulativeValueProperty: accumulativeValueProperty2, trailingAccumulatedValueProperty: trailingAccumulatedValueProperty2, ChartAxisDirection: ChartAxisDirection33, createDatumId: createDatumId25, checkCrisp: checkCrisp3, updateLabelNode: updateLabelNode4, prepareBarAnimationFunctions: prepareBarAnimationFunctions3, collapsedStartingBarPosition: collapsedStartingBarPosition2, resetBarSelectionsFn: resetBarSelectionsFn3, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation7, resetLabelFn: resetLabelFn6, animationValidation: animationValidation9, DEFAULT_CARTESIAN_DIRECTION_KEYS: DEFAULT_CARTESIAN_DIRECTION_KEYS22, DEFAULT_CARTESIAN_DIRECTION_NAMES: DEFAULT_CARTESIAN_DIRECTION_NAMES22, computeBarFocusBounds: computeBarFocusBounds6, isContinuous: isContinuous2, Rect: Rect10, motion: motion10, applyShapeStyle: applyShapeStyle14 } = import_ag_charts_community267._ModuleSupport; var WaterfallSeries = class extends import_ag_charts_community267._ModuleSupport.AbstractBarSeries { constructor(moduleCtx) { super({ moduleCtx, directionKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS22, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES22, pickModes: [SeriesNodePickMode18.NEAREST_NODE, SeriesNodePickMode18.EXACT_SHAPE_MATCH], pathsPerSeries: ["connector"], hasHighlightedLabels: true, pathsZIndexSubOrderOffset: [-1, -1], animationResetFns: { datum: resetBarSelectionsFn3, label: resetLabelFn6 } }); this.properties = new WaterfallSeriesProperties(); this.seriesItemTypes = /* @__PURE__ */ new Set(["positive", "negative", "total"]); } async processData(dataController) { const { xKey, yKey, totals } = this.properties; const { data = [] } = this; if (!this.properties.isValid() || !this.visible) return; const positiveNumber2 = (v) => isContinuous2(v) && Number(v) >= 0; const negativeNumber = (v) => isContinuous2(v) && Number(v) >= 0; const totalTypeValue = (v) => v === "total" || v === "subtotal"; const propertyDefinition = { missingValue: void 0, invalidValue: void 0 }; const dataWithTotals = []; const totalsMap = totals.reduce((result, total) => { const totalsAtIndex = result.get(total.index); if (totalsAtIndex) { totalsAtIndex.push(total); } else { result.set(total.index, [total]); } return result; }, /* @__PURE__ */ new Map()); data.forEach((datum, i) => { dataWithTotals.push(datum); totalsMap.get(i)?.forEach((total) => dataWithTotals.push({ ...total.toJson(), [xKey]: total.axisLabel })); }); const extraProps = []; if (!this.ctx.animationManager.isSkipped()) { extraProps.push(animationValidation9()); } const xScale = this.getCategoryAxis()?.scale; const yScale = this.getValueAxis()?.scale; const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale }); const { processedData } = await this.requestDataModel(dataController, dataWithTotals, { props: [ keyProperty10(xKey, xScaleType, { id: `xValue` }), accumulativeValueProperty2(yKey, yScaleType, { ...propertyDefinition, id: `yCurrent` }), accumulativeValueProperty2(yKey, yScaleType, { ...propertyDefinition, missingValue: 0, id: `yCurrentTotal` }), accumulativeValueProperty2(yKey, yScaleType, { ...propertyDefinition, id: `yCurrentPositive`, validation: positiveNumber2 }), accumulativeValueProperty2(yKey, yScaleType, { ...propertyDefinition, id: `yCurrentNegative`, validation: negativeNumber }), trailingAccumulatedValueProperty2(yKey, yScaleType, { ...propertyDefinition, id: `yPrevious` }), valueProperty18(yKey, yScaleType, { id: `yRaw` }), // Raw value pass-through. valueProperty18("totalType", "band", { id: `totalTypeValue`, missingValue: void 0, validation: totalTypeValue }), ...isContinuousX ? [import_ag_charts_community267._ModuleSupport.SMALLEST_KEY_INTERVAL, import_ag_charts_community267._ModuleSupport.LARGEST_KEY_INTERVAL] : [], ...extraProps ] }); this.smallestDataInterval = processedData.reduced?.smallestKeyInterval; this.largestDataInterval = processedData.reduced?.largestKeyInterval; this.updateSeriesItemTypes(); this.animationState.transition("updateData"); } getSeriesDomain(direction) { const { processedData, dataModel } = this; if (!processedData || !dataModel) return []; const { keys: [keys], values } = processedData.domain; if (direction === this.getCategoryDirection()) { const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`); if (keyDef?.def.type === "key" && keyDef?.def.valueType === "category") { return keys; } const isDirectionY = direction === ChartAxisDirection33.Y; const isReversed = this.getCategoryAxis().isReversed(); return this.padBandExtent(keys, isReversed !== isDirectionY); } else { const yCurrIndex = dataModel.resolveProcessedDataIndexById(this, "yCurrent"); const yExtent = values[yCurrIndex]; const fixedYExtent = [Math.min(0, yExtent[0]), Math.max(0, yExtent[1])]; return fixNumericExtent10(fixedYExtent); } } getSeriesRange(_direction, _visibleRange) { return [NaN, NaN]; } createNodeData() { const { data, dataModel, processedData } = this; const categoryAxis = this.getCategoryAxis(); const valueAxis = this.getValueAxis(); if (!data || !categoryAxis || !valueAxis || !dataModel || !processedData) { return; } const { line } = this.properties; const xScale = categoryAxis.scale; const yScale = valueAxis.scale; const barAlongX = this.getBarDirection() === ChartAxisDirection33.X; const barWidth = this.getBandwidth(categoryAxis) ?? 10; const categoryAxisReversed = categoryAxis.isReversed(); const valueAxisReversed = valueAxis.isReversed(); if (processedData.type !== "ungrouped") return; const context = { itemId: this.properties.yKey, nodeData: [], labelData: [], pointData: [], scales: this.calculateScaling(), visible: this.visible }; if (!this.visible) return context; const pointData = []; const xValues = dataModel.resolveKeysById(this, `xValue`, processedData); const yRawValues = dataModel.resolveColumnById(this, `yRaw`, processedData); const totalTypeValues = dataModel.resolveColumnById( this, `totalTypeValue`, processedData ); const yCurrValues = dataModel.resolveColumnById(this, "yCurrent", processedData); const yPrevValues = dataModel.resolveColumnById(this, "yPrevious", processedData); const yCurrTotalValues = dataModel.resolveColumnById(this, "yCurrentTotal", processedData); const crisp = checkCrisp3( categoryAxis?.scale, categoryAxis?.visibleRange, this.smallestDataInterval, this.largestDataInterval ); function getValues(isTotal, isSubtotal, datumIndex) { if (isTotal || isSubtotal) { return { cumulativeValue: yCurrTotalValues[datumIndex], trailingValue: isSubtotal ? trailingSubtotal : 0 }; } return { cumulativeValue: yCurrValues[datumIndex], trailingValue: yPrevValues[datumIndex] }; } function getValue(isTotal, isSubtotal, rawValue, cumulativeValue, trailingValue) { if (isTotal) { return cumulativeValue; } if (isSubtotal) { return (cumulativeValue ?? 0) - (trailingValue ?? 0); } return rawValue; } let trailingSubtotal = 0; const { xKey, yKey, xName, yName } = this.properties; const rawData = processedData.dataSources.get(this.id) ?? []; rawData.forEach((datum, datumIndex) => { const datumType = totalTypeValues[datumIndex]; const isSubtotal = this.isSubtotal(datumType); const isTotal = this.isTotal(datumType); const isTotalOrSubtotal = isTotal || isSubtotal; const xDatum = xValues[datumIndex]; if (xDatum == null) return; const x = Math.round(xScale.convert(xDatum)); const rawValue = yRawValues[datumIndex]; const { cumulativeValue, trailingValue } = getValues(isTotal, isSubtotal, datumIndex); if (isTotalOrSubtotal) { trailingSubtotal = cumulativeValue ?? 0; } const currY = Math.round(yScale.convert(cumulativeValue)); const trailY = Math.round(yScale.convert(trailingValue)); const value = getValue(isTotal, isSubtotal, rawValue, cumulativeValue, trailingValue); const isPositive = (value ?? 0) >= 0; const seriesItemType = this.getSeriesItemType(isPositive, datumType); const { strokeWidth, label } = this.getItemConfig(seriesItemType); const y = isPositive ? currY : trailY; const bottomY = isPositive ? trailY : currY; const barHeight = Math.max(strokeWidth, Math.abs(bottomY - y)); const rect = { x: barAlongX ? Math.min(y, bottomY) : x, y: barAlongX ? x : Math.min(y, bottomY), width: barAlongX ? barHeight : barWidth, height: barAlongX ? barWidth : barHeight }; const nodeMidPoint = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }; const pointY = isTotalOrSubtotal ? currY : trailY; const pixelAlignmentOffset = Math.floor(line.strokeWidth) % 2 / 2; const startY = categoryAxisReversed ? currY : pointY; const stopY = categoryAxisReversed ? pointY : currY; let startCoordinates; let stopCoordinates; if (barAlongX) { startCoordinates = { x: startY + pixelAlignmentOffset, y: rect.y }; stopCoordinates = { x: stopY + pixelAlignmentOffset, y: rect.y + rect.height }; } else { startCoordinates = { x: rect.x, y: startY + pixelAlignmentOffset }; stopCoordinates = { x: rect.x + rect.width, y: stopY + pixelAlignmentOffset }; } const pathPoint = { // lineTo x: categoryAxisReversed ? stopCoordinates.x : startCoordinates.x, y: categoryAxisReversed ? stopCoordinates.y : startCoordinates.y, // moveTo x2: categoryAxisReversed ? startCoordinates.x : stopCoordinates.x, y2: categoryAxisReversed ? startCoordinates.y : stopCoordinates.y, size: 0 }; pointData.push(pathPoint); const itemId = seriesItemType === "subtotal" ? "total" : seriesItemType; const labelText = this.getLabelText(label, { itemId, value, datum, xKey, yKey, xName, yName }); const nodeDatum = { index: datumIndex, series: this, itemId: seriesItemType, datum, datumIndex, cumulativeValue: cumulativeValue ?? 0, xValue: xDatum, yValue: value, yKey, xKey, x: rect.x, y: rect.y, width: rect.width, height: rect.height, midPoint: nodeMidPoint, crisp, label: { text: labelText, ...adjustLabelPlacement2({ isUpward: (value ?? -1) >= 0 !== valueAxisReversed, isVertical: !barAlongX, placement: label.placement, padding: label.padding, rect }) } }; context.nodeData.push(nodeDatum); context.labelData.push(nodeDatum); }); const connectorLinesEnabled = this.properties.line.enabled; if (yCurrValues != null && connectorLinesEnabled) { context.pointData = pointData; } return context; } updateSeriesItemTypes() { const { dataModel, seriesItemTypes, processedData } = this; if (!dataModel || !processedData) { return; } seriesItemTypes.clear(); const yPositiveIndex = dataModel.resolveProcessedDataIndexById(this, "yCurrentPositive"); const yNegativeIndex = dataModel.resolveProcessedDataIndexById(this, "yCurrentNegative"); const totalTypeIndex = dataModel.resolveProcessedDataIndexById(this, `totalTypeValue`); const positiveDomain = processedData.domain.values[yPositiveIndex] ?? []; const negativeDomain = processedData.domain.values[yNegativeIndex] ?? []; if (positiveDomain.length > 0) { seriesItemTypes.add("positive"); } if (negativeDomain.length > 0) { seriesItemTypes.add("negative"); } const itemTypes = processedData?.domain.values[totalTypeIndex]; if (!itemTypes) { return; } itemTypes.forEach((type) => { if (type === "total" || type === "subtotal") { seriesItemTypes.add("total"); } }); } isSubtotal(datumType) { return datumType === "subtotal"; } isTotal(datumType) { return datumType === "total"; } nodeFactory() { return new Rect10(); } getSeriesItemType(isPositive, datumType) { return datumType ?? (isPositive ? "positive" : "negative"); } getItemConfig(seriesItemType) { switch (seriesItemType) { case "positive": { return this.properties.item.positive; } case "negative": { return this.properties.item.negative; } case "subtotal": case "total": { return this.properties.item.total; } } } updateDatumSelection(opts) { const { nodeData, datumSelection } = opts; const data = nodeData ?? []; return datumSelection.update(data); } getItemStyle(datumId, datum, itemId, highlighted) { const { id: seriesId, properties } = this; const item = properties.item[itemId === "subtotal" ? "total" : itemId]; const highlightStyle = highlighted ? properties.highlightStyle.item : void 0; const { itemStyler } = item; const { xKey, yKey } = properties; const format = { fill: highlightStyle?.fill ?? item.fill, fillOpacity: highlightStyle?.fillOpacity ?? item.fillOpacity, stroke: highlightStyle?.stroke ?? item.stroke, strokeWidth: highlightStyle?.strokeWidth ?? item.strokeWidth, strokeOpacity: highlightStyle?.strokeOpacity ?? item.strokeOpacity, lineDash: highlightStyle?.lineDash ?? item.lineDash ?? [], lineDashOffset: highlightStyle?.lineDashOffset ?? item.lineDashOffset, cornerRadius: item.cornerRadius }; if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId25(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, itemId, datum, xKey, yKey, highlighted, ...format }); } ); Object.assign(format, itemStyle); } return format; } updateDatumNodes(opts) { const { datumSelection, isHighlight } = opts; const categoryAlongX = this.getCategoryDirection() === ChartAxisDirection33.X; datumSelection.each((rect, datum) => { const seriesItemType = datum.itemId; const style = this.getItemStyle(String(datum.datumIndex), datum.datum, seriesItemType, isHighlight); applyShapeStyle14(rect, style); rect.visible = categoryAlongX ? datum.width > 0 : datum.height > 0; rect.crisp = datum.crisp; }); } updateLabelSelection(opts) { const { labelData, labelSelection } = opts; if (labelData.length === 0) { return labelSelection.update([]); } const data = labelData.filter((labelDatum) => { const { label } = this.getItemConfig(labelDatum.itemId); return label.enabled; }); return labelSelection.update(data); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode4(textNode, this.getItemConfig(datum.itemId).label, datum.label); }); } getTooltipContent(nodeDatum) { const { id: seriesId, dataModel, processedData, properties } = this; const { xKey, xName, yKey, yName, tooltip } = properties; const xAxis = this.getCategoryAxis(); const yAxis = this.getValueAxis(); if (!dataModel || !processedData || !xAxis || !yAxis) return; const { datumIndex } = nodeDatum; const datum = processedData.dataSources.get(this.id)?.[datumIndex]; const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex]; const yValue = dataModel.resolveColumnById(this, `yRaw`, processedData)[datumIndex]; const yCurrTotalValues = dataModel.resolveColumnById(this, "yCurrentTotal", processedData); const totalTypeValues = dataModel.resolveColumnById( this, `totalTypeValue`, processedData ); if (xValue == null) return; const datumType = totalTypeValues[datumIndex]; const isPositive = (yValue ?? 0) >= 0; const seriesItemType = this.getSeriesItemType(isPositive, datumType); let total; if (this.isTotal(datumType)) { total = yCurrTotalValues[datumIndex]; } else if (this.isSubtotal(datumType)) { total = yCurrTotalValues[datumIndex]; for (let previousIndex = datumIndex - 1; previousIndex >= 0; previousIndex -= 1) { if (this.isSubtotal(totalTypeValues[previousIndex])) { total = total - yCurrTotalValues[previousIndex]; break; } } } else { total = yValue; } const format = this.getItemStyle(String(datumIndex), datum, seriesItemType, false); return tooltip.formatTooltip( { heading: xAxis.formatDatum(xValue), symbol: this.legendItemSymbol(seriesItemType), data: [{ label: yName, fallbackLabel: yKey, value: yAxis.formatDatum(total) }] }, { seriesId, datum, title: yName, itemId: seriesItemType, xKey, xName, yKey, yName, ...format } ); } legendItemSymbol(item) { const { fill, stroke: stroke22, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.getItemConfig(item); return { marker: { fill, stroke: stroke22, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (legendType !== "category") { return []; } const { id, seriesItemTypes } = this; const legendData = []; const capitalise = (text22) => text22.charAt(0).toUpperCase() + text22.substring(1); const { showInLegend } = this.properties; seriesItemTypes.forEach((item) => { const { name } = this.getItemConfig(item); legendData.push({ legendType: "category", id, itemId: item, seriesId: id, enabled: true, label: { text: name ?? capitalise(item) }, symbol: this.legendItemSymbol(item), hideInLegend: !showInLegend, isFixed: true }); }); return legendData; } toggleSeriesItem() { } animateEmptyUpdateReady({ datumSelection, labelSelection, contextData, paths }) { const fns = prepareBarAnimationFunctions3(collapsedStartingBarPosition2(this.isVertical(), this.axes, "normal")); motion10.fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], fns); seriesLabelFadeInAnimation7(this, "labels", this.ctx.animationManager, labelSelection); const { pointData } = contextData; if (!pointData) return; const [lineNode] = paths; if (this.isVertical()) { this.animateConnectorLinesVertical(lineNode, pointData); } else { this.animateConnectorLinesHorizontal(lineNode, pointData); } } animateConnectorLinesHorizontal(lineNode, pointData) { const { path: linePath } = lineNode; this.updateLineNode(lineNode); const valueAxis = this.getValueAxis(); const valueAxisReversed = valueAxis?.isReversed(); const compare = valueAxisReversed ? (v, v2) => v < v2 : (v, v2) => v > v2; const startX = valueAxis?.scale.convert(0); const endX = pointData.reduce( (end2, point) => { if (compare(point.x, end2)) { end2 = point.x; } return end2; }, valueAxisReversed ? Infinity : 0 ); const scale2 = (value, start1, end1, start2, end2) => { return (value - start1) / (end1 - start1) * (end2 - start2) + start2; }; this.ctx.animationManager.animate({ id: `${this.id}_connectors`, groupId: this.id, phase: "initial", from: startX, to: endX, ease: import_ag_charts_community267._ModuleSupport.Motion.easeOut, collapsable: false, onUpdate(pointX) { linePath.clear(true); pointData.forEach((point, index) => { const x = scale2(pointX, startX, endX, startX, point.x); const x2 = scale2(pointX, startX, endX, startX, point.x2); if (index !== 0) { linePath.lineTo(x, point.y); } linePath.moveTo(x2, point.y2); }); lineNode.checkPathDirty(); } }); } animateConnectorLinesVertical(lineNode, pointData) { const { path: linePath } = lineNode; this.updateLineNode(lineNode); const valueAxis = this.getValueAxis(); const valueAxisReversed = valueAxis?.isReversed(); const compare = valueAxisReversed ? (v, v2) => v > v2 : (v, v2) => v < v2; const startY = valueAxis?.scale.convert(0); const endY = pointData.reduce( (end2, point) => { if (compare(point.y, end2)) { end2 = point.y; } return end2; }, valueAxisReversed ? 0 : Infinity ); const scale2 = (value, start1, end1, start2, end2) => { return (value - start1) / (end1 - start1) * (end2 - start2) + start2; }; this.ctx.animationManager.animate({ id: `${this.id}_connectors`, groupId: this.id, phase: "initial", from: startY, to: endY, ease: import_ag_charts_community267._ModuleSupport.Motion.easeOut, collapsable: false, onUpdate(pointY) { linePath.clear(true); pointData.forEach((point, index) => { const y = scale2(pointY, startY, endY, startY, point.y); const y2 = scale2(pointY, startY, endY, startY, point.y2); if (index !== 0) { linePath.lineTo(point.x, y); } linePath.moveTo(point.x2, y2); }); lineNode.checkPathDirty(); } }); } animateReadyResize(data) { super.animateReadyResize(data); this.resetConnectorLinesPath(data); } updatePaths(opts) { this.resetConnectorLinesPath({ contextData: opts.contextData, paths: opts.paths }); } resetConnectorLinesPath({ contextData, paths }) { if (paths.length === 0) { return; } const [lineNode] = paths; this.updateLineNode(lineNode); const { path: linePath } = lineNode; linePath.clear(true); const { pointData } = contextData; if (!pointData) { return; } pointData.forEach((point, index) => { if (index !== 0) { linePath.lineTo(point.x, point.y); } linePath.moveTo(point.x2, point.y2); }); lineNode.checkPathDirty(); } updateLineNode(lineNode) { const { stroke: stroke22, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties.line; lineNode.setProperties({ fill: void 0, stroke: stroke22, strokeWidth: this.getStrokeWidth(strokeWidth), strokeOpacity, lineDash, lineDashOffset, lineJoin: "round", pointerEvents: import_ag_charts_community267._ModuleSupport.PointerEvents.None }); } isLabelEnabled() { const { positive, negative, total } = this.properties.item; return positive.label.enabled || negative.label.enabled || total.label.enabled; } onDataChange() { } computeFocusBounds({ datumIndex }) { return computeBarFocusBounds6(this, this.contextNodeData?.nodeData[datumIndex]); } }; WaterfallSeries.className = "WaterfallSeries"; WaterfallSeries.type = "waterfall"; var import_ag_charts_community268 = (init_main4(), __toCommonJS(main_exports)); var itemTheme = { strokeWidth: 0, label: { enabled: false, fontStyle: void 0, fontWeight: { $ref: "fontWeight" }, fontSize: { $ref: "fontSize" }, fontFamily: { $ref: "fontFamily" }, color: { $ref: "textColor" }, formatter: void 0, placement: "outside-end" } }; var WATERFALL_SERIES_THEME = { series: { item: { positive: itemTheme, negative: itemTheme, total: itemTheme }, line: { stroke: import_ag_charts_community268._ModuleSupport.ThemeSymbols.PALETTE_NEUTRAL_STROKE, strokeOpacity: 1, lineDash: [0], lineDashOffset: 0, strokeWidth: 2 } }, legend: { enabled: true, toggleSeries: false } }; var { ThemeConstants } = import_ag_charts_community269._ModuleSupport; var WaterfallModule = { type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "waterfall", solo: true, moduleFactory: (ctx) => new WaterfallSeries(ctx), tooltipDefaults: { range: "exact" }, defaultAxes: import_ag_charts_community269._ModuleSupport.swapAxisCondition( [ { type: ThemeConstants.CARTESIAN_AXIS_TYPE.NUMBER, position: ThemeConstants.CARTESIAN_POSITION.LEFT }, { type: ThemeConstants.CARTESIAN_AXIS_TYPE.CATEGORY, position: ThemeConstants.CARTESIAN_POSITION.BOTTOM } ], (series) => series?.direction === "horizontal" ), themeTemplate: WATERFALL_SERIES_THEME, paletteFactory: ({ takeColors, colorsCount, userPalette, palette }) => { if (userPalette === "user-indexed") { const { fills, strokes } = takeColors(colorsCount); return { line: { stroke: palette.neutral.stroke }, item: { positive: { fill: fills[0], stroke: strokes[0] }, negative: { fill: fills[1], stroke: strokes[1] }, total: { fill: fills[2], stroke: strokes[2] } } }; } return { line: { stroke: palette.neutral.stroke }, item: { positive: { fill: palette.altUp.fill, stroke: palette.altUp.stroke, label: { color: { $ref: "textColor" } } }, negative: { fill: palette.altDown.fill, stroke: palette.altDown.stroke, label: { color: { $ref: "textColor" } } }, total: { fill: palette.neutral.fill, stroke: palette.neutral.stroke, label: { color: { $ref: "textColor" } } } } }; } }; var styles_default2 = `.ag-watermark{position:absolute;bottom:20px;right:25px;font-weight:700;font-family:Impact,sans-serif;font-size:19px;opacity:.7;animation:1s ease-out 3s ag-watermark-fadeout;color:#9b9b9b;pointer-events:none;&:before{content:"";display:block;height:40px;width:170px;background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjU4IiBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMjU4IDQwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjUuNzc5IDI4LjY1N0gxMy4zNTlMMTEuMTczIDM0LjAxMkg1LjY3Mjk3TDE3LjE4MiA3LjA1OTk5SDIxLjk1M0wzMy40NjIgMzQuMDEySDI3Ljk2MkwyNS43NzYgMjguNjU3SDI1Ljc3OVpNMjQuMDY4IDI0LjM5N0wxOS41ODggMTMuNDM0TDE1LjEwNyAyNC4zOTdIMjQuMDY4Wk02Mi4wOTIgMTguODIzSDQ5LjgxN1YyMy4wODZINTYuNzc1QzU2LjU1NSAyNS4yMjIgNTUuNzU1IDI2LjkyNyA1NC4zNzIgMjguMjAyQzUyLjk4OSAyOS40NzYgNTEuMTY2IDMwLjExNSA0OC45MDkgMzAuMTE1QzQ3LjYyMiAzMC4xMTUgNDYuNDUgMjkuODg1IDQ1LjM5MyAyOS40MjNDNDQuMzU4MyAyOC45NzgxIDQzLjQzMjYgMjguMzEzOCA0Mi42OCAyNy40NzZDNDEuOTI3IDI2LjYzOSA0MS4zNDQgMjUuNjMxIDQwLjkzMSAyNC40NTNDNDAuNTE5IDIzLjI3NSA0MC4zMTEgMjEuOTcgNDAuMzExIDIwLjUzN0M0MC4zMTEgMTkuMTA1IDQwLjUxNiAxNy44IDQwLjkzMSAxNi42MjFDNDEuMzQ0IDE1LjQ0MyA0MS45MjcgMTQuNDM2IDQyLjY4IDEzLjU5OEM0My40Mzc2IDEyLjc1NzcgNDQuMzY5NiAxMi4wOTMyIDQ1LjQxMSAxMS42NTFDNDYuNDc4IDExLjE4OSA0Ny42NTYgMTAuOTYgNDguOTQ2IDEwLjk2QzUxLjYxMiAxMC45NiA1My42MzcgMTEuNjAyIDU1LjAyIDEyLjg4NUw1OC4zIDkuNjA0OTlDNTUuODE3IDcuNjY5OTkgNTIuNjc2IDYuNjk5OTkgNDguODcyIDYuNjk5OTlDNDYuNzYgNi42OTk5OSA0NC44NTMgNy4wMzQ5OSA0My4xNTQgNy43MDA5OUM0MS40NTUgOC4zNjc5OSAzOS45OTggOS4zMDM5OSAzOC43ODMgMTAuNTA0QzM3LjU2NyAxMS43MDcgMzYuNjM0IDEzLjE1OCAzNS45NzcgMTQuODU3QzM1LjMxOSAxNi41NTYgMzQuOTk0IDE4LjQ1MSAzNC45OTQgMjAuNTRDMzQuOTk0IDIyLjYzIDM1LjMyOSAyNC40OTQgMzUuOTk1IDI2LjIwNUMzNi42NjIgMjcuOTE2IDM3LjYwNSAyOS4zNzQgMzguODE3IDMwLjU3N0M0MC4wMzIgMzEuNzggNDEuNDg2IDMyLjcxMyA0My4xODggMzMuMzgzQzQ0Ljg4OCAzNC4wNDkgNDYuNzgyIDM0LjM4NCA0OC44NzIgMzQuMzg0QzUwLjk2MSAzNC4zODQgNTIuNzUgMzQuMDQ5IDU0LjM5IDMzLjM4M0M1Ni4wMzEgMzIuNzE2IDU3LjQyNiAzMS43OCA1OC41NzkgMzAuNTc3QzU5LjczMyAyOS4zNzQgNjAuNjE5IDI3LjkxNiA2MS4yMzkgMjYuMjA1QzYxLjg2IDI0LjQ5NCA2Mi4xNyAyMi42MDUgNjIuMTcgMjAuNTRDNjIuMTY5NiAxOS45Njg4IDYyLjE0NDUgMTkuMzk4IDYyLjA5NSAxOC44MjlMNjIuMDkyIDE4LjgyM1pNMTUxLjgxIDE2Ljk4MUMxNTMuNDEgMTQuNjA5IDE1Ny40MTkgMTQuMzU4IDE1OS4wMjIgMTQuMzU4VjE4LjkxQzE1Ni45NTcgMTguOTEgMTU0Ljk4NSAxOC45OTYgMTUzLjc1NyAxOS44OTJDMTUyLjUyOSAyMC43OTIgMTUxLjkxOSAyMS45ODIgMTUxLjkxOSAyMy40NjRWMzMuOTlIMTQ2Ljk2NFYxNC4zNThIMTUxLjczNkwxNTEuODEgMTYuOTgxWk0xNDMuMDExIDE0LjM2MVYzNC4wMzFIMTM4LjI0TDEzOC4xMzEgMzEuMDQ1QzEzNy40NjYgMzIuMDc2IDEzNi41NTEgMzIuOTIxOSAxMzUuNDcxIDMzLjUwNEMxMzQuMzc2IDM0LjA5OSAxMzMuMDY4IDM0LjM5NiAxMzEuNTM2IDM0LjM5NkMxMzAuMiAzNC4zOTYgMTI4Ljk2MyAzNC4xNTIgMTI3LjgyMiAzMy42NjhDMTI2LjcgMzMuMTk2NCAxMjUuNjg5IDMyLjQ5NSAxMjQuODU1IDMxLjYwOUMxMjQuMDE4IDMwLjcyMiAxMjMuMzU0IDI5LjY2MiAxMjIuODcxIDI4LjQyMkMxMjIuMzg0IDI3LjE4NSAxMjIuMTQyIDI1LjgxMSAxMjIuMTQyIDI0LjMwNEMxMjIuMTQyIDIyLjc5OCAxMjIuMzg0IDIxLjM3OCAxMjIuODcxIDIwLjExNkMxMjMuMzU3IDE4Ljg1NCAxMjQuMDE4IDE3Ljc3MiAxMjQuODU1IDE2Ljg3M0MxMjUuNjg4IDE1Ljk3NjQgMTI2LjY5OCAxNS4yNjM2IDEyNy44MjIgMTQuNzhDMTI4Ljk2MyAxNC4yODEgMTMwLjIwMyAxNC4wMzMgMTMxLjUzNiAxNC4wMzNDMTMzLjA0MyAxNC4wMzMgMTM0LjMzIDE0LjMxOCAxMzUuMzk3IDE0Ljg4OEMxMzYuNDYyIDE1LjQ1ODkgMTM3LjM3NSAxNi4yNzggMTM4LjA1NyAxNy4yNzZWMTQuMzYxSDE0My4wMTFaTTEzMi42MzEgMzAuMTMzQzEzNC4yNTYgMzAuMTMzIDEzNS41NjcgMjkuNTk0IDEzNi41NjUgMjguNTEyQzEzNy41NjEgMjcuNDMgMTM4LjA2IDI1Ljk5MSAxMzguMDYgMjQuMTk2QzEzOC4wNiAyMi40MDEgMTM3LjU2MSAyMC45OSAxMzYuNTY1IDE5Ljg5OUMxMzUuNTcgMTguODA3IDEzNC4yNTkgMTguMjU4IDEzMi42MzEgMTguMjU4QzEzMS4wMDMgMTguMjU4IDEyOS43MjkgMTguODA0IDEyOC43MzQgMTkuODk5QzEyNy43MzggMjAuOTkzIDEyNy4yMzkgMjIuNDM4IDEyNy4yMzkgMjQuMjMzQzEyNy4yMzkgMjYuMDI4IDEyNy43MzUgMjcuNDMzIDEyOC43MzQgMjguNTE1QzEyOS43MjkgMjkuNTk0IDEzMS4wMjggMzAuMTM2IDEzMi42MzEgMzAuMTM2VjMwLjEzM1pNOTMuNjk4IDI3Ljg3NkM5My41Nzk1IDI4LjAwMjUgOTMuNDU2NCAyOC4xMjQ2IDkzLjMyOSAyOC4yNDJDOTEuOTQ3IDI5LjUxNiA5MC4xMjMgMzAuMTU1IDg3Ljg2NiAzMC4xNTVDODYuNTggMzAuMTU1IDg1LjQwOCAyOS45MjYgODQuMzUgMjkuNDY0QzgzLjMxNTUgMjkuMDE4OSA4Mi4zODk4IDI4LjM1NDYgODEuNjM3IDI3LjUxN0M4MC44ODQgMjYuNjc5IDgwLjMwMSAyNS42NzIgNzkuODg5IDI0LjQ5NEM3OS40NzYgMjMuMzE1IDc5LjI2OSAyMi4wMSA3OS4yNjkgMjAuNTc4Qzc5LjI2OSAxOS4xNDUgNzkuNDczIDE3Ljg0IDc5Ljg4OSAxNi42NjJDODAuMzAxIDE1LjQ4NCA4MC44ODQgMTQuNDc2IDgxLjYzNyAxMy42MzlDODIuMzk0OSAxMi43OTg3IDgzLjMyNzMgMTIuMTM0MiA4NC4zNjkgMTEuNjkyQzg1LjQzNiAxMS4yMyA4Ni42MTQgMTEgODcuOTAzIDExQzkwLjU3IDExIDkyLjU5NSAxMS42NDIgOTMuOTc3IDEyLjkyNkw5Ny4yNTggOS42NDQ5OUM5NC43NzQgNy43MTA5OSA5MS42MzMgNi43Mzk5OSA4Ny44MjkgNi43Mzk5OUM4NS43MTggNi43Mzk5OSA4My44MTEgNy4wNzQ5OSA4Mi4xMTIgNy43NDE5OUM4MC40MTMgOC40MDc5OSA3OC45NTYgOS4zNDQ5OSA3Ny43NCAxMC41NDVDNzYuNTI1IDExLjc0NyA3NS41OTIgMTMuMTk5IDc0LjkzNCAxNC44OThDNzQuMjc3IDE2LjU5NyA3My45NTEgMTguNDkxIDczLjk1MSAyMC41ODFDNzMuOTUxIDIyLjY3IDc0LjI4NiAyNC41MzQgNzQuOTUzIDI2LjI0NUM3NS42MTkgMjcuOTU3IDc2LjU2MiAyOS40MTQgNzcuNzc0IDMwLjYxN0M3OC45OSAzMS44MiA4MC40NDQgMzIuNzUzIDgyLjE0NiAzMy40MjNDODMuODQ1IDM0LjA5IDg1LjczOSAzNC40MjQgODcuODI5IDM0LjQyNEM4OS45MTkgMzQuNDI0IDkxLjcwOCAzNC4wOSA5My4zNDggMzMuNDIzQzk0LjcxOCAzMi44NjUgOTUuOTE4IDMyLjEyMSA5Ni45NDggMzEuMTkxQzk3LjE0OSAzMS4wMDggOTcuMzQ4IDMwLjgxNSA5Ny41MzcgMzAuNjJMOTMuNzAxIDI3Ljg4NUw5My42OTggMjcuODc2Wk0xMTAuODAyIDE0LjAxNUMxMDkuMTk5IDE0LjAxNSAxMDYuODM2IDE0LjQ3MSAxMDUuNjExIDE2LjE1OEwxMDUuNTM3IDYuMDE1OTlIMTAwLjc2NVYzMy45MzlIMTA1LjcyVjIyLjY0MUMxMDUuNzcxIDIxLjQ2MDcgMTA2LjI4OCAyMC4zNDg4IDEwNy4xNTcgMTkuNTQ4OUMxMDguMDI3IDE4Ljc0OTEgMTA5LjE3OCAxOC4zMjY2IDExMC4zNTggMTguMzc0QzExMy4zOTcgMTguMzc0IDExNC4yNjggMjEuMTU5IDExNC4yNjggMjIuNjQxVjMzLjkzOUgxMTkuMjIzVjIxLjA1OUMxMTkuMjIzIDIxLjA1OSAxMTkuMTQyIDE0LjAxNSAxMTAuODAyIDE0LjAxNVpNMTczLjc2MyAxNC4zNThIMTY5Ljk5OVY4LjcxNDk5SDE2NS4wNDhWMTQuMzU4SDE2MS4yODRWMTguOTE2SDE2NS4wNDhWMzQuMDAzSDE2OS45OTlWMTguOTE2SDE3My43NjNWMTQuMzU4Wk0xOTAuNzg3IDI1LjI2MkMxOTAuMTI5IDI0LjUwMTQgMTg5LjMwNyAyMy44OTk0IDE4OC4zODQgMjMuNTAxQzE4Ny40ODggMjMuMTE3IDE4Ni4zMzEgMjIuNzMyIDE4NC45NDggMjIuMzY0QzE4NC4xNjUgMjIuMTQzOSAxODMuMzkgMjEuODk3OCAxODIuNjIzIDIxLjYyNkMxODIuMTYzIDIxLjQ2MjEgMTgxLjc0MSAyMS4yMDY2IDE4MS4zODMgMjAuODc1QzE4MS4yMzUgMjAuNzQyMSAxODEuMTE4IDIwLjU3ODkgMTgxLjAzOSAyMC4zOTY0QzE4MC45NjEgMjAuMjE0IDE4MC45MjIgMjAuMDE2NiAxODAuOTI3IDE5LjgxOEMxODAuOTI3IDE5LjI3MiAxODEuMTU2IDE4Ljg0NCAxODEuNjI1IDE4LjUxQzE4Mi4xMjEgMTguMTU2IDE4Mi44NjIgMTcuOTc2IDE4My44MjYgMTcuOTc2QzE4NC43OSAxNy45NzYgMTg1LjU4NyAxOC4yMDkgMTg2LjE0OCAxOC42NjhDMTg2LjcwNiAxOS4xMjQgMTg3LjAwNyAxOS43MjUgMTg3LjA3MiAyMC41TDE4Ny4wOTQgMjAuNzgySDE5MS42MzNMMTkxLjYxNyAyMC40NkMxOTEuNTIxIDE4LjQ4NSAxOTAuNzcxIDE2LjkgMTg5LjM4NSAxNS43NUMxODguMDEyIDE0LjYxMiAxODYuMTg1IDE0LjAzMyAxODMuOTYyIDE0LjAzM0MxODIuNDc3IDE0LjAzMyAxODEuMTQxIDE0LjI4NyAxNzkuOTk0IDE0Ljc4NkMxNzguODMxIDE1LjI5MSAxNzcuOTI2IDE1Ljk5NSAxNzcuMjk2IDE2Ljg4MkMxNzYuNjczIDE3Ljc0NTUgMTc2LjMzOCAxOC43ODQgMTc2LjM0MSAxOS44NDlDMTc2LjM0MSAyMS4xNjcgMTc2LjY5OCAyMi4yNDkgMTc3LjM5OSAyMy4wNjRDMTc4LjA2IDIzLjg0MzIgMTc4Ljg5OCAyNC40NTM0IDE3OS44NDIgMjQuODQ0QzE4MC43NDQgMjUuMjE2IDE4MS45MjggMjUuNjA3IDE4My4zNjEgMjZDMTg0LjgwNiAyNi40MSAxODUuODcyIDI2Ljc4NSAxODYuNTMgMjcuMTIzQzE4Ny4xIDI3LjQxNCAxODcuMzc5IDI3Ljg0NSAxODcuMzc5IDI4LjQ0NEMxODcuMzc5IDI5LjA0MiAxODcuMTIyIDI5LjQ2NyAxODYuNTk1IDI5LjgzOUMxODYuMDQzIDMwLjIyNiAxODUuMjM3IDMwLjQyNSAxODQuMjAxIDMwLjQyNUMxODMuMTY2IDMwLjQyNSAxODIuMzk0IDMwLjE3NCAxODEuNzQ5IDI5LjY3NEMxODEuMTEzIDI5LjE4MSAxODAuNzcyIDI4LjU4OSAxODAuNzEgMjcuODY0TDE4MC42ODUgMjcuNTgySDE3Ni4wMTNMMTc2LjAyNSAyNy45MDFDMTc2LjA2NyAyOS4wOTU1IDE3Ni40NzIgMzAuMjQ4NyAxNzcuMTg4IDMxLjIwNkMxNzcuOTA3IDMyLjE4IDE3OC44OTMgMzIuOTU4IDE4MC4xMTggMzMuNTE5QzE4MS4zMzYgMzQuMDc3IDE4Mi43MzIgMzQuMzYyIDE4NC4yNjYgMzQuMzYyQzE4NS44MDEgMzQuMzYyIDE4Ny4xMDkgMzQuMTA4IDE4OC4yMzggMzMuNjA5QzE4OS4zNzYgMzMuMTA0IDE5MC4yNzIgMzIuMzk0IDE5MC45MDEgMzEuNDk0QzE5MS41MzQgMzAuNTkyIDE5MS44NTMgMjkuNTU0IDE5MS44NTMgMjguNDAzQzE5MS44MjggMjcuMTEgMTkxLjQ2NiAyNi4wNTMgMTkwLjc3NyAyNS4yNjJIMTkwLjc4N1oiIGZpbGw9IiM5QjlCOUIiLz4KPHBhdGggZD0iTTI0MS45ODIgMjUuNjU4MlYxNy43MTE3SDIyOC40NDFMMjIwLjQ5NCAyNS42NTgySDI0MS45ODJaIiBmaWxsPSIjOUI5QjlCIi8+CjxwYXRoIGQ9Ik0yNTcuMjM5IDUuOTUwODFIMjQwLjI2NUwyMzIuMjU1IDEzLjg5NzNIMjU3LjIzOVY1Ljk1MDgxWiIgZmlsbD0iIzlCOUI5QiIvPgo8cGF0aCBkPSJNMjEyLjYxMSAzMy42MDQ4TDIxNi42OCAyOS41MzYxSDIzMC40MTJWMzcuNDgyN0gyMTIuNjExVjMzLjYwNDhaIiBmaWxsPSIjOUI5QjlCIi8+CjxwYXRoIGQ9Ik0yMTUuNTk5IDIxLjc4MDNIMjI0LjM3MkwyMzIuMzgyIDEzLjgzMzdIMjE1LjU5OVYyMS43ODAzWiIgZmlsbD0iIzlCOUI5QiIvPgo8cGF0aCBkPSJNMjA2IDMzLjYwNDdIMjEyLjYxMUwyMjAuNDk0IDI1LjY1ODJIMjA2VjMzLjYwNDdaIiBmaWxsPSIjOUI5QjlCIi8+CjxwYXRoIGQ9Ik0yNDAuMjY1IDUuOTUwODFMMjM2LjE5NyAxMC4wMTk0SDIxMC4yNTlWMi4wNzI4OEgyNDAuMjY1VjUuOTUwODFaIiBmaWxsPSIjOUI5QjlCIi8+Cjwvc3ZnPgo=);background-repeat:no-repeat;background-size:170px 40px}>span{padding-left:.7rem}}@keyframes ag-watermark-fadeout{0%{opacity:.5}to{opacity:0}}.ag-charts-dialog{display:flex;flex-direction:column;font-size:var(--ag-charts-chrome-font-size-large)}.ag-charts-dialog__tabs{display:flex;flex-direction:column}.ag-charts-dialog__header{border-bottom:1px solid var(--ag-charts-border-color);display:flex}.ag-charts-dialog__tab-list{display:flex;gap:calc(var(--ag-charts-spacing) * 2)}.ag-charts-dialog__drag-handle{align-items:center;color:inherit;cursor:grab;display:flex;padding:1px 6px;text-align:center}.ag-charts-dialog__drag-handle--dragging{cursor:grabbing}.ag-charts-dialog__tab-button{background:none;border:0;border-bottom:2px solid transparent;border-radius:0;color:var(--ag-charts-chrome-subtle-text-color);margin-bottom:-1px;padding:var(--input-padding) calc(var(--input-padding) / 2)}.ag-charts-dialog__tab-button:hover{background:none}.ag-charts-dialog__tab-button--active{border-color:var(--ag-charts-accent-color);color:inherit}.ag-charts-dialog__drag-handle+.ag-charts-dialog__tab-button{margin-left:calc(var(--ag-charts-spacing) * -2)}.ag-charts-button.ag-charts-dialog__close-button{background:none;border:0;margin-left:auto;padding:1px 6px}.ag-charts-dialog__close-button:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:calc(var(--ag-charts-layer-ui-overlay) + 1)}.ag-charts-dialog__tab-panel{display:none;flex-direction:column;gap:calc(var(--ag-charts-spacing) * 4);margin:0 calc(var(--ag-charts-spacing) * 4);padding:calc(var(--ag-charts-spacing) * 4) 0}.ag-charts-dialog__tab-panel--active{display:flex}.ag-charts-dialog__input-group-line{display:flex;gap:16px 18px;flex-wrap:wrap}.ag-charts-dialog__input-group{align-items:center;display:flex;font-size:var(--ag-charts-chrome-font-size)}.ag-charts-dialog__input-group-label{color:var(--ag-charts-chrome-subtle-text-color);margin-right:5px}.ag-charts-dialog__input-group-label[for]{cursor:pointer}.ag-charts-dialog__button{border-radius:0;margin-right:-1px}.ag-charts-dialog__button.ag-charts-dialog__button--active{background:var(--ag-charts-button-focus-background-color);border-color:var(--ag-charts-input-focus-border-color);color:var(--ag-charts-input-focus-text-color);z-index:var(--input-layer-active)}.ag-charts-dialog__button:first-child,.ag-charts-dialog__input-group-label+.ag-charts-dialog__button{border-bottom-left-radius:var(--ag-charts-input-border-radius);border-top-left-radius:var(--ag-charts-input-border-radius)}.ag-charts-dialog__button:last-child{border-bottom-right-radius:var(--ag-charts-input-border-radius);border-top-right-radius:var(--ag-charts-input-border-radius)}.ag-charts-dialog__color-picker-button{--color: #000;background:var(--color);border:none;color:transparent;height:26px;width:26px}.ag-charts-dialog__color-picker-button:hover{background:var(--color)}.ag-charts-dialog__color-picker-button--multi-color,.ag-charts-dialog__color-picker-button--multi-color:hover{background:linear-gradient(135deg,red 0%,#ff0 calc(100% * 1 / 6),#0f0 calc(100% * 2 / 6),#0ff 50%,#00f calc(100% * 4 / 6),#f0f calc(100% * 5 / 6),red 100%)}.ag-charts-color-picker{width:190px;padding:8px;--h: 0;--s: 0;--v: 0;--a: 0;--color: #000;--color-a: #000;--thumb-size: 18px;--inner-width: 172px;--track-height: 12px;--palette-height: 136px;--checker: url('data:image/svg+xml;utf8,');--multi-color: linear-gradient( 135deg, #f00 0% , #ff0 calc(100% * 1 / 6), #0f0 calc(100% * 2 / 6), #0ff 50% , #00f calc(100% * 4 / 6), #f0f calc(100% * 5 / 6), #f00 100% )}.ag-charts-color-picker__content{display:flex;flex-direction:column}.ag-charts-color-picker__palette{position:relative;width:100%;height:var(--palette-height);margin-bottom:8px;background:linear-gradient(to bottom,#0000,#000),linear-gradient(to right,#fff,#fff0) hsl(var(--h),100%,50%);border-radius:calc(var(--ag-charts-border-radius) * 1.5);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__palette:after{content:"";position:absolute;display:block;top:calc(var(--thumb-size) * -.5 + (1 - var(--v)) * 100%);left:calc(var(--thumb-size) * -.5 + var(--s) * 100%);background:var(--color);width:var(--thumb-size);height:var(--thumb-size);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:var(--box-shadow);--box-shadow: inset 0 0 0 3px white, inset 0 0 1px 3px #0006, 0 0 5px #00000038}.ag-charts-color-picker__palette:focus-visible:after{outline:var(--ag-charts-focus-border);box-shadow:var(--box-shadow),0 0 0 2px #fff8,var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__color-row{display:flex;gap:8px;align-items:center;margin-bottom:4px;--inset: calc((var(--thumb-size) - var(--track-height)) / 2)}.ag-charts-color-picker__hue-input,.ag-charts-color-picker__alpha-input{-webkit-appearance:none;display:block;position:relative;padding:0;margin:0 calc(var(--inset) * -1);border:0;height:var(--thumb-size);width:auto;background:transparent;--inset: calc((var(--thumb-size) - var(--track-height)) / 2)}.ag-charts-color-picker__hue-input::-webkit-slider-thumb,.ag-charts-color-picker__alpha-input::-webkit-slider-thumb{-webkit-appearance:none;width:var(--thumb-size);height:var(--thumb-size);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:var(--box-shadow);--box-shadow: inset 0 0 0 3px white, inset 0 0 1px 3px #0006, 0 0 5px #00000038;transform:translateZ(0)}.ag-charts-color-picker__hue-input::-webkit-slider-thumb{background:hsl(var(--h),100%,50%)}.ag-charts-color-picker__alpha-input::-webkit-slider-thumb{background:transparent}.ag-charts-color-picker__alpha-input--opaque::-webkit-slider-thumb{background:var(--color)}.ag-charts-color-picker__hue-input:focus-visible::-webkit-slider-thumb,.ag-charts-color-picker__alpha-input:focus-visible::-webkit-slider-thumb{outline:var(--ag-charts-focus-border);box-shadow:var(--box-shadow),var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__hue-input:before,.ag-charts-color-picker__alpha-input:before{position:absolute;content:"";display:block;top:calc(50% - var(--track-height) / 2);left:var(--inset);right:var(--inset);height:var(--track-height);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__multi-color-button{width:36px;margin-left:var(--inset);height:var(--track-height);border-radius:calc(var(--ag-charts-border-radius) * 99);border:0;background:var(--multi-color);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__multi-color-button--hidden{display:none}.ag-charts-color-picker__multi-color-button--active{box-shadow:inset 0 0 0 1px #0003;outline-offset:1px;outline:2px solid #2196f3}.ag-charts-color-picker__hue-input{flex:1 0 0}.ag-charts-color-picker__hue-input:before{background:linear-gradient(to right,red,red calc((100% - var(--track-height)) * 0 / 6 + var(--track-height) / 2),#ff0 calc((100% - var(--track-height)) * 1 / 6 + var(--track-height) / 2),#0f0 calc((100% - var(--track-height)) * 2 / 6 + var(--track-height) / 2),#0ff calc((100% - var(--track-height)) * 3 / 6 + var(--track-height) / 2),#00f calc((100% - var(--track-height)) * 4 / 6 + var(--track-height) / 2),#f0f calc((100% - var(--track-height)) * 5 / 6 + var(--track-height) / 2),red calc((100% - var(--track-height)) * 6 / 6 + var(--track-height) / 2))}.ag-charts-color-picker__alpha-input{margin-bottom:7px}.ag-charts-color-picker__alpha-input:before{background:linear-gradient(to right,transparent,var(--color)),var(--checker) top left / 4px 4px}.ag-charts-color-picker__color-field{display:flex;border:var(--ag-charts-border);background:var(--ag-charts-background-color);border-radius:var(--ag-charts-border-radius);overflow:hidden}.ag-charts-color-picker__color-field:has(:focus-visible){border-color:var(--ag-charts-accent-color);box-shadow:var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__color-label{width:16px;height:16px;margin:7px 0 7px 7px;color:transparent;background:linear-gradient(to right,var(--color-a),var(--color-a)),var(--checker) top left / 4px 4px;border-radius:calc(var(--ag-charts-border-radius) / 2);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__color-label--multi-color{background:var(--multi-color)}.ag-charts-color-picker__color-input{flex:1;min-width:0;padding:7px 7px 7px 8px;border:0;margin:0;color:inherit;background:transparent;font-variant:tabular-nums}.ag-charts-color-picker__color-input:focus-visible{border:none;outline:none}.ag-charts-annotations__line-stroke-width-menu,.ag-charts-annotations__line-style-type-menu,.ag-charts-annotations__text-size-menu{.ag-charts-menu__row:first-child{border-radius:0}}.ag-charts-annotations__text-size-menu{--item-padding: 4px 8px;border-top-left-radius:0;border-top-right-radius:0;min-width:34px;text-align:center}.ag-charts-annotations__line-stroke-width-menu{--item-padding: 6px;column-gap:6px}.ag-charts-annotations__line-style-type-menu{--item-padding: 6px;column-gap:0}.ag-charts-annotations__stroke-width-button:before{background:var(--ag-charts-foreground-color);content:"";margin-right:var(--toolbar-button-padding);height:min(var(--stroke-width),20px);width:12px}.ag-charts-annotations__stroke-width-button[aria-disabled=true]:before{filter:grayscale(1);opacity:.5}.ag-charts-annotations__color-picker-button{--emblem: var(--color)}.ag-charts-annotations__color-picker-button--multi-color{--emblem: linear-gradient( to right, #f00 0% , #ff0 calc(100% * 1 / 6), #0f0 calc(100% * 2 / 6), #0ff 50% , #00f calc(100% * 4 / 6), #f0f calc(100% * 5 / 6), #f00 100% )}.ag-charts-annotations__color-picker-button:after{content:"";display:block;position:absolute;bottom:3px;left:5px;right:5px;height:4px;border-radius:99px;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ag-charts-foreground-color) 10%,transparent);background:var(--emblem)}.ag-charts-annotations__color-picker-button[aria-disabled=true]:after{filter:grayscale(1);opacity:.5}.ag-charts-annotations__toolbar-menu{min-width:200px}.ag-charts-annotations__axis-button--hidden{display:none}.ag-charts-annotations__axis-button{background-color:var(--ag-charts-crosshair-label-background-color);border-radius:calc(var(--ag-charts-border-radius) / 2);border:none;box-sizing:border-box;color:var(--ag-charts-crosshair-label-text-color);cursor:pointer;font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size);font-weight:var(--ag-charts-chrome-font-weight);left:0;line-height:16px;overflow:hidden;padding:0;position:absolute;top:0;user-select:none;white-space:nowrap;z-index:var(--ag-charts-layer-annotations)}.ag-charts-annotations__axis-button:hover{opacity:.8;color:var(--ag-charts-background-color)}.ag-charts-dialog--annotation-settings{min-height:233px;width:289px}.ag-charts-dialog--annotation-settings .ag-charts-textarea{height:calc(10px * 2 + var(--textarea-line-height) * 1em * 3 + 2px);overflow-y:auto;resize:vertical}.ag-charts-context-menu{background:var(--ag-charts-chrome-background-color);border:var(--ag-charts-border);border-radius:var(--ag-charts-border-radius);box-shadow:var(--ag-charts-shadow);color:var(--ag-charts-chrome-text-color);font-family:var(--ag-charts-chrome-font-family);font-size:calc(var(--ag-charts-chrome-font-size) * (13 / 12));font-weight:var(--ag-charts-chrome-font-weight);transition:transform .1s ease;white-space:nowrap;z-index:var(--ag-charts-layer-ui-overlay)}.ag-charts-context-menu__cover{position:fixed;left:0;top:0}.ag-charts-context-menu__menu{display:flex;flex-direction:column;padding:.5em 0}.ag-charts-context-menu__menu:focus{outline:none}.ag-charts-context-menu__item{background:none;border:none;box-sizing:border-box;color:inherit;font:inherit;padding:.5em 1em;text-align:left;-webkit-appearance:none;-moz-appearance:none}.ag-charts-context-menu__item:focus,.ag-charts-context-menu__item:active{background:var(--ag-charts-focus-color)}.ag-charts-context-menu__item[data-focus-visible-override=true]:focus,.ag-charts-context-menu__item:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:calc(var(--ag-charts-layer-ui-overlay) + 1)}.ag-charts-context-menu__item[data-focus-visible-override=false]{outline:inherit;box-shadow:inherit;z-index:inherit}.ag-charts-context-menu__item[aria-disabled=true]{border:none;opacity:.5;text-align:left}.ag-charts-context-menu__item[aria-disabled=true]:focus{background:inherit;cursor:inherit}.ag-charts-context-menu__divider{margin:5px 0;background:#babfc7;height:1px}.ag-charts-context-menu__divider.ag-charts-dark-context-menu{background:#2196f31a}.ag-charts-crosshair-label{position:absolute;left:0;top:0;user-select:none;pointer-events:none;font-family:var(--ag-charts-font-family);font-size:var(--ag-charts-font-size);font-weight:var(--ag-charts-font-weight);overflow:hidden;white-space:nowrap;z-index:var(--ag-charts-layer-crosshair);box-sizing:border-box}.ag-charts-crosshair-label-content{padding:0 8px;border-radius:calc(var(--ag-charts-border-radius) / 2);line-height:calc(var(--ag-charts-font-size) + 8px);background-color:var(--ag-charts-crosshair-label-background-color);color:var(--ag-charts-crosshair-label-text-color)}.ag-charts-crosshair-label--hidden{visibility:hidden!important}.ag-charts-text-input{position:absolute}.ag-charts-text-input__textarea{--placeholder-text-color: var(--ag-charts-input-placeholder-text-color);display:block;height:100%;width:100%;border:0;background:none;line-height:1.38;outline:none;transform:translateY(.09em)}.ag-charts-text-input__textarea[placeholder]:empty:before{content:attr(placeholder);color:var(--placeholder-text-color);font-weight:400}.ag-charts-text-input__textarea[placeholder]:not(:empty):before{content:""}.ag-charts-chart-toolbar__menu{min-width:200px}.ag-charts-range-buttons .ag-charts-toolbar__button{padding:var(--toolbar-button-padding) calc(var(--toolbar-button-padding) * 1.5)}.ag-charts-zoom-buttons{align-items:center;display:flex;height:44px;justify-content:center;overflow:hidden;padding-bottom:10px;pointer-events:none;width:100%;.ag-charts-toolbar{--toolbar-size: 24px;--toolbar-button-padding: 1px;display:flex;font-size:var(--ag-charts-chrome-font-size);height:var(--toolbar-size);justify-content:center;opacity:1;pointer-events:auto;transition:opacity .2s ease-in-out,transform .4s ease-in-out;.ag-charts-toolbar__button--first{border-bottom-left-radius:var(--ag-charts-border-radius);border-top-left-radius:var(--ag-charts-border-radius)}.ag-charts-toolbar__button--last{border-bottom-right-radius:var(--ag-charts-border-radius);border-top-right-radius:var(--ag-charts-border-radius)}.ag-charts-toolbar__label{padding-left:var(--ag-charts-spacing);padding-right:var(--ag-charts-spacing)}.ag-charts-toolbar__icon+.ag-charts-toolbar__label{padding-left:0}.ag-charts-toolbar__button--gap{margin-left:var(--toolbar-gap)}.ag-charts-zoom-buttons__toolbar--hidden{opacity:0;transition:opacity .4s ease-in-out,transform .4s ease-in-out}}}.ag-charts-shared-toolbar{gap:var(--toolbar-gap);.ag-charts-toolbar__button{border-radius:var(--ag-charts-border-radius);margin:0}} `; import_ag_charts_community270._ModuleSupport.ModuleRegistry.registerMany([ FlowProportionChartModule, GaugeChartModule, HierarchyChartModule, StandaloneChartModule, TopologyChartModule ]); function setupEnterpriseModules() { import_ag_charts_community270._ModuleSupport.moduleRegistry.register( AngleCategoryAxisModule, AngleNumberAxisModule, AnimationModule, AnnotationsModule, BackgroundModule2, BarModule, ForegroundModule, BoxPlotModule, CandlestickModule, ChordModule, ConeFunnelModule, FunnelModule, OhlcModule, ChartToolbarModule, ContextMenuModule, CrosshairModule, DataSourceModule, ErrorBarsModule, LinearGaugeModule, LineModule, MapLineModule, MapLineBackgroundModule, MapMarkerModule, MapShapeModule, MapShapeBackgroundModule, NavigatorModule, StatusBarModule, GradientLegendModule, HeatmapModule, NightingaleModule, OrdinalTimeAxisModule, RadarAreaModule, RadarLineModule, RadialBarModule, RadialColumnModule, RadiusCategoryAxisModule, RadialGaugeModule, RadiusNumberAxisModule, RangeBarModule, RangeAreaModule, RangesModule, PyramidModule, SankeyModule, SharedToolbarModule, SunburstModule, SyncModule, TreemapModule, WaterfallModule, ZoomModule ); import_ag_charts_community270._ModuleSupport.enterpriseModule.isEnterprise = true; import_ag_charts_community270._ModuleSupport.enterpriseModule.styles = styles_default2; import_ag_charts_community270._ModuleSupport.enterpriseModule.licenseManager = (options) => new LicenseManager( options.container?.ownerDocument ?? (typeof document === "undefined" ? void 0 : document) ); import_ag_charts_community270._ModuleSupport.enterpriseModule.injectWatermark = injectWatermark; } __reExport(main_exports2, (init_main4(), __toCommonJS(main_exports)), module.exports); setupEnterpriseModules(); var LicenseManager2 = { setLicenseKey(key) { LicenseManager.setLicenseKey(key); } }; function setupEnterpriseModules2() { setupEnterpriseModules(); (0, import_ag_charts_community271.setupCommunityModules)(); } var AgChartsEnterpriseModule = { VERSION: import_ag_charts_community271.VERSION, _Scene: import_ag_charts_community271._Scene, _Theme: import_ag_charts_community271._Theme, _Util: import_ag_charts_community271._Util, create: import_ag_charts_community271.AgCharts.create.bind(import_ag_charts_community271.AgCharts), createSparkline: import_ag_charts_community271.AgCharts.__createSparkline.bind(import_ag_charts_community271.AgCharts), setup: setupEnterpriseModules2, setGridContext: LicenseManager.setGridContext.bind(LicenseManager), setLicenseKey: LicenseManager.setLicenseKey.bind(LicenseManager), isEnterprise: true }; if (typeof module.exports == "object" && typeof exports == "object") { var __cp = (to, from, except, desc) => { if ((from && typeof from === "object") || typeof from === "function") { for (let key of Object.getOwnPropertyNames(from)) { if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except) Object.defineProperty(to, key, { get: () => from[key], enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable, }); } } return to; }; module.exports = __cp(module.exports, exports); } return module.exports; }))