UNPKG

ag-charts-community

Version:

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

1,568 lines (1,534 loc) 273 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 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-community/src/integrated-charts-scene.ts var integrated_charts_scene_exports = {}; __export(integrated_charts_scene_exports, { Arc: () => Arc, 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: () => import_ag_charts_core42.toRadians }); module.exports = __toCommonJS(integrated_charts_scene_exports); // packages/ag-charts-community/src/chart/caption.ts var import_ag_charts_core27 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/node.ts var import_ag_charts_core2 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/bbox.ts var import_ag_charts_core = require("ag-charts-core"); // packages/ag-charts-community/src/util/interpolating.ts var interpolate = Symbol("interpolate"); // packages/ag-charts-community/src/scene/bbox.ts var _BBox = class _BBox { constructor(x, y, width, height) { this.x = x; this.y = y; this.width = width; this.height = height; } static fromObject({ x, y, width, height }) { return new _BBox(x, y, width, height); } 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 (end(box.x, box.width) > right) { right = end(box.x, box.width); } if (end(box.y, box.height) > bottom) { bottom = end(box.y, box.height); } } return new _BBox(left, top, right - left, bottom - top); } static nearestBox(x, y, boxes) { return (0, import_ag_charts_core.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: end(this.x, this.width), bottom: end(this.y, this.height), toJSON() { return {}; } }; } clone() { const { x, y, width, height } = this; return new _BBox(x, y, width, height); } equals(other) { return (0, import_ag_charts_core.boxesEqual)(this, other); } containsPoint(x, y) { return (0, import_ag_charts_core.boxContains)(this, x, y); } intersectsWith(other) { return !(this.x + this.width <= other.x || other.x + other.width <= this.x || this.y + this.height <= other.y || other.y + other.height <= this.y); } intersection(other) { const x0 = Math.max(this.x, other.x); const y0 = Math.max(this.y, other.y); const x1 = Math.min(end(this.x, this.width), end(other.x, other.width)); const y1 = Math.min(end(this.y, this.height), end(other.y, other.height)); if (x0 > x1 || y0 > y1) return; return new _BBox(x0, y0, x1 - x0, y1 - y0); } collidesBBox(other) { return this.x < end(other.x, other.width) && end(this.x, this.width) > other.x && this.y < end(other.y, other.height) && end(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 dx = x - (0, import_ag_charts_core.clamp)(this.x, x, end(this.x, this.width)); const dy = y - (0, import_ag_charts_core.clamp)(this.y, y, end(this.y, this.height)); return dx * dx + dy * dy; } shrink(amount, position) { if (typeof amount === "number") { this.applyMargin(amount, position); } else { for (const key of Object.keys(amount)) { const value = amount[key]; if (typeof value === "number") { 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 of Object.keys(amount)) { const value = amount[key]; if (typeof value === "number") { 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(Number.NaN, Number.NaN, Number.NaN, Number.NaN)); var BBox = _BBox; function end(x, width) { if (x === -Infinity && width === Infinity) return Infinity; return x + width; } // packages/ag-charts-community/src/scene/zIndex.ts var cmp = (a, b) => Math.sign(a - b); 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 length = Math.min(aArray.length, bArray.length); for (let i = 0; i < length; i += 1) { const diff = cmp(aArray[i], bArray[i]); if (diff !== 0) return diff; } return cmp(aArray.length, bArray.length); } // packages/ag-charts-community/src/scene/node.ts var import_ag_charts_core3 = require("ag-charts-core"); var MAX_ERROR_COUNT = 5; var _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 = (0, import_ag_charts_core2.createId)(this); this.name = void 0; this.transitionOut = void 0; this.pointerEvents = 0 /* All */; this._datum = void 0; this._previousDatum = void 0; this.scene = void 0; this._debugDirtyProperties = void 0; this.parentNode = void 0; this.cachedBBox = void 0; /** * 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.batchLevel = 0; this.batchDirty = false; this.name = options?.name; this.tag = options?.tag ?? Number.NaN; this.zIndex = options?.zIndex ?? 0; this.scene = options?.scene; if (options?.debugDirty ?? _Node._debugEnabled) { this._debugDirtyProperties = /* @__PURE__ */ new Map([["__first__", []]]); } } static toSVG(node, width, height) { const svg = node?.toSVG(); if (svg == null || !svg.elements.length && !svg.defs?.length) return; const root = (0, import_ag_charts_core2.createSvgElement)("svg"); root.setAttribute("width", String(width)); root.setAttribute("height", String(height)); root.setAttribute("viewBox", `0 0 ${width} ${height}`); root.setAttribute("overflow", "visible"); if (svg.defs?.length) { const defs = (0, import_ag_charts_core2.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; } set datum(datum) { if (this._datum !== datum) { this._previousDatum = this._datum; this._datum = datum; } } get previousDatum() { return this._previousDatum; } /** @deprecated do not use unsafe non-null assertion (`datum!`), used typed `datum` */ get unsafeNonNullDatum() { return this.datum; } /** @deprecated do not use `any`, used typed `datum` */ get unsafeDatum() { return this.datum; } /** @deprecated do not use `any`, used typed `datum` */ set unsafeDatum(datum) { this.datum = datum; } /** @deprecated do not use `any`, used typed `previousDatum` */ get unsafePreviousDatum() { return this.previousDatum; } get layerManager() { return this.scene?.layersManager; } get imageLoader() { return this.scene?.imageLoader; } closestDatum() { for (const { datum } of this.traverseUp(true)) { if (datum != null) { return datum; } } } /** @deprecated do not use `any` */ unsafeClosestDatum() { return this.closestDatum(); } /** 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; if (this.batchLevel > 0 || this.batchDirty) { throw new Error("AG Charts - illegal rendering state; batched update in progress"); } return this.childNodeCounts; } /** Guaranteed isolated render - if there is any failure, the Canvas2D context is returned to its prior state. */ isolatedRender(renderCtx) { const savedFont = renderCtx.currentFont; renderCtx.ctx.save(); try { this.render(renderCtx); } catch (e) { const errorCount = e.errorCount ?? 1; if (errorCount >= MAX_ERROR_COUNT) { e.errorCount = errorCount; throw e; } import_ag_charts_core2.Logger.warnOnce("Error during rendering", e, e.stack); } finally { renderCtx.ctx.restore(); renderCtx.currentFont = savedFont; } } render(renderCtx) { const { stats } = renderCtx; this.debugDirtyProperties(); 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; } } setScene(scene) { this.scene = scene; } *traverseUp(includeSelf) { if (includeSelf) { yield this; } let node = this.parentNode; while (node) { yield node; node = node.parentNode; } } /** * Checks if the node is the root (has no parent). */ isRoot() { return !this.parentNode; } removeChild(node) { throw new Error( `AG Charts - internal error, unknown child node ${node.name ?? node.id} in $${this.name ?? this.id}` ); } remove() { this.parentNode?.removeChild(this); } destroy() { if (this.parentNode) { this.remove(); } } batchedUpdate(fn) { this.batchLevel++; try { fn(); } finally { this.batchLevel--; if (this.batchLevel === 0 && this.batchDirty) { this.markDirty(); this.batchDirty = false; } } } setProperties(styles) { this.batchLevel++; try { const target = this; const source = styles; const keys = Object.keys(source); for (let i = 0, n = keys.length; i < n; i++) { const key = keys[i]; target[key] = source[key]; } } finally { this.batchLevel--; if (this.batchLevel === 0 && this.batchDirty) { this.markDirty(); this.batchDirty = false; } } return this; } setPropertiesWithKeys(styles, keys) { this.batchLevel++; try { const target = this; const source = styles; for (let i = 0, n = keys.length; i < n; i++) { const key = keys[i]; target[key] = source[key]; } } finally { this.batchLevel--; if (this.batchLevel === 0 && this.batchDirty) { this.markDirty(); this.batchDirty = false; } } return this; } containsPoint(_x, _y) { return false; } distanceSquared(_x, _y) { return Infinity; } pickNode(x, y) { if (!this.visible || this.pointerEvents === 1 /* None */) { return; } if (this.containsPoint(x, y)) { return this; } } pickNodes(x, y, into = []) { if (!this.visible || this.pointerEvents === 1 /* None */) { return into; } if (this.containsPoint(x, y)) { into.push(this); } return into; } getBBox() { this.cachedBBox ?? (this.cachedBBox = Object.freeze(this.computeBBox())); return this.cachedBBox; } computeBBox() { return; } onChangeDetection(property) { this.markDirty(property); } markDirtyChildrenOrder() { this.cachedBBox = void 0; } markDirty(property) { if (this.batchLevel > 0) { this.batchDirty = true; return; } if (property != null && this._debugDirtyProperties) { this.markDebugProperties(property); } this.cachedBBox = void 0; this.parentNode?.markDirty(); } markDebugProperties(property) { const sources = this._debugDirtyProperties?.get(property) ?? []; const caller = new Error("Stack trace for property change tracking").stack?.split("\n").filter((line) => { return line !== "Error" && !line.includes(".markDebugProperties") && !line.includes(".markDirty") && !line.includes("Object.assign ") && !line.includes(`${this.constructor.name}.`); }) ?? "unknown"; sources.push(caller[0].replace(" at ", "").trim()); this._debugDirtyProperties?.set(property, sources); } debugDirtyProperties() { if (this._debugDirtyProperties == null) return; if (!this._debugDirtyProperties.has("__first__")) { for (const [property, sources] of this._debugDirtyProperties.entries()) { if (sources.length > 1) { import_ag_charts_core2.Logger.logGroup( `Property changed multiple times before render: ${this.constructor.name}.${property} (${sources.length}x)`, () => { for (const source of sources) { import_ag_charts_core2.Logger.log(source); } } ); } } } this._debugDirtyProperties.clear(); } static handleNodeZIndexChange(target) { target.onZIndexChange(); } onZIndexChange() { this.parentNode?.markDirtyChildrenOrder(); } /** Override in subclasses that carry a font (Text) or contain font-bearing children (Group). */ resolveFont() { return void 0; } toSVG() { return; } }; _Node.className = "AbstractNode"; _Node._nextSerialNumber = 0; _Node._debugEnabled = false; __decorateClass([ (0, import_ag_charts_core2.DeclaredSceneChangeDetection)() ], _Node.prototype, "visible", 2); __decorateClass([ (0, import_ag_charts_core2.DeclaredSceneChangeDetection)({ equals: import_ag_charts_core2.objectsEqual, changeCb: _Node.handleNodeZIndexChange }) ], _Node.prototype, "zIndex", 2); var Node = _Node; // packages/ag-charts-community/src/scene/shape/text.ts var import_ag_charts_core26 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/group.ts var import_ag_charts_core21 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/canvas/hdpiOffscreenCanvas.ts var import_ag_charts_core5 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/util/pixel.ts var HALF_PIXEL_EPSILON = 1e-8; function deviceDimension(pixelRatio, value) { const scaled = value * pixelRatio; const fractional = scaled - Math.floor(scaled); const stable = Math.abs(fractional - 0.5) < HALF_PIXEL_EPSILON ? scaled + HALF_PIXEL_EPSILON : scaled; return Math.round(stable); } function roundToDevicePixel(pixelRatio, value) { return deviceDimension(pixelRatio, value) / pixelRatio; } function align(pixelRatio, start, length) { const alignedStart = roundToDevicePixel(pixelRatio, start); if (length == null) { return alignedStart; } else if (length === 0) { return 0; } else if (length < 1) { return alignAfter(pixelRatio, length); } return roundToDevicePixel(pixelRatio, length + start) - alignedStart; } function alignBefore(pixelRatio, value) { return Math.floor(value * pixelRatio) / pixelRatio; } function alignAfter(pixelRatio, value) { return Math.ceil(value * pixelRatio) / pixelRatio; } // packages/ag-charts-community/src/scene/canvas/canvasUtil.ts var import_ag_charts_core4 = require("ag-charts-core"); function clearContext({ context, pixelRatio, width, height }) { context.save(); try { context.resetTransform(); context.clearRect(0, 0, Math.ceil(width * pixelRatio), Math.ceil(height * pixelRatio)); } finally { context.restore(); } } function debugContext(ctx) { if (import_ag_charts_core4.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}`); } } }); } } // packages/ag-charts-community/src/scene/canvas/hdpiOffscreenCanvas.ts function canvasDimensions(width, height, pixelRatio) { return [deviceDimension(pixelRatio, width), deviceDimension(pixelRatio, height)]; } var fallbackCanvas; function getFallbackCanvas() { const OffscreenCanvasCtor = (0, import_ag_charts_core5.getOffscreenCanvas)(); fallbackCanvas ?? (fallbackCanvas = new OffscreenCanvasCtor(1, 1)); return fallbackCanvas; } var HdpiOffscreenCanvas = class { constructor(options) { const { width, height, pixelRatio, willReadFrequently = false } = options; this.width = width; this.height = height; this.pixelRatio = pixelRatio; const [canvasWidth, canvasHeight] = canvasDimensions(width, height, pixelRatio); const OffscreenCanvasCtor = (0, import_ag_charts_core5.getOffscreenCanvas)(); this.canvas = new OffscreenCanvasCtor(canvasWidth, canvasHeight); this.context = this.canvas.getContext("2d", { willReadFrequently }); this.context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); debugContext(this.context); } drawImage(context, dx = 0, dy = 0) { return context.drawImage(this.canvas, dx, dy); } transferToImageBitmap() { if (this.canvas.width < 1 || this.canvas.height < 1) { return getFallbackCanvas().transferToImageBitmap(); } return this.canvas.transferToImageBitmap(); } resize(width, height, pixelRatio) { if (!(width > 0 && height > 0)) return; const { canvas, context } = this; if (width !== this.width || height !== this.height || pixelRatio !== this.pixelRatio) { const [canvasWidth, canvasHeight] = canvasDimensions(width, height, pixelRatio); canvas.width = canvasWidth; canvas.height = canvasHeight; } context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); this.width = width; this.height = height; 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/scene/shape/shape.ts var import_ag_charts_core18 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/gradient/conicGradient.ts var import_ag_charts_core9 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/gradient/gradient.ts var import_ag_charts_core8 = require("ag-charts-core"); // packages/ag-charts-community/src/scale/colorScale.ts var import_ag_charts_core7 = require("ag-charts-core"); // packages/ag-charts-community/src/scale/abstractScale.ts var AbstractScale = class { invertWithPercentage(value) { return this.invert(value, true); } snapshotDomain() { return this.domain; } restoreDomain(snapshot) { this.domain = snapshot; } get domainMin() { return this.getDomainMinMax()[0]; } get domainMax() { return this.getDomainMinMax()[1]; } ticks(_ticks, _domain, _visibleRange) { return void 0; } niceDomain(_ticks, domain = this.domain) { return domain; } get bandwidth() { return void 0; } get step() { return void 0; } get inset() { return void 0; } }; // packages/ag-charts-community/src/scale/invalidating.ts var 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 var import_ag_charts_core6 = require("ag-charts-core"); function visibleTickRange(ticks, reversed, visibleRange) { if (visibleRange == null || visibleRange[0] === 0 && visibleRange[1] === 1) return; const vt0 = (0, import_ag_charts_core6.clamp)(0, Math.floor(visibleRange[0] * ticks.length), ticks.length); const vt1 = (0, import_ag_charts_core6.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 [t0, t1]; } function filterVisibleTicks(ticks, reversed, visibleRange) { const tickRange = visibleTickRange(ticks, reversed, visibleRange); if (tickRange == null) return { ticks, count: ticks.length, firstTickIndex: 0 }; const [t0, t1] = tickRange; return { ticks: ticks.slice(t0, t1), count: ticks.length, firstTickIndex: t0 }; } function unpackDomainMinMax(domain) { const min = (0, import_ag_charts_core6.readIntegratedWrappedValue)(domain.at(0)); const max = (0, import_ag_charts_core6.readIntegratedWrappedValue)(domain.at(-1)); return min != void 0 && max != void 0 ? [min, max] : [void 0, void 0]; } // packages/ag-charts-community/src/scale/colorScale.ts var convertColorStringToOklcha = (v) => { const color = import_ag_charts_core7.Color.fromString(v); const [l, c, h] = import_ag_charts_core7.Color.RGBtoOKLCH(color.r, color.g, color.b); return { l, c, h, a: color.a }; }; var delta = 1e-6; var isAchromatic = (x) => x.c < delta || x.l < delta || x.l > 1 - delta; var interpolateOklch = (x, y, d) => { d = (0, import_ag_charts_core7.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 import_ag_charts_core7.Color.fromOKLCH(l, c, h, a); }; var ColorScale = class extends AbstractScale { constructor() { super(...arguments); this.type = "color"; this.defaultTickCount = 0; this.invalid = true; this.domain = [0, 1]; this.range = ["red", "blue"]; this.mode = "continuous"; this.parsedRange = this.range.map(convertColorStringToOklcha); } update() { const { domain, range: range2 } = this; if (domain.length < 2) { import_ag_charts_core7.Logger.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) { import_ag_charts_core7.Logger.warnOnce("`colorDomain` values should be supplied in ascending order."); domain.sort((a2, b2) => a2 - b2); break; } } const expectedLength = this.mode === "discrete" ? domain.length - 1 : domain.length; if (range2.length < expectedLength) { for (let i = range2.length; i < expectedLength; i++) { range2.push(range2.length > 0 ? range2[0] : "black"); } } this.parsedRange = this.range.map(convertColorStringToOklcha); } normalizeDomains(...domains) { return { domain: domains.map((d) => d.domain).flat(), animatable: true }; } toDomain() { return; } convert(x) { this.refresh(); const xn = (0, import_ag_charts_core7.toNumber)(x); const { domain, range: range2, parsedRange } = this; const d0 = domain[0]; const d1 = domain.at(-1); const r0 = range2[0]; const r1 = range2.at(-1); if (xn <= d0) { return r0; } if (xn >= d1) { return r1; } let index; let q; if (domain.length === 2) { const t = (xn - d0) / (d1 - d0); const step = 1 / (range2.length - 1); index = range2.length <= 2 ? 0 : Math.min(Math.floor(t * (range2.length - 1)), range2.length - 2); q = (t - index * step) / step; } else { for (index = 0; index < domain.length - 2; index++) { if (xn < domain[index + 1]) { break; } } const a = domain[index]; const b = domain[index + 1]; q = (xn - a) / (b - a); } if (this.mode === "discrete") { return range2[index]; } const c0 = parsedRange[index]; const c1 = parsedRange[index + 1]; return interpolateOklch(c0, c1, q).toRgbaString(); } invert() { return; } getDomainMinMax() { return unpackDomainMinMax(this.domain); } refresh() { if (!this.invalid) return; this.invalid = false; this.update(); if (this.invalid) { import_ag_charts_core7.Logger.warnOnce("Expected update to not invalidate scale"); } } }; __decorateClass([ Invalidating ], ColorScale.prototype, "domain", 2); __decorateClass([ Invalidating ], ColorScale.prototype, "range", 2); __decorateClass([ Invalidating ], ColorScale.prototype, "mode", 2); // packages/ag-charts-community/src/scene/gradient/gradient.ts var Gradient = class { constructor(colorSpace, stops = [], bbox) { this.colorSpace = colorSpace; this.stops = stops; this.bbox = bbox; this._cache = void 0; } createGradient(ctx, shapeBbox, params) { const bbox = this.bbox ?? shapeBbox; if (!bbox.isFinite()) { return; } if (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 gradient = this.createCanvasGradient(ctx, bbox, params); if (gradient == null) return; const isOkLch = colorSpace === "oklch"; const step = 0.05; let c0 = stops[0]; gradient.addColorStop(c0.stop, c0.color); for (let i = 1; i < stops.length; i += 1) { const c1 = stops[i]; if (isOkLch) { const scale = new ColorScale(); scale.domain = [c0.stop, c1.stop]; scale.range = [c0.color, c1.color]; for (let stop = c0.stop + step; stop < c1.stop; stop += step) { gradient.addColorStop(stop, scale.convert(stop) ?? "transparent"); } } gradient.addColorStop(c1.stop, c1.color); c0 = c1; } if ("createPattern" in gradient) { gradient = gradient.createPattern(); } this._cache = { ctx, bbox, gradient }; return gradient; } toSvg(shapeBbox) { const bbox = this.bbox ?? shapeBbox; const gradient = this.createSvgGradient(bbox); for (const { stop: offset, color } of this.stops) { const stop = (0, import_ag_charts_core8.createSvgElement)("stop"); stop.setAttribute("offset", `${offset}`); stop.setAttribute("stop-color", `${color}`); gradient.appendChild(stop); } return gradient; } }; // packages/ag-charts-community/src/scene/gradient/conicGradient.ts var ConicGradient = class extends Gradient { constructor(colorSpace, stops, angle = 0, bbox) { super(colorSpace, stops, bbox); this.angle = angle; } createCanvasGradient(ctx, bbox, params) { const angleOffset = -90; const { angle } = this; const radians = (0, import_ag_charts_core9.normalizeAngle360FromDegrees)(angle + angleOffset); const cx = params?.centerX ?? bbox.x + bbox.width * 0.5; const cy = params?.centerY ?? bbox.y + bbox.height * 0.5; return ctx.createConicGradient(radians, cx, cy); } createSvgGradient(_bbox) { return (0, import_ag_charts_core9.createSvgElement)("linearGradient"); } }; // packages/ag-charts-community/src/scene/gradient/linearGradient.ts var import_ag_charts_core10 = require("ag-charts-core"); var LinearGradient = class extends Gradient { constructor(colorSpace, stops, angle = 0, bbox) { super(colorSpace, stops, bbox); this.angle = angle; } getGradientPoints(bbox) { const angleOffset = 90; const { angle } = this; const radians = (0, import_ag_charts_core10.normalizeAngle360FromDegrees)(angle + 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.hypot(h, 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 { x0: cx + cos * l, y0: cy + sin * l, x1: cx - cos * l, y1: cy - sin * l }; } createCanvasGradient(ctx, bbox) { const { x0, y0, x1, y1 } = this.getGradientPoints(bbox); if (Number.isNaN(x0) || Number.isNaN(y0) || Number.isNaN(x1) || Number.isNaN(y1)) { return void 0; } return ctx.createLinearGradient(x0, y0, x1, y1); } createSvgGradient(bbox) { const { x0, y0, x1, y1 } = this.getGradientPoints(bbox); const gradient = (0, import_ag_charts_core10.createSvgElement)("linearGradient"); gradient.setAttribute("x1", String(x0)); gradient.setAttribute("y1", String(y0)); gradient.setAttribute("x2", String(x1)); gradient.setAttribute("y2", String(y1)); gradient.setAttribute("gradientUnits", "userSpaceOnUse"); return gradient; } }; // packages/ag-charts-community/src/scene/gradient/radialGradient.ts var import_ag_charts_core11 = require("ag-charts-core"); var RadialGradient = class extends Gradient { constructor(colorSpace, stops, bbox) { super(colorSpace, stops, bbox); } createCanvasGradient(ctx, bbox, params) { const cx = params?.centerX ?? bbox.x + bbox.width * 0.5; const cy = params?.centerY ?? bbox.y + bbox.height * 0.5; const innerRadius = params?.innerRadius ?? 0; const outerRadius = params?.outerRadius ?? Math.hypot(bbox.width * 0.5, bbox.height * 0.5) / Math.SQRT2; return ctx.createRadialGradient(cx, cy, innerRadius, cx, cy, outerRadius); } createSvgGradient(bbox) { const cx = bbox.x + bbox.width * 0.5; const cy = bbox.y + bbox.height * 0.5; const gradient = (0, import_ag_charts_core11.createSvgElement)("radialGradient"); gradient.setAttribute("cx", String(cx)); gradient.setAttribute("cy", String(cy)); gradient.setAttribute("r", String(Math.hypot(bbox.width * 0.5, bbox.height * 0.5) / Math.SQRT2)); gradient.setAttribute("gradientUnits", "userSpaceOnUse"); return gradient; } }; // packages/ag-charts-community/src/scene/gradient/stops.ts var import_ag_charts_core12 = require("ag-charts-core"); var StopProperties = class extends import_ag_charts_core12.BaseProperties { constructor() { super(...arguments); this.color = "black"; } }; __decorateClass([ import_ag_charts_core12.Property ], StopProperties.prototype, "stop", 2); __decorateClass([ import_ag_charts_core12.Property ], StopProperties.prototype, "color", 2); __decorateClass([ import_ag_charts_core12.Property ], StopProperties.prototype, "name", 2); var ColorScaleProperties = class extends import_ag_charts_core12.BaseProperties { constructor() { super(...arguments); this.fills = new import_ag_charts_core12.PropertiesArray(StopProperties); this.mode = "continuous"; } }; __decorateClass([ import_ag_charts_core12.Property ], ColorScaleProperties.prototype, "fills", 2); __decorateClass([ import_ag_charts_core12.Property ], ColorScaleProperties.prototype, "domain", 2); __decorateClass([ import_ag_charts_core12.Property ], ColorScaleProperties.prototype, "mode", 2); __decorateClass([ import_ag_charts_core12.Property ], ColorScaleProperties.prototype, "missingDataFill", 2); function getDefaultColorStops(defaultColorStops, fillMode) { const stopOffset = fillMode === "discrete" ? 1 : 0; const colorStops = defaultColorStops.map( (color, index, { length }) => ({ stop: (index + stopOffset) / (length - 1 + stopOffset), color }) ); return fillMode === "discrete" ? (0, import_ag_charts_core12.discreteColorStops)(colorStops) : colorStops; } function getColorStops(baseFills, defaultColorStops, domain, fillMode = "continuous") { const fills = baseFills.map( (fill) => typeof fill === "string" ? { color: fill } : fill ); if (fills.length === 0) { return getDefaultColorStops(defaultColorStops, fillMode); } const d0 = Math.min(...domain); const d1 = Math.max(...domain); const isDiscrete = fillMode === "discrete"; const stops = (0, import_ag_charts_core12.resolveStopPositions)(fills, d0, d1, isDiscrete); let lastDefinedColor = fills.find((c) => c.color != null)?.color; let colorScale; const colorStops = fills.map((fill, i) => { let color = fill?.color; const stop = Math.max(0, Math.min(1, (stops[i] - d0) / (d1 - d0))); if (color != null) { lastDefinedColor = color; } else if (lastDefinedColor == null) { if (colorScale == null) { colorScale = new ColorScale(); colorScale.domain = [0, 1]; colorScale.range = defaultColorStops; } color = colorScale.convert(stop); } else { color = lastDefinedColor; } return { stop, color }; }); return fillMode === "discrete" ? (0, import_ag_charts_core12.discreteColorStops)(colorStops) : colorStops; } // packages/ag-charts-community/src/scene/image/image.ts var import_ag_charts_core13 = require("ag-charts-core"); var Image = class { constructor(imageLoader, imageOptions) { this.imageLoader = imageLoader; this._cache = void 0; this.url = imageOptions.url; this.backgroundFill = imageOptions.backgroundFill ?? "black"; this.backgroundFillOpacity = imageOptions.backgroundFillOpacity ?? 1; this.repeat = imageOptions.repeat ?? "no-repeat"; this.width = imageOptions.width; this.height = imageOptions.height; this.fit = imageOptions.fit ?? "stretch"; this.rotation = imageOptions.rotation ?? 0; } createCanvasImage(ctx, image, width, height) { if (!image) return null; const [renderedWidth, renderedHeight] = this.getSize(image.width, image.height, width, height); if (renderedWidth < 1 || renderedHeight < 1) { import_ag_charts_core13.Logger.warnOnce("Image fill is too small to render, ignoring."); return null; } return ctx.createPattern(image, this.repeat); } getSize(imageWidth, imageHeight, width, height) { const { fit } = this; let dw = imageWidth; let dh = imageHeight; let scale = 1; const shapeAspectRatio = width / height; const imageAspectRatio = imageWidth / imageHeight; if (fit === "stretch" || imageWidth === 0 || imageHeight === 0) { dw = width; dh = height; } else if (fit === "contain") { scale = imageAspectRatio > shapeAspectRatio ? width / imageWidth : height / imageHeight; } else if (fit === "cover") { scale = imageAspectRatio > shapeAspectRatio ? height / imageHeight : width / imageWidth; } return [Math.max(1, dw * scale), Math.max(1, dh * scale)]; } setImageTransform(pattern, bbox) { if (typeof pattern === "string") return; const { url, rotation, width, height } = this; const image = this.imageLoader?.loadImage(url); if (!image) { return; } const angle = (0, import_ag_charts_core13.normalizeAngle360FromDegrees)(rotation); const cos = Math.cos(angle); const sin = Math.sin(angle); const [renderedWidth, renderedHeight] = this.getSize( image.width, image.height, width ?? bbox.width, height ?? bbox.height ); const widthScale = renderedWidth / image.width; const heightScale = renderedHeight / image.height; const bboxCenterX = bbox.x + bbox.width / 2; const bboxCenterY = bbox.y + bbox.height / 2; const rotatedW = cos * renderedWidth - sin * renderedHeight; const rotatedH = sin * renderedWidth + cos * renderedHeight; const shapeCenterX = rotatedW / 2; const shapeCenterY = rotatedH / 2; const DOMMatrixCtor = (0, import_ag_charts_core13.getDOMMatrix)(); pattern?.setTransform( new DOMMatrixCtor([ cos * widthScale, sin * heightScale, -sin * widthScale, cos * heightScale, bboxCenterX - shapeCenterX, bboxCenterY - shapeCenterY ]) ); } createPattern(ctx, shapeWidth, shapeHeight, node) { const width = this.width ?? shapeWidth; const height = this.height ?? shapeHeight; const cache = this._cache; if (cache?.ctx === ctx && cache.width === width && cache.height === height) { return cache.pattern; } const image = this.imageLoader?.loadImage(this.url, node); const pattern = this.createCanvasImage(ctx, image, width, height); if (pattern == null) return; this._cache = { ctx, pattern, width, height }; return pattern; } toSvg(bbox, pixelRatio) { const { url, rotation, backgroundFill, backgroundFillOpacity } = this; const { x, y, width, height } = bbox; const pattern = (0, import_ag_charts_core13.createSvgElement)("pattern"); pattern.setAttribute("viewBox", `0 0 ${width} ${height}`); pattern.setAttribute("x", String(x)); pattern.setAttribute("y", String(y)); pattern.setAttribute("width", String(width)); pattern.setAttribute("height", String(height)); pattern.setAttribute("patternUnits", "userSpaceOnUse"); const rect = (0, import_ag_charts_core13.createSvgElement)("rect"); rect.setAttribute("x", "0"); rect.setAttribute("y", "0"); rect.setAttribute("width", String(width)); rect.setAttribute("height", String(height)); rect.setAttribute("fill", backgroundFill); rect.setAttribute("fill-opacity", String(backgroundFillOpacity)); pattern.appendChild(rect); const image = (0, import_ag_charts_core13.createSvgElement)("image"); image.setAttribute("href", url); image.setAttribute("x", "0"); image.setAttribute("y", "0"); image.setAttribute("width", String(width)); image.setAttribute("height", String(height)); image.setAttribute("preserveAspectRatio", "none"); image.setAttribute("transform", `scale(${1 / pixelRatio}) rotate(${rotation}, ${width / 2}, ${height / 2})`); pattern.appendChild(image); return pattern; } }; // packages/ag-charts-community/src/scene/pattern/pattern.ts var import_ag_charts_core17 = require("ag-charts-core"); // packages/ag-charts-community/src/scene/extendedPath2D.ts var import_ag_charts_core15 = require("ag-charts-core"); // packages/ag-charts-community/src/util/svg.ts var import_ag_charts_core14 = require("ag-charts-core"); var commandEx = /^[\t\n\f\r ]*([achlmqstvz])[\t\n\f\r ]*/i; var coordinateEx = /^[+-]?((\d*\.\d+)|(\d+\.)|(\d+))(e[+-]?\d+)?/i; var commaEx = /[\t\n\f\r ]*,?[\t\n\f\r ]*/; var flagEx = /^[01]/; var pathParams = { z: [], h: [coordinateEx], v: [coordinateEx], m: [coordinateEx, coordinateEx], l: [coordinateEx, coordinateEx], t: [coordinateEx, coordinateEx], s: [coordinateEx, coordinateEx, coordinateEx, coordinateEx], q: [coordinateEx, coordinateEx, coordinateEx, coordinateEx], c: [coordinateEx, coordinateEx, coordinateEx, coordinateEx, coordinateEx, coordinateEx], a: [coordinateEx, coordinateEx, coordinateEx, flagEx, flagEx, coordinateEx, coordinateEx] }; function parseSvg(d) { if (!d) return; const segments = []; let i = 0; let currentCommand; while (i < d.length) { const commandMatch = commandEx.exec(d.slice(i)); let command; if (commandMatch == null) { if (!currentCommand) { import_ag_charts_core14.Logger.warnOnce(`Invalid SVG path, error at index ${i}: Missing command.`); return; } command = currentCommand; } else { command = commandMatch[1]; i += commandMatch[0].length; } const segment = parseSegment(command, d, i); if (!segment) return; i = segment[0]; currentCommand = command; segments.push(segment[1]); } return segments; } function parseSegment(command, d, index) { const params = pathParams[command.toLocaleLowerCase()]; const pathSeg = { command, params: [] }; for (const regex of params) { const segment = d.slice(index); const match = regex.exec(segment); if (match != null) { pathSeg.params.push(Number.parseFloat(match[0])); index += match[0].length; const next = commaEx.exec(segment.slice(match[0].length)); if (next != null) { index += next[0].length; } } else if (pathSeg.params.length === 1) { return [index, pathSeg]; } else { import_ag_charts_core14.Logger.warnOnce( `Invalid SVG path, error at index ${index}: No path segment parameters for command [${command}]` ); return; } } return [index, pathSeg]; } // 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, delta3 = 1e-6) { if (Math.abs(a) < delta3) { return linearRoot(b, c); } const D = b * b - 4 * a * c; const roots = []; if (Math.abs(D) < delta3) { 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, delta3 = 1e-6) { if (Math.abs(a) < delta3) { return quadraticRoots(b, c, d, delta3); } const A = b / a; const B = c / a; const C = d / a; const Q = (3 * B - A * A) / 9; const R = (9 * A * B - 27 * C - 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 (Math.abs(Im) < delta3) { 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; } // 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 C = 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] + C; 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: // |-1 3 -3 1| |P1| // [t^3 t^2 t 1] | 3 -6 3 0| |P2| // |-3 3 0 0| |P3| // | 1 0 0 0| |P4| -P1 + 3 * P2 - 3 * P3 + P4, 3 * P1 - 6 * P2 + 3 * P3, -3 * P1 + 3 * P2, P1 ]; } // packages/ag-charts-community/src/scene/extendedPath2D.ts var ExtendedPath2D = class { constructor() { this.previousCommands = []; this.previousParams = []; this.previousClosedPath = false; this.commands = []; this.params = []; this.commandsLength = 0; this.paramsLength = 0; this.cx = Number.NaN; this.cy = Number.NaN; this.sx = Number.NaN; this.sy = Number.NaN; this.openedPath = false; this.closedPath = false; const Path2DCtor = (0, import_ag_charts_core15.getPath2D)(); this.path2d = new Path2DCtor(); } isEmpty() { return this.commandsLength === 0; } isDirty() { return this.closedPath !== this.previousClosedPath || this.previousCommands.length !== this.commandsLength || this.previousParams.length !== this.paramsLength || this.previousCommands.toString() !== this.commands.slice(0, this.commandsLength).toString() || this.previousParams.toString() !== this.params.slice(0, this.paramsLength).toString(); } getPath2D() { return this.path2d; } moveTo(x, y) { this.openedPath = true; this.sx = x; this.sy = y; this.cx = x; this.cy = y; this.path2d.moveTo(x, y); this.commands[this.commandsLength++] = 0 /* Move */; this.params[this.paramsLength++] = x; this.params[this.paramsLength++] = y; } lineTo