"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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); 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-enterprise/src/main.ts var main_exports = {}; __export(main_exports, { AgChartsEnterpriseModule: () => AgChartsEnterpriseModule, LicenseManager: () => LicenseManager2, setupEnterpriseModules: () => setupEnterpriseModules2 }); module.exports = __toCommonJS(main_exports); var import_ag_charts_community271 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/license/md5.ts 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; } }; // packages/ag-charts-enterprise/src/license/licenseManager.ts 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 _LicenseManager { constructor(document2) { this.watermarkMessage = void 0; this.totalMessageLength = 124; this.document = document2; this.md5 = new MD5(); this.md5.init(); } validateLicense() { const licenseDetails = this.getLicenseDetails(_LicenseManager.licenseKey, _LicenseManager.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 = _LicenseManager.getChartsReleaseDate(); const formattedReleaseDate = _LicenseManager.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(_LicenseManager.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] = _LicenseManager.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 = _LicenseManager.getChartsReleaseDate(); const { md5, license, version, isTrial, type } = _LicenseManager.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 = _LicenseManager.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: _LicenseManager.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(date) { const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; const day = date.getDate(); const monthIndex = date.getMonth(); const year = date.getFullYear(); return day + " " + monthNames[monthIndex] + " " + year; } static getChartsReleaseDate() { return new Date(parseInt(_LicenseManager.decode(_LicenseManager.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 = _LicenseManager.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) { _LicenseManager.gridContext = gridContext; } static setLicenseKey(licenseKey) { _LicenseManager.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 (!_LicenseManager.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 (!_LicenseManager.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 (!_LicenseManager.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 (!_LicenseManager.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; // packages/ag-charts-enterprise/src/setup.ts var import_ag_charts_community270 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/axes/angle-category/angleCategoryAxis.ts var import_ag_charts_community5 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/utils/polar.ts function loopSymmetrically(items, step, iterator) { const loop = (start, end, loopStep, loopIterator) => { let prev = items[0]; for (let i = start; loopStep > 0 ? i <= end : i > end; 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); } // packages/ag-charts-enterprise/src/axes/angle-number/angleAxisInterval.ts var import_ag_charts_community = require("ag-charts-community"); var { OR, POSITIVE_NUMBER, NAN, AxisInterval, Validate } = import_ag_charts_community._ModuleSupport; var AngleAxisInterval = class extends AxisInterval { constructor() { super(...arguments); this.minSpacing = NaN; } }; __decorateClass([ Validate(OR(POSITIVE_NUMBER, NAN)) ], AngleAxisInterval.prototype, "minSpacing", 2); // packages/ag-charts-enterprise/src/axes/angle/angleAxis.ts var import_ag_charts_community4 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/axes/polar-crosslines/angleCrossLine.ts var import_ag_charts_community3 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/axes/polar-crosslines/polarCrossLine.ts var import_ag_charts_community2 = require("ag-charts-community"); var { BaseProperties, ChartAxisDirection, ARRAY, BOOLEAN, COLOR_STRING, FONT_STYLE, FONT_WEIGHT, LINE_DASH, NUMBER, OBJECT, POSITIVE_NUMBER: POSITIVE_NUMBER2, RATIO, STRING, UNION, AND, Validate: Validate2, MATCHING_CROSSLINE_TYPE, createId, Group } = import_ag_charts_community2._ModuleSupport; var PolarCrossLineLabel = 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([ Validate2(BOOLEAN, { optional: true }) ], PolarCrossLineLabel.prototype, "enabled", 2); __decorateClass([ Validate2(STRING, { optional: true }) ], PolarCrossLineLabel.prototype, "text", 2); __decorateClass([ Validate2(FONT_STYLE, { optional: true }) ], PolarCrossLineLabel.prototype, "fontStyle", 2); __decorateClass([ Validate2(FONT_WEIGHT, { optional: true }) ], PolarCrossLineLabel.prototype, "fontWeight", 2); __decorateClass([ Validate2(POSITIVE_NUMBER2) ], PolarCrossLineLabel.prototype, "fontSize", 2); __decorateClass([ Validate2(STRING) ], PolarCrossLineLabel.prototype, "fontFamily", 2); __decorateClass([ Validate2(NUMBER) ], PolarCrossLineLabel.prototype, "padding", 2); __decorateClass([ Validate2(COLOR_STRING, { optional: true }) ], PolarCrossLineLabel.prototype, "color", 2); __decorateClass([ Validate2(BOOLEAN, { optional: true }) ], PolarCrossLineLabel.prototype, "parallel", 2); var PolarCrossLine = class extends BaseProperties { constructor() { super(...arguments); this.id = createId(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 = ChartAxisDirection.X; this.axisInnerRadius = 0; this.axisOuterRadius = 0; this.lineGroup = new Group({ name: this.id }); this.rangeGroup = new Group({ name: this.id }); this.labelGroup = new Group({ 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; } }; __decorateClass([ Validate2(BOOLEAN, { optional: true }) ], PolarCrossLine.prototype, "enabled", 2); __decorateClass([ Validate2(UNION(["range", "line"], "a crossLine type"), { optional: true }) ], PolarCrossLine.prototype, "type", 2); __decorateClass([ Validate2(AND(MATCHING_CROSSLINE_TYPE("range"), ARRAY.restrict({ length: 2 })), { optional: true }) ], PolarCrossLine.prototype, "range", 2); __decorateClass([ Validate2(MATCHING_CROSSLINE_TYPE("value"), { optional: true }) ], PolarCrossLine.prototype, "value", 2); __decorateClass([ Validate2(COLOR_STRING, { optional: true }) ], PolarCrossLine.prototype, "fill", 2); __decorateClass([ Validate2(RATIO, { optional: true }) ], PolarCrossLine.prototype, "fillOpacity", 2); __decorateClass([ Validate2(COLOR_STRING, { optional: true }) ], PolarCrossLine.prototype, "stroke", 2); __decorateClass([ Validate2(NUMBER, { optional: true }) ], PolarCrossLine.prototype, "strokeWidth", 2); __decorateClass([ Validate2(RATIO, { optional: true }) ], PolarCrossLine.prototype, "strokeOpacity", 2); __decorateClass([ Validate2(LINE_DASH, { optional: true }) ], PolarCrossLine.prototype, "lineDash", 2); __decorateClass([ Validate2(UNION(["polygon", "circle"], "a shape")) ], PolarCrossLine.prototype, "shape", 2); __decorateClass([ Validate2(OBJECT) ], PolarCrossLine.prototype, "label", 2); // packages/ag-charts-enterprise/src/axes/polar-crosslines/angleCrossLine.ts var { ChartAxisDirection: ChartAxisDirection2, validateCrossLineValues, normalizeAngle360, isNumberEqual, Group: Group2, Path, Sector, RotatableText, ContinuousScale, BandScale } = import_ag_charts_community3._ModuleSupport; var AngleCrossLine = class extends PolarCrossLine { constructor() { super(); this.direction = ChartAxisDirection2.X; this.polygonNode = new Path(); this.sectorNode = new Sector(); this.lineNode = new Path(); this.crossLineRange = new Group2(); this.labelNode = new RotatableText(); 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, shape, type, value, range: range2 } = this; const visibilityCheck = () => { if (!ContinuousScale.is(scale)) { return true; } const [start, end] = range2 ?? [value, void 0]; const { domain } = scale; return start >= domain[0] && start <= domain[1] && (type === "line" || end >= start && end <= domain[1]); }; if (!scale || !type || !validateCrossLineValues(type, value, range2, scale, 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" && BandScale.is(scale)) { this.type = "range"; this.range = [value, value]; } this.updateLineNode(visible); this.updatePolygonNode(visible); this.updateSectorNode(visible); this.updateLabelNode(visible); } updateLineNode(visible) { const { scale, type, value, lineNode: line } = this; if (!visible || type !== "line" || !scale) { line.visible = false; return; } const angle = scale.convert(value); if (isNaN(angle)) { 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(angle); const y = axisOuterRadius * Math.sin(angle); const x0 = axisInnerRadius * Math.cos(angle); const y0 = axisInnerRadius * Math.sin(angle); 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: range2, scale, shape, type, ticks } = this; if (!visible || type !== "range" || shape !== "polygon" || !scale || !range2) { polygon.visible = false; return; } const { axisInnerRadius, axisOuterRadius } = this; const startIndex = ticks.indexOf(range2[0]); const endIndex = ticks.indexOf(range2[1]); const stops = startIndex <= endIndex ? ticks.slice(startIndex, endIndex + 1) : ticks.slice(startIndex).concat(ticks.slice(0, endIndex + 1)); const angles = stops.map((value) => scale.convert(value)); polygon.visible = true; this.setSectorNodeProps(polygon); const { path } = polygon; path.clear(true); angles.forEach((angle, index) => { const x = axisOuterRadius * Math.cos(angle); const y = axisOuterRadius * Math.sin(angle); if (index === 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } }); if (axisInnerRadius === 0) { path.lineTo(0, 0); } else { angles.slice().reverse().forEach((angle) => { const x = axisInnerRadius * Math.cos(angle); const y = axisInnerRadius * Math.sin(angle); path.lineTo(x, y); }); } polygon.path.closePath(); this.assignCrossLineGroup(true, this.crossLineRange); } updateSectorNode(visible) { const { sectorNode: sector, range: range2, scale, shape, type } = this; if (!visible || type !== "range" || shape !== "circle" || !scale || !range2) { sector.visible = false; return; } const { axisInnerRadius, axisOuterRadius } = this; const angles = range2.map((value) => scale.convert(value)); const step = scale.step ?? 0; const padding = scale 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: range2, scale, type, ticks } = this; if (!visible || label.enabled === false || !label.text || !scale || type === "range" && !range2) { node.visible = false; return; } node.visible = true; const { axisInnerRadius, axisOuterRadius } = this; let labelX; let labelY; let rotation; let textBaseline; if (type === "line") { const angle = normalizeAngle360(scale.convert(this.value)); const angle270 = 1.5 * Math.PI; const isRightSide = isNumberEqual(angle, angle270) || angle > angle270 || angle < Math.PI / 2; const midX = (axisInnerRadius + axisOuterRadius) / 2 * Math.cos(angle); const midY = (axisInnerRadius + axisOuterRadius) / 2 * Math.sin(angle); labelX = midX + label.padding * Math.cos(angle + Math.PI / 2); labelY = midY + label.padding * Math.sin(angle + Math.PI / 2); textBaseline = isRightSide ? "top" : "bottom"; rotation = isRightSide ? angle : angle - Math.PI; } else { const [startAngle, endAngle] = range2.map((value) => normalizeAngle360(scale.convert(value))); let angle = (startAngle + endAngle) / 2; if (startAngle > endAngle) { angle -= Math.PI; } angle = normalizeAngle360(angle); const isBottomSide = (isNumberEqual(angle, 0) || angle > 0) && angle < Math.PI; let distance; if (this.shape === "circle" || ticks.length < 3) { distance = axisOuterRadius - label.padding; } else { distance = axisOuterRadius * Math.cos(Math.PI / ticks.length) - label.padding; } labelX = distance * Math.cos(angle); labelY = distance * Math.sin(angle); textBaseline = isBottomSide ? "bottom" : "top"; rotation = isBottomSide ? angle - Math.PI / 2 : angle + Math.PI / 2; } this.setLabelNodeProps(node, labelX, labelY, textBaseline, rotation); } }; AngleCrossLine.className = "AngleCrossLine"; // packages/ag-charts-enterprise/src/axes/angle/angleAxis.ts var { ChartAxisDirection: ChartAxisDirection3, NUMBER: NUMBER2, UNION: UNION2, ProxyOnWrite, TextWrapper, TextUtils, Validate: Validate3, isNumberEqual: isNumberEqual2, toRadians, normalizeAngle360: normalizeAngle3602, normalizeAngle360Inclusive, Path: Path2, RotatableText: RotatableText2, Transformable, BBox } = import_ag_charts_community4._ModuleSupport; var AngleAxisLabel = class extends import_ag_charts_community4._ModuleSupport.AxisLabel { constructor() { super(...arguments); this.orientation = "fixed"; } }; __decorateClass([ Validate3(UNION2(["fixed", "parallel", "perpendicular"], "a label orientation")) ], AngleAxisLabel.prototype, "orientation", 2); var AngleAxis = class extends import_ag_charts_community4._ModuleSupport.PolarAxis { constructor(moduleCtx, scale) { super(moduleCtx, scale); this.startAngle = 0; this.endAngle = void 0; this.labelData = []; this.tickData = []; this.radiusLine = this.axisGroup.appendChild(new Path2()); this.includeInvisibleDomains = true; } get direction() { return ChartAxisDirection3.X; } createLabel() { return new AngleAxisLabel(); } calculateTickLayout(domain) { const { nice, scale } = this; const ticksParams = { nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity }; const niceDomain = nice ? scale.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 = normalizeAngle3602(-Math.PI / 2 + toRadians(this.startAngle)); const sweep = this.endAngle != null ? normalizeAngle360Inclusive(toRadians(this.endAngle) - toRadians(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, shape, gridLength: radius } = this; const [startAngle, endAngle] = this.range; const isFullCircle = isNumberEqual2(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: normalizeAngle3602(startAngle), endAngle: normalizeAngle3602(endAngle), arc: true, moveTo: false } ); } } else if (shape === "polygon") { const angles = scale.ticks({ nice: this.nice, interval: void 0, tickCount: void 0, minTickCount: 0, maxTickCount: Infinity })?.map((value) => scale.convert(value)); if (angles && angles.length > 2) { angles.forEach((angle, i) => { const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); const moveTo = i === 0; points.push({ x, y, moveTo }); }); } } return { points, closePath: isFullCircle }; } updateGridLines() { const { scale, gridLength: radius, gridLine: { style, width }, 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: stroke2, lineDash } = style[index % styleCount]; const angle = scale.convert(value); line.x1 = innerRadius * Math.cos(angle); line.y1 = innerRadius * Math.sin(angle); line.x2 = radius * Math.cos(angle); line.y2 = radius * Math.sin(angle); line.stroke = stroke2; line.strokeWidth = width; 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, gridLength: radius, tick, tickLineGroupSelection } = this; tickLineGroupSelection.each((line, datum) => { const { value } = datum; const angle = scale.convert(value); const cos = Math.cos(angle); const sin = Math.sin(angle); 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, tick } = this; if (!label.enabled) { return []; } const tempText2 = new RotatableText2(); 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 distance = radius + label.spacing + tick.size; const angle = scale.convert(value); const cos = Math.cos(angle); const sin = Math.sin(angle); const x = distance * cos; const y = distance * sin; const { textAlign, textBaseline } = this.getLabelAlign(angle); const isLastTickOverFirst = index === ticks.length - 1 && value !== ticks[0] && isNumberEqual2(normalizeAngle3602(angle), normalizeAngle3602(scale.convert(ticks[0]))); const rotation = this.getLabelRotation(angle); let text2 = String(value); if (label.formatter) { const { callbackCache } = this.moduleCtx; text2 = callbackCache.call(label.formatter, { value, index }) ?? ""; } tempText2.text = text2; 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 ? Transformable.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); text2 = TextWrapper.wrapText(text2, { maxWidth: availWidth, font: label, textWrap: "never" }); if (text2 === TextUtils.EllipsisChar) { text2 = ""; } tempText2.text = text2; box = tempText2.getBBox(); } } return { text: text2, x, y, textAlign, textBaseline, hidden: text2 === "" || 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 BBox.merge(textBoxes); } getLabelOrientation() { const { label } = this; return label instanceof AngleAxisLabel ? label.orientation : "fixed"; } getLabelRotation(tickAngle) { let rotation = toRadians(this.label.rotation ?? 0); tickAngle = normalizeAngle3602(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 = isNumberEqual2(cos, 0); const isSin0 = isNumberEqual2(sin, 0); const isCos1 = isNumberEqual2(cos, 1); const isSinMinus1 = isNumberEqual2(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; __decorateClass([ ProxyOnWrite("rotation"), Validate3(NUMBER2) ], AngleAxis.prototype, "startAngle", 2); __decorateClass([ Validate3(NUMBER2, { optional: true }) ], AngleAxis.prototype, "endAngle", 2); // packages/ag-charts-enterprise/src/axes/angle-category/angleCategoryAxis.ts var { RATIO: RATIO2, OBJECT: OBJECT2, Validate: Validate4, isNumberEqual: isNumberEqual3, CategoryScale } = import_ag_charts_community5._ModuleSupport; var AngleCategoryAxis = class extends AngleAxis { constructor(moduleCtx) { super(moduleCtx, new CategoryScale()); this.groupPaddingInner = 0; this.paddingInner = 0; this.interval = new AngleAxisInterval(); } generateAngleTicks() { const { scale, gridLength: radius } = this; const { values, minSpacing } = this.interval; const ticks = values ?? scale.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 = scale.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 = scale.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"; __decorateClass([ Validate4(RATIO2) ], AngleCategoryAxis.prototype, "groupPaddingInner", 2); __decorateClass([ Validate4(RATIO2) ], AngleCategoryAxis.prototype, "paddingInner", 2); __decorateClass([ Validate4(OBJECT2) ], AngleCategoryAxis.prototype, "interval", 2); // packages/ag-charts-enterprise/src/axes/angle-category/angleCategoryAxisModule.ts var AngleCategoryAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "angle-category", moduleFactory: (ctx) => new AngleCategoryAxis(ctx) }; // packages/ag-charts-enterprise/src/axes/angle-number/angleNumberAxis.ts var import_ag_charts_community7 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/axes/angle-number/linearAngleScale.ts var import_ag_charts_community6 = require("ag-charts-community"); var { range, isDenseInterval, isNumberEqual: isNumberEqual4, LinearScale } = import_ag_charts_community6._ModuleSupport; var LinearAngleScale = class _LinearAngleScale extends LinearScale { constructor() { super(...arguments); this.arcLength = 0; } static getNiceStepAndTickCount(ticks, domain) { const [start, stop] = domain; let step = LinearScale.getTickStep(start, stop, ticks); const maxTickCount = isNaN(ticks.maxTickCount) ? Infinity : ticks.maxTickCount; const expectedTickCount = Math.abs(stop - start) / 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 (!isDenseInterval((d1 - d0) / step2, availableRange)) { return range(d0, d1, step2); } } let step; if (nice && this.hasNiceRange()) { const linearNiceDomain = super.niceDomain(ticks, domain); step = _LinearAngleScale.getNiceStepAndTickCount(ticks, linearNiceDomain).step; } else { step = LinearScale.getTickStep(d0, d1, ticks); } return range(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 start = reversed ? linearNiceDomain[1] : linearNiceDomain[0]; const { step, count } = _LinearAngleScale.getNiceStepAndTickCount(ticks, linearNiceDomain); const s = 1 / step; const stop = step >= 1 ? Math.ceil(start / step + count) * step : Math.ceil((start + count * step) * s) / s; return reversed ? [stop, start] : [start, stop]; } getPixelRange() { return this.arcLength; } }; // packages/ag-charts-enterprise/src/axes/angle-number/angleNumberAxis.ts var { AND: AND2, Default, GREATER_THAN, LESS_THAN, NUMBER_OR_NAN, OBJECT: OBJECT3, Validate: Validate5, angleBetween, isNumberEqual: isNumberEqual5, normalisedExtentWithMetadata, findMinMax } = 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 } = normalisedExtentWithMetadata(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 = angleBetween(min, max) || 2 * Math.PI; const radius = this.gridLength; return rotation * radius; } generateAngleTicks(domain) { const { scale, range: requestedRange, nice } = this; const { values, step, minSpacing, maxSpacing } = this.interval; let rawTicks; if (values == null) { const { arcLength } = scale; 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 = scale.ticks(tickParams, domain); } else { const [d0, d1] = findMinMax(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"; __decorateClass([ Validate5(AND2(NUMBER_OR_NAN, LESS_THAN("max"))), Default(NaN) ], AngleNumberAxis.prototype, "min", 2); __decorateClass([ Validate5(AND2(NUMBER_OR_NAN, GREATER_THAN("min"))), Default(NaN) ], AngleNumberAxis.prototype, "max", 2); __decorateClass([ Validate5(OBJECT3) ], AngleNumberAxis.prototype, "interval", 2); // packages/ag-charts-enterprise/src/axes/angle-number/angleNumberAxisModule.ts var AngleNumberAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "angle-number", moduleFactory: (ctx) => new AngleNumberAxis(ctx) }; // packages/ag-charts-enterprise/src/axes/ordinal/ordinalTimeAxis.ts var import_ag_charts_community8 = require("ag-charts-community"); var { OrdinalTimeScale } = import_ag_charts_community8._ModuleSupport; var OrdinalTimeAxis = class extends import_ag_charts_community8._ModuleSupport.CategoryAxis { constructor(moduleCtx) { super(moduleCtx, new OrdinalTimeScale()); } }; OrdinalTimeAxis.className = "OrdinalTimeAxis"; OrdinalTimeAxis.type = "ordinal-time"; // packages/ag-charts-enterprise/src/axes/ordinal/ordinalTimeAxisModule.ts var OrdinalTimeAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "ordinal-time", moduleFactory: (ctx) => new OrdinalTimeAxis(ctx) }; // packages/ag-charts-enterprise/src/axes/radius-category/radiusCategoryAxis.ts var import_ag_charts_community11 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/axes/radius/radiusAxis.ts var import_ag_charts_community10 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/axes/polar-crosslines/radiusCrossLine.ts var import_ag_charts_community9 = require("ag-charts-community"); var { ChartAxisDirection: ChartAxisDirection4, Validate: Validate6, NUMBER: NUMBER3, validateCrossLineValues: validateCrossLineValues2, clamp, normalizeAngle360: normalizeAngle3603, toRadians: toRadians2, isNumberEqual: isNumberEqual6, Group: Group3, Path: Path3, Sector: Sector2, RotatableText: RotatableText3 } = import_ag_charts_community9._ModuleSupport; var RadiusCrossLineLabel = class extends PolarCrossLineLabel { constructor() { super(...arguments); this.positionAngle = void 0; } }; __decorateClass([ 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 Sector2(); 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, type, value, range: range2 } = this; if (!scale || !type || !validateCrossLineValues2(type, value, range2, scale)) { this.rangeGroup.visible = false; this.lineGroup.visible = false; this.labelGroup.visible = false; return; } if (type === "line" && scale 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: range2, scale, type, axisInnerRadius, axisOuterRadius } = this; if (!scale) return { innerRadius: 0, outerRadius: 0 }; const getRadius = (value) => axisOuterRadius + axisInnerRadius - value; let outerRadius, innerRadius; if (type === "line") { outerRadius = getRadius(scale.convert(this.value)); innerRadius = outerRadius; } else { const bandwidth = Math.abs(scale?.bandwidth ?? 0); const convertedRange = range2.map((r) => scale.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((angle, index) => { const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); if (index === 0) { polygon.path.moveTo(x, y); } else { polygon.path.lineTo(x, y); } }); polygon.path.closePath(); } updatePolygonNode(visible) { const { gridAngles, polygonNode: polygon, scale, shape, type, innerRadius, outerRadius } = this; if (!visible || shape !== "polygon" || !scale || !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, sectorNode: sector, shape, innerRadius, outerRadius } = this; if (!visible || shape !== "circle" || !scale) { sector.visible = false; return; } sector.visible = true; sector.startAngle = 0; sector.endAngle = 2 * Math.PI; const padding = this.getPadding(); const r0 = clamp(axisInnerRadius, innerRadius + padding, axisOuterRadius); const r1 = clamp(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, shape, type } = this; if (!visible || label.enabled === false || !label.text || !scale) { node.visible = false; return; } const angle = normalizeAngle3603(toRadians2((label.positionAngle ?? 0) - 90)); const isBottomSide = (isNumberEqual6(angle, 0) || angle > 0) && angle < Math.PI; const rotation = isBottomSide ? angle - Math.PI / 2 : angle + Math.PI / 2; let distance; const angles = this.gridAngles ?? []; if (type === "line") { distance = innerRadius + label.padding; } else if (shape === "circle" || angles.length < 3) { distance = innerRadius - label.padding; } else { distance = innerRadius * Math.cos(Math.PI / angles.length) - label.padding; } const labelX = distance * Math.cos(angle); const labelY = distance * Math.sin(angle); let textBaseline; if (type === "line") { textBaseline = isBottomSide ? "top" : "bottom"; } else { textBaseline = isBottomSide ? "bottom" : "top"; } this.setLabelNodeProps(node, labelX, labelY, textBaseline, rotation); } getPadding() { const { scale } = this; if (!scale) return 0; const bandwidth = Math.abs(scale.bandwidth ?? 0); const step = Math.abs(scale.step ?? 0); return scale instanceof import_ag_charts_community9._ModuleSupport.BandScale ? (step - bandwidth) / 2 : 0; } }; RadiusCrossLine.className = "RadiusCrossLine"; // packages/ag-charts-enterprise/src/axes/radius/radiusAxis.ts var { ChartAxisDirection: ChartAxisDirection5, Default: Default2, ZIndexMap, NUMBER: NUMBER4, BOOLEAN: BOOLEAN2, Validate: Validate7, isNumberEqual: isNumberEqual7, normalizeAngle360: normalizeAngle3604, toRadians: toRadians3, Caption, Group: Group4, Path: Path4, Line, Selection, AxisTickGenerator, AxisGroupZIndexMap } = import_ag_charts_community10._ModuleSupport; var RadiusAxisLabel = class extends import_ag_charts_community10._ModuleSupport.AxisLabel { constructor() { super(...arguments); this.autoRotateAngle = 335; } }; __decorateClass([ Validate7(BOOLEAN2, { optional: true }) ], RadiusAxisLabel.prototype, "autoRotate", 2); __decorateClass([ Validate7(NUMBER4) ], RadiusAxisLabel.prototype, "autoRotateAngle", 2); var RadiusAxis = class extends import_ag_charts_community10._ModuleSupport.PolarAxis { constructor(moduleCtx, scale) { super(moduleCtx, scale); this.positionAngle = 0; this.tickGenerator = new AxisTickGenerator(this); this.generatedTicks = void 0; this.lineNode = this.axisGroup.appendChild( new Line({ name: `${this.id}-Axis-line`, zIndex: AxisGroupZIndexMap.AxisLine }) ); this.gridPathGroup = this.gridGroup.appendChild( new Group4({ name: `${this.id}-gridPaths`, zIndex: ZIndexMap.AXIS_GRID }) ); this.gridPathSelection = Selection.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: stroke2, width } = this.line; this.lineNode.setProperties({ stroke: stroke2, strokeWidth: enabled ? width : 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 }, shape, generatedTicks } = this; if (!style || !generatedTicks) { return; } const styleCount = style.length; const setStyle = (node, index) => { const { stroke: stroke2, lineDash } = style[index % styleCount]; node.stroke = stroke2; node.strokeWidth = width; 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((angle, idx) => { const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); 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 = -Caption.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: range2, innerRadiusRatio } = this; const radius = range2[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 range2 = this.scale.range; const text2 = datum.tickLabel; const sideFlag = label.getSideFlag(); const labelX = sideFlag * (this.getTickSize() + label.spacing + this.seriesAreaPadding); const visible = text2 !== "" && text2 != null; return { ...this.getLabelStyles({ value: datum.tickLabel }), tickId: datum.tickId, rotation: combinedRotation, rotationCenterX: labelX, translationY: datum.translationY, text: text2, textAlign, textBaseline, visible, x: labelX, y: 0, range: range2 }; } }; RadiusAxis.CrossLineConstructor = RadiusCrossLine; __decorateClass([ Validate7(NUMBER4), Default2(0) ], RadiusAxis.prototype, "positionAngle", 2); // packages/ag-charts-enterprise/src/axes/radius-category/radiusCategoryAxis.ts var { RATIO: RATIO3, ProxyPropertyOnWrite, Validate: Validate8, CategoryScale: CategoryScale2 } = import_ag_charts_community11._ModuleSupport; var RadiusCategoryAxis = class extends RadiusAxis { constructor(moduleCtx) { super(moduleCtx, new CategoryScale2()); 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, innerRadiusRatio } = this; const maxRadius = scale.range[0]; const minRadius = maxRadius * innerRadiusRatio; if (CategoryScale2.is(scale)) { const ticks = scale.domain; const index = ticks.length - 1 - ticks.indexOf(tickDatum.tick); return index === 0 ? minRadius : scale.inset + scale.step * (index - 0.5) + scale.bandwidth / 2; } else { const tickRange = (maxRadius - minRadius) / scale.domain.length; return maxRadius - tickDatum.translationY + minRadius - tickRange / 2; } } }; RadiusCategoryAxis.className = "RadiusCategoryAxis"; RadiusCategoryAxis.type = "radius-category"; __decorateClass([ Validate8(RATIO3) ], RadiusCategoryAxis.prototype, "groupPaddingInner", 2); __decorateClass([ ProxyPropertyOnWrite("scale", "paddingInner"), Validate8(RATIO3) ], RadiusCategoryAxis.prototype, "paddingInner", 2); __decorateClass([ ProxyPropertyOnWrite("scale", "paddingOuter"), Validate8(RATIO3) ], RadiusCategoryAxis.prototype, "paddingOuter", 2); // packages/ag-charts-enterprise/src/axes/radius-category/radiusCategoryAxisModule.ts var RadiusCategoryAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radius-category", moduleFactory: (ctx) => new RadiusCategoryAxis(ctx) }; // packages/ag-charts-enterprise/src/axes/radius-number/radiusNumberAxis.ts var import_ag_charts_community12 = require("ag-charts-community"); var { AND: AND3, Default: Default3, GREATER_THAN: GREATER_THAN2, LESS_THAN: LESS_THAN2, NUMBER_OR_NAN: NUMBER_OR_NAN2, Validate: Validate9, normalisedExtentWithMetadata: normalisedExtentWithMetadata2, LinearScale: LinearScale2 } = import_ag_charts_community12._ModuleSupport; var RadiusNumberAxis = class extends RadiusAxis { constructor(moduleCtx) { super(moduleCtx, new LinearScale2()); this.shape = "polygon"; this.min = NaN; this.max = NaN; } prepareGridPathTickData(data) { const { scale } = this; const domainTop = scale.domain[1]; return data.filter(({ tick }) => tick !== domainTop).sort((a, b) => b.tick - a.tick); } getTickRadius(tickDatum) { const { scale } = this; const maxRadius = scale.range[0]; const minRadius = maxRadius * this.innerRadiusRatio; return maxRadius - tickDatum.translationY + minRadius; } normaliseDataDomain(d) { const { min, max } = this; const { extent: extent3, clipped } = normalisedExtentWithMetadata2(d, min, max); return { domain: extent3, clipped }; } }; RadiusNumberAxis.className = "RadiusNumberAxis"; RadiusNumberAxis.type = "radius-number"; __decorateClass([ Validate9(AND3(NUMBER_OR_NAN2, LESS_THAN2("max"))), Default3(NaN) ], RadiusNumberAxis.prototype, "min", 2); __decorateClass([ Validate9(AND3(NUMBER_OR_NAN2, GREATER_THAN2("min"))), Default3(NaN) ], RadiusNumberAxis.prototype, "max", 2); // packages/ag-charts-enterprise/src/axes/radius-number/radiusNumberAxisModule.ts var RadiusNumberAxisModule = { type: "axis", optionsKey: "axes[]", packageType: "enterprise", chartTypes: ["polar"], identifier: "radius-number", moduleFactory: (ctx) => new RadiusNumberAxis(ctx) }; // packages/ag-charts-enterprise/src/charts/flowProportionChartModule.ts var import_ag_charts_community14 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/charts/flowProportionChart.ts var import_ag_charts_community13 = require("ag-charts-community"); var { Chart } = import_ag_charts_community13._ModuleSupport; function isFlowProportion(series) { return series.type === "sankey" || series.type === "chord"; } var FlowProportionChart = class extends Chart { 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"; // packages/ag-charts-enterprise/src/charts/flowProportionChartModule.ts var { isAgFlowProportionChartOptions } = import_ag_charts_community14._ModuleSupport; var FlowProportionChartModule = { type: "chart", name: "flow-proportion", detect: isAgFlowProportionChartOptions, create(options, resources) { return new FlowProportionChart(options, resources); } }; // packages/ag-charts-enterprise/src/charts/gaugeChartModule.ts var import_ag_charts_community16 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/charts/gaugeChart.ts var import_ag_charts_community15 = require("ag-charts-community"); // 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 }); var doOnceCache = /* @__PURE__ */ new Set(); function log(...logContent) { console.log(...logContent); } function warn(message, ...logContent) { console.warn(`AG Charts - ${message}`, ...logContent); } function error(message, ...logContent) { if (typeof message === "object") { console.error(`AG Charts error`, message, ...logContent); } else { console.error(`AG Charts - ${message}`, ...logContent); } } function table(...logContent) { console.table(...logContent); } function 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(); } } // packages/ag-charts-core/src/utils/arrays.ts function unique(array) { return Array.from(new Set(array)); } // packages/ag-charts-core/src/utils/binarySearch.ts 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; } // packages/ag-charts-core/src/utils/functions.ts function debounce(callback, 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); callback(...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) { callback(...args); } }, adjustedWaitMs); } return Object.assign(debounceCallback, { cancel() { clearTimeout(timerId); startTime = null; } }); } // packages/ag-charts-core/src/utils/iterators.ts function* iterate(...iterators) { for (const iterator of iterators) { yield* iterator; } } // packages/ag-charts-core/src/utils/typeGuards.ts function isDefined(val) { return val != null; } function isArray(value) { return Array.isArray(value); } function isDate(value) { return value instanceof Date; } function isValidDate(value) { return isDate(value) && !isNaN(Number(value)); } function isObject(value) { return typeof value === "object" && value !== null && !isArray(value); } function isString(value) { return typeof value === "string"; } function isNumber(value) { return typeof value === "number"; } function isFiniteNumber(value) { return Number.isFinite(value); } // packages/ag-charts-enterprise/src/charts/gaugeChart.ts var { CartesianAxis, Chart: Chart2, ChartAxisDirection: ChartAxisDirection6, LinearScale: LinearScale3, PolarAxis, isBetweenAngles, normalizeAngle360Inclusive: normalizeAngle360Inclusive2, sectorBox } = 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 Chart2 { getChartType() { return "gauge"; } updateRadialGauge(seriesRect, series) { const angleAxis = this.axes.find((axis) => axis.direction === ChartAxisDirection6.X); if (!(angleAxis instanceof PolarAxis)) 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 = normalizeAngle360Inclusive2(endAngle - startAngle); const largerThanHalf = sweepAngle > Math.PI; const containsTop = largerThanHalf || isBetweenAngles(1.5 * Math.PI, startAngle, endAngle); const containsRight = largerThanHalf || isBetweenAngles(0 * Math.PI, startAngle, endAngle); const containsBottom = largerThanHalf || isBetweenAngles(0.5 * Math.PI, startAngle, endAngle); const containsLeft = largerThanHalf || isBetweenAngles(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 = sectorBox({ 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_exports.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 CartesianAxis)) return seriesRect; if (!(yAxis instanceof CartesianAxis)) return seriesRect; const { horizontal, thickness } = series; let horizontalInset = 0; let verticalInset = 0; const scale = new LinearScale3(); const scaleAxis = horizontal ? xAxis : yAxis; scale.domain = [0, 100]; scale.range = scaleAxis.range; const ticks = scale.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, height } = 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 - width) / 2 + Math.max(horizontalInset, 0); const y0 = seriesRect.y + (seriesHeight - height) / 2 - Math.min(verticalInset, 0); xAxis.range = [0, width]; xAxis.gridLength = width; xAxis.calculateLayout(); xAxis.translation.x = x0; xAxis.translation.y = y0 + (xAxis.position === "bottom" ? thickness : 0); yAxis.range = [0, height]; yAxis.gridLength = height; 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 (width === 0 || height === 0) { logger_exports.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"; // packages/ag-charts-enterprise/src/charts/gaugeChartModule.ts var { isAgGaugeChartOptions } = import_ag_charts_community16._ModuleSupport; var GaugeChartModule = { type: "chart", name: "gauge", detect: isAgGaugeChartOptions, create(options, resources) { return new GaugeChart(options, resources); } }; // packages/ag-charts-enterprise/src/charts/hierarchyChartModule.ts var import_ag_charts_community18 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/charts/hierarchyChart.ts var import_ag_charts_community17 = require("ag-charts-community"); 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"; // packages/ag-charts-enterprise/src/charts/hierarchyChartModule.ts var { isAgHierarchyChartOptions } = import_ag_charts_community18._ModuleSupport; var HierarchyChartModule = { type: "chart", name: "hierarchy", detect: isAgHierarchyChartOptions, create(options, resources) { return new HierarchyChart(options, resources); } }; // packages/ag-charts-enterprise/src/charts/standaloneChartModule.ts var import_ag_charts_community20 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/charts/standaloneChart.ts var import_ag_charts_community19 = require("ag-charts-community"); 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"; // packages/ag-charts-enterprise/src/charts/standaloneChartModule.ts var { isAgStandaloneChartOptions } = import_ag_charts_community20._ModuleSupport; var StandaloneChartModule = { type: "chart", name: "standalone", detect: isAgStandaloneChartOptions, create(options, resources) { return new StandaloneChart(options, resources); } }; // packages/ag-charts-enterprise/src/charts/topologyChartModule.ts var import_ag_charts_community22 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/charts/topologyChart.ts var import_ag_charts_community21 = require("ag-charts-community"); var { Chart: Chart5, MercatorScale, NumberAxis } = 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 NumberAxis(this.getModuleContext()); this.xAxis.position = "bottom"; this.yAxis = new NumberAxis(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 scale; if (combinedBbox != null) { const { lon0, lat0, lon1, lat1 } = combinedBbox; const domain = [ [lon0, lat0], [lon1, lat1] ]; const bounds = MercatorScale.bounds(domain); const { width, height } = seriesRect; const viewBoxScale = Math.min(width / bounds.width, height / bounds.height); const viewBoxWidth = bounds.width * viewBoxScale; const viewBoxHeight = bounds.height * viewBoxScale; const viewBoxOriginX = (width - viewBoxWidth) / 2; const viewBoxOriginY = (height - 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); scale = new MercatorScale(domain, [ [xStart, yStart], [xStart + xSpan, yStart + ySpan] ]); } mapSeries.forEach((series) => { series.scale = scale; }); 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"; // packages/ag-charts-enterprise/src/charts/topologyChartModule.ts var { isAgTopologyChartOptions } = import_ag_charts_community22._ModuleSupport; var TopologyChartModule = { type: "chart", name: "topology", detect: isAgTopologyChartOptions, create(options, resources) { return new TopologyChart(options, resources); } }; // packages/ag-charts-enterprise/src/features/animation/animation.ts var import_ag_charts_community23 = require("ag-charts-community"); var { BOOLEAN: BOOLEAN3, POSITIVE_NUMBER: POSITIVE_NUMBER3, ObserveChanges, Validate: Validate10 } = import_ag_charts_community23._ModuleSupport; var Animation = class extends import_ag_charts_community23._ModuleSupport.BaseModuleInstance { constructor(ctx) { super(); this.ctx = ctx; this.enabled = true; ctx.animationManager.skip(false); } }; __decorateClass([ ObserveChanges((target, newValue) => { target.ctx.animationManager.skip(!newValue); }), Validate10(BOOLEAN3) ], Animation.prototype, "enabled", 2); __decorateClass([ ObserveChanges((target, newValue) => { target.ctx.animationManager.defaultDuration = newValue; }), Validate10(POSITIVE_NUMBER3, { optional: true }) ], Animation.prototype, "duration", 2); // packages/ag-charts-enterprise/src/features/animation/animationModule.ts var AnimationModule = { type: "root", optionsKey: "animation", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Animation(ctx), themeTemplate: { animation: { enabled: true } } }; // packages/ag-charts-enterprise/src/features/annotations/annotations.ts var import_ag_charts_community98 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/text-input/textInput.ts var import_ag_charts_community24 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/text-input/textInputTemplate.html var textInputTemplate_default = '
'; // packages/ag-charts-enterprise/src/features/text-input/textInput.ts var { focusCursorAtEnd } = import_ag_charts_community24._ModuleSupport; var moduleId = "text-input"; var canvasOverlay = "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(canvasOverlay, moduleId); this.element.classList.add("ag-charts-text-input"); this.destroyFns.push(() => ctx.domManager.removeChild(canvasOverlay, 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"; focusCursorAtEnd(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 } = this; const textArea = element.firstElementChild; if (!textArea) return; const sceneRect = this.ctx.domManager.getBoundingClientRect(); const { width, getTextInputCoords, getTextPosition, alignment, textAlign } = this.layout; element.style.setProperty("width", width ? `${width}px` : "unset"); const textRect = textArea.getBoundingClientRect(); const point = getTextInputCoords(textRect.height); let horizontalPosition = point.x; if (alignment === "center") { horizontalPosition -= (width ?? textRect.width) / 2; } else if (alignment === "right") { horizontalPosition -= width ?? textRect.width; } const position = getTextPosition(); let verticalPosition = point.y; if (position === "center") { verticalPosition -= textRect.height / 2; } else if (position === "bottom") { verticalPosition -= textRect.height; } element.style.setProperty("top", `${verticalPosition}px`); element.style.setProperty("left", `${horizontalPosition}px`); element.style.setProperty("max-width", `${sceneRect.width - horizontalPosition}px`); element.style.setProperty("text-align", alignment); textArea.style.setProperty("text-align", textAlign); } getBBox() { const { left, top, width, height } = this.element.getBoundingClientRect(); return new import_ag_charts_community24._ModuleSupport.BBox(left, top, width, height); } }; // packages/ag-charts-enterprise/src/features/annotations/annotationAxesButtons.ts var import_ag_charts_community25 = require("ag-charts-community"); var { BOOLEAN: BOOLEAN4, BaseProperties: BaseProperties2, Validate: Validate11, UNION: UNION3 } = import_ag_charts_community25._ModuleSupport; var AXIS_TYPE = UNION3(["x", "y", "xy"], "an axis type"); var AxesButtons = class extends BaseProperties2 { constructor() { super(...arguments); this.enabled = false; this.axes = "y"; } }; __decorateClass([ Validate11(BOOLEAN4) ], AxesButtons.prototype, "enabled", 2); __decorateClass([ Validate11(AXIS_TYPE, { optional: true }) ], AxesButtons.prototype, "axes", 2); // packages/ag-charts-enterprise/src/features/annotations/annotationDefaults.ts var import_ag_charts_community47 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/annotationTypes.ts 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; } } // packages/ag-charts-enterprise/src/features/annotations/callout/calloutProperties.ts var import_ag_charts_community30 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/annotationProperties.ts var import_ag_charts_community26 = require("ag-charts-community"); var { BOOLEAN: BOOLEAN5, COLOR_STRING: COLOR_STRING2, DATE, FONT_STYLE: FONT_STYLE2, FONT_WEIGHT: FONT_WEIGHT2, FUNCTION, LINE_DASH: LINE_DASH2, LINE_STYLE, NUMBER: NUMBER5, OBJECT: OBJECT4, OR: OR2, POSITIVE_NUMBER: POSITIVE_NUMBER4, RATIO: RATIO4, STRING: STRING2, TEXT_ALIGN, UNION: UNION4, BaseProperties: BaseProperties3, Validate: Validate12, predicateWithMessage, generateUUID } = import_ag_charts_community26._ModuleSupport; var GROUPING_VALUE_KEYS = ["value", "groupPercentage"]; var GROUPING_VALUE = predicateWithMessage( (value) => isObject(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 { }; __decorateClass([ Validate12(OR2(STRING2, NUMBER5, DATE, GROUPING_VALUE)) ], PointProperties.prototype, "x", 2); __decorateClass([ Validate12(OR2(STRING2, NUMBER5, DATE, GROUPING_VALUE)) ], PointProperties.prototype, "y", 2); var ChannelAnnotationMiddleProperties = class extends Stroke(LineStyle(Visible(BaseProperties3))) { }; var AxisLabelProperties = class extends Stroke(LineStyle(Fill(Label(Font(BaseProperties3))))) { constructor() { super(...arguments); this.cornerRadius = 2; } }; __decorateClass([ Validate12(BOOLEAN5) ], AxisLabelProperties.prototype, "enabled", 2); __decorateClass([ 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"; } }; __decorateClass([ Validate12(STRING2) ], LineTextProperties.prototype, "label", 2); __decorateClass([ Validate12(UNION4(["top", "center", "bottom"]), { optional: true }) ], LineTextProperties.prototype, "position", 2); __decorateClass([ 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 = ""; } }; __decorateClass([ Validate12(STRING2) ], ChannelTextProperties.prototype, "label", 2); __decorateClass([ Validate12(UNION4(["top", "inside", "bottom"]), { optional: true }) ], ChannelTextProperties.prototype, "position", 2); __decorateClass([ Validate12(UNION4(["left", "center", "right"]), { optional: true }) ], ChannelTextProperties.prototype, "alignment", 2); function Annotation(Parent) { class AnnotationInternal extends Lockable(Visible(Parent)) { constructor() { super(...arguments); // A uuid is required, over the usual incrementing index, as annotations can be restored from external databases this.id = generateUUID(); } isValidWithContext(_context, warningPrefix) { return super.isValid(warningPrefix); } } return AnnotationInternal; } function Line2(Parent) { class LineInternal extends Parent { constructor() { super(...arguments); this.start = new PointProperties(); this.end = new PointProperties(); } } __decorateClass([ Validate12(OBJECT4) ], LineInternal.prototype, "start", 2); __decorateClass([ Validate12(OBJECT4) ], LineInternal.prototype, "end", 2); return LineInternal; } function Point(Parent) { class PointInternal extends Parent { } __decorateClass([ Validate12(OR2(STRING2, NUMBER5, DATE, GROUPING_VALUE)) ], PointInternal.prototype, "x", 2); __decorateClass([ Validate12(OR2(STRING2, NUMBER5, DATE, GROUPING_VALUE)) ], PointInternal.prototype, "y", 2); return PointInternal; } function Value(Parent) { class ValueInternal extends Parent { } __decorateClass([ Validate12(OR2(STRING2, NUMBER5, DATE, GROUPING_VALUE)) ], ValueInternal.prototype, "value", 2); return ValueInternal; } function Background(Parent) { class BackgroundInternal extends Parent { constructor() { super(...arguments); this.background = new BackgroundProperties(); } } __decorateClass([ Validate12(OBJECT4, { optional: true }) ], BackgroundInternal.prototype, "background", 2); return BackgroundInternal; } function Handle(Parent) { class HandleInternal extends Parent { constructor() { super(...arguments); this.handle = new HandleProperties(); } } __decorateClass([ Validate12(OBJECT4, { optional: true }) ], HandleInternal.prototype, "handle", 2); return HandleInternal; } function AxisLabel(Parent) { class AxisLabelInternal extends Parent { constructor() { super(...arguments); this.axisLabel = new AxisLabelProperties(); } } __decorateClass([ Validate12(OBJECT4, { optional: true }) ], AxisLabelInternal.prototype, "axisLabel", 2); return AxisLabelInternal; } function Label(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 } __decorateClass([ Validate12(POSITIVE_NUMBER4, { optional: true }) ], LabelInternal.prototype, "padding", 2); __decorateClass([ Validate12(TEXT_ALIGN, { optional: true }) ], LabelInternal.prototype, "textAlign", 2); __decorateClass([ Validate12(FUNCTION, { optional: true }) ], LabelInternal.prototype, "formatter", 2); return LabelInternal; } function Cappable(Parent) { class CappableInternal extends Parent { } return CappableInternal; } function Extendable(Parent) { class ExtendableInternal extends Parent { } __decorateClass([ Validate12(BOOLEAN5, { optional: true }) ], ExtendableInternal.prototype, "extendStart", 2); __decorateClass([ Validate12(BOOLEAN5, { optional: true }) ], ExtendableInternal.prototype, "extendEnd", 2); return ExtendableInternal; } function Lockable(Parent) { class LockableInternal extends Parent { } __decorateClass([ 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 { } __decorateClass([ Validate12(BOOLEAN5, { optional: true }) ], VisibleInternal.prototype, "visible", 2); return VisibleInternal; } function Fill(Parent) { class FillInternal extends Parent { } __decorateClass([ Validate12(COLOR_STRING2, { optional: true }) ], FillInternal.prototype, "fill", 2); __decorateClass([ Validate12(RATIO4, { optional: true }) ], FillInternal.prototype, "fillOpacity", 2); return FillInternal; } function Stroke(Parent) { class StrokeInternal extends Parent { } __decorateClass([ Validate12(COLOR_STRING2, { optional: true }) ], StrokeInternal.prototype, "stroke", 2); __decorateClass([ Validate12(RATIO4, { optional: true }) ], StrokeInternal.prototype, "strokeOpacity", 2); __decorateClass([ 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; } } __decorateClass([ Validate12(LINE_DASH2, { optional: true }) ], LineDashInternal.prototype, "lineDash", 2); __decorateClass([ Validate12(NUMBER5, { optional: true }) ], LineDashInternal.prototype, "lineDashOffset", 2); __decorateClass([ Validate12(LINE_STYLE, { 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"; } } __decorateClass([ Validate12(FONT_STYLE2, { optional: true }) ], FontInternal.prototype, "fontStyle", 2); __decorateClass([ Validate12(FONT_WEIGHT2, { optional: true }) ], FontInternal.prototype, "fontWeight", 2); __decorateClass([ Validate12(POSITIVE_NUMBER4) ], FontInternal.prototype, "fontSize", 2); __decorateClass([ Validate12(STRING2) ], FontInternal.prototype, "fontFamily", 2); __decorateClass([ Validate12(COLOR_STRING2, { optional: true }) ], FontInternal.prototype, "color", 2); return FontInternal; } // packages/ag-charts-enterprise/src/features/annotations/properties/textualStartEndProperties.ts var import_ag_charts_community29 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/values.ts var import_ag_charts_community27 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/scale.ts function getGroupingValue(d) { if (isNumber(d) || isString(d) || isDate(d)) { return { value: d, groupPercentage: 0 }; } return d ?? { value: void 0, groupPercentage: 0 }; } // packages/ag-charts-enterprise/src/features/annotations/utils/values.ts var { clampArray } = import_ag_charts_community27._ModuleSupport; function convertLine(datum, context) { if (datum.start == null || datum.end == null) return; const start = convertPoint(datum.start, context); const end = convertPoint(datum.end, context); if (start == null || end == null) return; return { x1: start.x, y1: start.y, x2: end.x, y2: end.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, snapToGroup } = context; const width = scale.bandwidth === 0 ? scale.step ?? 0 : scale.bandwidth ?? 0; const offset = snapToGroup ? width / 2 : width * groupPercentage; return scale.convert(value) + offset; } 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 } = context; if (context.continuous && scale.step == null) { return context.scaleInvert(n); } const value = context.scaleInvertNearest(n); const width = scale.bandwidth === 0 ? scale.step : scale.bandwidth ?? 0; const bandStart = scale.convert(value); const bandEnd = bandStart + width; const position = clampArray(n, scale.range); const groupPercentage = bandStart === bandEnd ? 0 : (position - bandStart) / (bandEnd - bandStart); return { value, groupPercentage }; } // packages/ag-charts-enterprise/src/features/annotations/properties/startEndProperties.ts var import_ag_charts_community28 = require("ag-charts-community"); var { BaseProperties: BaseProperties4 } = import_ag_charts_community28._ModuleSupport; var StartEndProperties = class extends Annotation(Line2(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; } }; // packages/ag-charts-enterprise/src/features/annotations/properties/textualStartEndProperties.ts var { STRING: STRING3, Validate: Validate13 } = import_ag_charts_community29._ModuleSupport; var TextualStartEndProperties = class extends Localisable(Label(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 text2 = this.text; if (isPlaceholder) { text2 = this.placeholderText ?? ""; if (this.localeManager) text2 = this.localeManager.t(text2); } return { text: text2, isPlaceholder }; } getTextInputCoords(context, _height) { return convertPoint(this.end, context); } getTextPosition() { return this.position; } }; __decorateClass([ Validate13(STRING3) ], TextualStartEndProperties.prototype, "text", 2); // packages/ag-charts-enterprise/src/features/annotations/callout/calloutProperties.ts var { STRING: STRING4, Validate: Validate14, Color } = 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" /* Callout */; this.position = "bottom"; this.alignment = "left"; } static is(value) { return isObject(value) && value.type === "callout" /* 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 } = Color.fromString(this.color ?? "#888888"); return new Color(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, height) { const coords = super.getTextInputCoords(context, height); const padding = this.getPadding(); const paddingLeft = padding.left ?? 0; const paddingBottom = padding.bottom ?? 0; return { x: coords.x + paddingLeft, y: coords.y - paddingBottom }; } }; __decorateClass([ Validate14(STRING4) ], CalloutProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/comment/commentProperties.ts var import_ag_charts_community32 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/properties/textualPointProperties.ts var import_ag_charts_community31 = require("ag-charts-community"); var { STRING: STRING5, BaseProperties: BaseProperties5, Validate: Validate15 } = import_ag_charts_community31._ModuleSupport; var TextualPointProperties = class extends Annotation(Point(Handle(Label(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 text2 = !isPlaceholder ? this.text : this.placeholderText ?? ""; return { text: text2, isPlaceholder }; } getTextInputCoords(context, _height) { return convertPoint(this, context); } getTextPosition() { return this.position; } }; __decorateClass([ Validate15(STRING5) ], TextualPointProperties.prototype, "text", 2); // packages/ag-charts-enterprise/src/features/annotations/comment/commentProperties.ts var { STRING: STRING6, Validate: Validate16, Color: Color2 } = 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" /* Comment */; this.position = "bottom"; this.alignment = "left"; } static is(value) { return isObject(value) && value.type === "comment" /* 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 } = Color2.fromString(this.color ?? "#888888"); return new Color2(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, height) { const coords = super.getTextInputCoords(context, height); const padding = this.getPadding(); return { x: coords.x + padding.left, y: coords.y - padding.bottom }; } }; __decorateClass([ Validate16(STRING6) ], CommentProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerProperties.ts var import_ag_charts_community34 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/line.ts var import_ag_charts_community33 = require("ag-charts-community"); var { Vec2 } = 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] = Vec2.from(coords); const reflection = bounds.height; const gradient = Vec2.gradient(p2, p1, reflection); const intercept = Vec2.intercept(p2, gradient, reflection); const fallback = [ { x: p1.x, y: reflection ?? 0 }, { x: p1.x, y: reflection == null ? bounds.height : reflection - bounds.height } ]; if (gradient === Infinity) { return fallback; } let points = [ Vec2.intersectAtY(gradient, intercept, 0, reflection), Vec2.intersectAtY(gradient, intercept, bounds.height, reflection), Vec2.intersectAtX(gradient, intercept, 0, reflection), Vec2.intersectAtX(gradient, intercept, 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; } // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerProperties.ts 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(); } }; __decorateClass([ Validate17(OBJECT5, { optional: true }) ], MeasurerStatistics.prototype, "divider", 2); var MeasurerDirectionProperties = class extends Fill(Stroke(Handle(BaseProperties6))) { constructor() { super(...arguments); this.statistics = new MeasurerStatistics(); } }; __decorateClass([ Validate17(OBJECT5, { optional: true }) ], MeasurerDirectionProperties.prototype, "statistics", 2); var MeasurerTypeProperties = class extends Localisable(Background(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); } }; __decorateClass([ Validate17(OBJECT5, { optional: true }) ], MeasurerTypeProperties.prototype, "statistics", 2); __decorateClass([ 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" /* DateRange */; this.direction = "horizontal"; } static is(value) { return isObject(value) && value.type === "date-range" /* DateRange */; } }; __decorateClass([ Validate17(STRING7) ], DateRangeProperties.prototype, "type", 2); __decorateClass([ Validate17(BOOLEAN6, { optional: true }) ], DateRangeProperties.prototype, "extendAbove", 2); __decorateClass([ Validate17(BOOLEAN6, { optional: true }) ], DateRangeProperties.prototype, "extendBelow", 2); var PriceRangeProperties = class extends PriceRange(MeasurerTypeProperties) { constructor() { super(...arguments); this.type = "price-range" /* PriceRange */; this.direction = "vertical"; } static is(value) { return isObject(value) && value.type === "price-range" /* PriceRange */; } }; __decorateClass([ Validate17(STRING7) ], PriceRangeProperties.prototype, "type", 2); __decorateClass([ Validate17(BOOLEAN6, { optional: true }) ], PriceRangeProperties.prototype, "extendLeft", 2); __decorateClass([ Validate17(BOOLEAN6, { optional: true }) ], PriceRangeProperties.prototype, "extendRight", 2); var DatePriceRangeProperties = class extends DateRange(PriceRange(MeasurerTypeProperties)) { constructor() { super(...arguments); this.type = "date-price-range" /* DatePriceRange */; this.direction = "both"; } static is(value) { return isObject(value) && value.type === "date-price-range" /* DatePriceRange */; } }; __decorateClass([ Validate17(STRING7) ], DatePriceRangeProperties.prototype, "type", 2); var QuickDatePriceRangeProperties = class extends DateRange(PriceRange(MeasurerTypeProperties)) { constructor() { super(...arguments); this.type = "quick-date-price-range" /* QuickDatePriceRange */; this.up = new MeasurerDirectionProperties(); this.down = new MeasurerDirectionProperties(); this.direction = "both"; } static is(value) { return isObject(value) && value.type === "quick-date-price-range" /* QuickDatePriceRange */; } }; __decorateClass([ Validate17(STRING7) ], QuickDatePriceRangeProperties.prototype, "type", 2); __decorateClass([ Validate17(OBJECT5, { optional: true }) ], QuickDatePriceRangeProperties.prototype, "up", 2); __decorateClass([ Validate17(OBJECT5, { optional: true }) ], QuickDatePriceRangeProperties.prototype, "down", 2); // packages/ag-charts-enterprise/src/features/annotations/note/noteProperties.ts var import_ag_charts_community36 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/text/util.ts var import_ag_charts_community35 = require("ag-charts-community"); var { TextWrapper: TextWrapper2, CachedTextMeasurerPool, BBox: BBox2 } = 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, text2, width) { return width ? TextWrapper2.wrapText(text2, { ...getTextWrapOptions(options), maxWidth: width }) : text2; } function measureAnnotationText(options, text2) { const textOptions = getTextWrapOptions(options); const { lineMetrics, width } = CachedTextMeasurerPool.measureLines(text2, textOptions); const height = lineMetrics.length * (options.fontSize ?? 14) * ANNOTATION_TEXT_LINE_HEIGHT; return { width, height }; } function getBBox(options, text2, coords, bbox) { let width = bbox?.width ?? 0; let height = bbox?.height ?? 0; if (!bbox) { const wrappedText = options.width != null ? wrapText(options, text2, options.width) : text2; ({ width, height } = measureAnnotationText(options, wrappedText)); } return new BBox2(coords.x, coords.y, width, height); } function updateTextNode(node, text2, 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: text2, fill, fontFamily, fontSize, fontStyle, fontWeight, textAlign, lineHeight, textBaseline }); } // packages/ag-charts-enterprise/src/features/annotations/note/noteProperties.ts var { OBJECT: OBJECT6, STRING: STRING8, BaseProperties: BaseProperties7, Validate: Validate18, clamp: clamp2 } = 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" /* Note */; this.background = new NoteBackgroundProperties(); this.position = "bottom"; this.alignment = "center"; this.width = 200; } static is(value) { return isObject(value) && value.type === "note" /* 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, height) { const { width, text: text2 } = this; const textInputCoords = super.getTextInputCoords(context, height); const padding = this.getPadding().top; const bbox = getBBox(this, text2, textInputCoords); bbox.x = clamp2(width / 2, bbox.x, context.seriesRect.width - width / 2); const topY = bbox.y - LABEL_OFFSET - padding * 2; const bottomY = bbox.y + HANDLE_SIZE + padding * 2; const textHeight = Math.max(bbox.height, height); 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 }; } }; __decorateClass([ Validate18(STRING8) ], NoteProperties.prototype, "type", 2); __decorateClass([ Validate18(OBJECT6, { optional: true }) ], NoteProperties.prototype, "background", 2); // packages/ag-charts-enterprise/src/features/annotations/properties/pointProperties.ts var import_ag_charts_community37 = require("ag-charts-community"); 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; } }; // packages/ag-charts-enterprise/src/features/annotations/properties/shapePointProperties.ts 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; } }; // packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineProperties.ts var import_ag_charts_community39 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/validation.ts var import_ag_charts_community38 = require("ag-charts-community"); function validateDatumLine(context, datum, directions, warningPrefix) { let valid = true; valid && (valid = validateDatumPoint(context, datum.start, directions, warningPrefix && `${warningPrefix}[start] `)); valid && (valid = validateDatumPoint(context, datum.end, directions, 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_exports.warnOnce(`${warningPrefix}is outside the axis domain, ignoring. - value: [${value}]]`); } return valid; } function validateDatumPoint(context, point, directions, warningPrefix) { if (point.x == null || point.y == null) { if (warningPrefix) { logger_exports.warnOnce(`${warningPrefix}requires both an [x] and [y] property, ignoring.`); } return false; } const validX = directions?.x === false ? true : validateDatumPointDirection(point.x, context.xAxis); const validY = directions?.y === false ? true : validateDatumPointDirection(point.y, context.yAxis); if (!validX || !validY) { let text2 = "x & y domains"; if (validX) text2 = "y domain"; if (validY) text2 = "x domain"; if (warningPrefix) { const { value: xValue } = getGroupingValue(point.x); const { value: yValue } = getGroupingValue(point.y); logger_exports.warnOnce(`${warningPrefix}is outside the ${text2}, 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; } // packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineProperties.ts var { OBJECT: OBJECT7, STRING: STRING9, BaseProperties: BaseProperties9, Validate: Validate19 } = import_ag_charts_community39._ModuleSupport; var HorizontalLineProperties = class extends Annotation(Value(Handle(AxisLabel(Stroke(LineStyle(BaseProperties9)))))) { constructor() { super(...arguments); this.direction = "horizontal"; this.type = "horizontal-line" /* HorizontalLine */; this.text = new LineTextProperties(); } static is(value) { return isObject(value) && value.type === "horizontal-line" /* HorizontalLine */; } 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); } }; __decorateClass([ Validate19(STRING9) ], HorizontalLineProperties.prototype, "type", 2); __decorateClass([ Validate19(OBJECT7, { optional: true }) ], HorizontalLineProperties.prototype, "text", 2); var VerticalLineProperties = class extends Annotation(Value(Handle(AxisLabel(Stroke(LineStyle(BaseProperties9)))))) { constructor() { super(...arguments); this.direction = "vertical"; this.type = "vertical-line" /* VerticalLine */; this.text = new LineTextProperties(); } static is(value) { return isObject(value) && value.type === "vertical-line" /* VerticalLine */; } 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); } }; __decorateClass([ Validate19(STRING9) ], VerticalLineProperties.prototype, "type", 2); __decorateClass([ Validate19(OBJECT7, { optional: true }) ], VerticalLineProperties.prototype, "text", 2); // packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelProperties.ts var import_ag_charts_community40 = require("ag-charts-community"); var { NUMBER: NUMBER6, OBJECT: OBJECT8, STRING: STRING10, BaseProperties: BaseProperties10, Validate: Validate20 } = import_ag_charts_community40._ModuleSupport; var DisjointChannelProperties = class extends Annotation( Background(Line2(Handle(Extendable(Stroke(LineStyle(BaseProperties10)))))) ) { constructor() { super(...arguments); this.type = "disjoint-channel" /* DisjointChannel */; this.text = new ChannelTextProperties(); this.snapToAngle = 45; } static is(value) { return isObject(value) && value.type === "disjoint-channel" /* DisjointChannel */; } 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_exports.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); } }; __decorateClass([ Validate20(STRING10) ], DisjointChannelProperties.prototype, "type", 2); __decorateClass([ Validate20(NUMBER6) ], DisjointChannelProperties.prototype, "startHeight", 2); __decorateClass([ Validate20(NUMBER6) ], DisjointChannelProperties.prototype, "endHeight", 2); __decorateClass([ Validate20(OBJECT8, { optional: true }) ], DisjointChannelProperties.prototype, "text", 2); // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedProperties.ts var import_ag_charts_community43 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/properties/fibonacciProperties.ts var import_ag_charts_community42 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/line/lineProperties.ts var import_ag_charts_community41 = require("ag-charts-community"); 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); } }; __decorateClass([ Validate21(OBJECT9, { optional: true }) ], LineTypeProperties.prototype, "text", 2); var ArrowProperties = class extends LineTypeProperties { constructor() { super(...arguments); this.type = "arrow" /* Arrow */; this.endCap = "arrow"; } static is(value) { return isObject(value) && value.type === "arrow" /* Arrow */; } }; __decorateClass([ Validate21(STRING11) ], ArrowProperties.prototype, "type", 2); var LineProperties = class extends LineTypeProperties { constructor() { super(...arguments); this.type = "line" /* Line */; } static is(value) { return isObject(value) && value.type === "line" /* Line */; } }; __decorateClass([ Validate21(STRING11) ], LineProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/properties/fibonacciProperties.ts var { OBJECT: OBJECT10, BOOLEAN: BOOLEAN7, COLOR_STRING: COLOR_STRING3, COLOR_STRING_ARRAY, Validate: Validate22, predicateWithMessage: predicateWithMessage2 } = import_ag_charts_community42._ModuleSupport; var fibonacciBands = [10, 6, 4]; var FIBONACCI_BANDS = predicateWithMessage2( (value) => isFiniteNumber(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; } } }; __decorateClass([ Validate22(OBJECT10, { optional: true }) ], FibonacciProperties.prototype, "label", 2); __decorateClass([ Validate22(BOOLEAN7, { optional: true }) ], FibonacciProperties.prototype, "reverse", 2); __decorateClass([ Validate22(BOOLEAN7, { optional: true }) ], FibonacciProperties.prototype, "showFill", 2); __decorateClass([ Validate22(BOOLEAN7, { optional: true }) ], FibonacciProperties.prototype, "isMultiColor", 2); __decorateClass([ Validate22(COLOR_STRING_ARRAY, { optional: true }) ], FibonacciProperties.prototype, "strokes", 2); __decorateClass([ Validate22(COLOR_STRING3, { optional: true }) ], FibonacciProperties.prototype, "rangeStroke", 2); __decorateClass([ Validate22(FIBONACCI_BANDS, { optional: true }) ], FibonacciProperties.prototype, "bands", 2); // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedProperties.ts 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" /* FibonacciRetracementTrendBased */; this.endRetracement = new PointProperties(); } static is(value) { return isObject(value) && value.type === "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */; } }; __decorateClass([ Validate23(STRING12) ], FibonacciRetracementTrendBasedProperties.prototype, "type", 2); __decorateClass([ Validate23(OBJECT11) ], FibonacciRetracementTrendBasedProperties.prototype, "endRetracement", 2); // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementProperties.ts var import_ag_charts_community44 = require("ag-charts-community"); var { STRING: STRING13, Validate: Validate24 } = import_ag_charts_community44._ModuleSupport; var FibonacciRetracementProperties = class extends FibonacciProperties { constructor() { super(...arguments); this.type = "fibonacci-retracement" /* FibonacciRetracement */; } static is(value) { return isObject(value) && value.type === "fibonacci-retracement" /* FibonacciRetracement */; } }; __decorateClass([ Validate24(STRING13) ], FibonacciRetracementProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelProperties.ts var import_ag_charts_community45 = require("ag-charts-community"); var { NUMBER: NUMBER7, STRING: STRING14, OBJECT: OBJECT12, BaseProperties: BaseProperties11, Validate: Validate25 } = import_ag_charts_community45._ModuleSupport; var ParallelChannelProperties = class extends Annotation( Background(Line2(Handle(Extendable(Stroke(LineStyle(BaseProperties11)))))) ) { constructor() { super(...arguments); this.type = "parallel-channel" /* ParallelChannel */; this.middle = new ChannelAnnotationMiddleProperties(); this.text = new ChannelTextProperties(); this.snapToAngle = 45; } static is(value) { return isObject(value) && value.type === "parallel-channel" /* ParallelChannel */; } 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_exports.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); } }; __decorateClass([ Validate25(STRING14) ], ParallelChannelProperties.prototype, "type", 2); __decorateClass([ Validate25(NUMBER7) ], ParallelChannelProperties.prototype, "height", 2); __decorateClass([ Validate25(OBJECT12, { optional: true }) ], ParallelChannelProperties.prototype, "middle", 2); __decorateClass([ Validate25(OBJECT12, { optional: true }) ], ParallelChannelProperties.prototype, "text", 2); // packages/ag-charts-enterprise/src/features/annotations/text/textProperties.ts var import_ag_charts_community46 = require("ag-charts-community"); var { STRING: STRING15, Validate: Validate26 } = import_ag_charts_community46._ModuleSupport; var TextProperties = class extends TextualPointProperties { constructor() { super(...arguments); this.type = "text" /* Text */; this.position = "bottom"; } static is(value) { return isObject(value) && value.type === "text" /* Text */; } }; __decorateClass([ Validate26(STRING15) ], TextProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/utils/types.ts 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); } // packages/ag-charts-enterprise/src/features/annotations/utils/has.ts 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) && isObject(datum.text); } // packages/ag-charts-enterprise/src/features/annotations/utils/styles.ts 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; } } } // packages/ag-charts-enterprise/src/features/annotations/annotationDefaults.ts var { deepClone } = 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" /* Callout */, void 0], ["comment" /* Comment */, void 0], ["text" /* Text */, void 0], ["arrow" /* Arrow */, void 0], ["line" /* Line */, void 0], ["disjoint-channel" /* DisjointChannel */, void 0], ["parallel-channel" /* ParallelChannel */, void 0], ["date-range" /* DateRange */, void 0], ["price-range" /* PriceRange */, void 0], ["date-price-range" /* DatePriceRange */, void 0] ]); this.lineStyles = /* @__PURE__ */ new Map([ ["line" /* Line */, void 0], ["horizontal-line" /* HorizontalLine */, void 0], ["vertical-line" /* VerticalLine */, void 0], ["disjoint-channel" /* DisjointChannel */, void 0], ["parallel-channel" /* ParallelChannel */, void 0], ["arrow" /* Arrow */, void 0], ["date-range" /* DateRange */, void 0], ["price-range" /* PriceRange */, void 0], ["date-price-range" /* DatePriceRange */, void 0] ]); this.lineTextAlignments = /* @__PURE__ */ new Map([ ["line" /* Line */, void 0], ["horizontal-line" /* HorizontalLine */, void 0], ["vertical-line" /* VerticalLine */, void 0], ["disjoint-channel" /* DisjointChannel */, void 0], ["parallel-channel" /* ParallelChannel */, void 0], ["arrow" /* Arrow */, void 0], ["date-range" /* DateRange */, void 0], ["price-range" /* PriceRange */, void 0], ["date-price-range" /* DatePriceRange */, void 0] ]); this.lineTextPositions = /* @__PURE__ */ new Map([ ["line" /* Line */, void 0], ["horizontal-line" /* HorizontalLine */, void 0], ["vertical-line" /* VerticalLine */, void 0], ["disjoint-channel" /* DisjointChannel */, void 0], ["parallel-channel" /* ParallelChannel */, void 0], ["arrow" /* Arrow */, void 0], ["date-range" /* DateRange */, void 0], ["price-range" /* PriceRange */, void 0], ["date-price-range" /* DatePriceRange */, void 0] ]); this.fibonacciOptions = /* @__PURE__ */ new Map([ [ "fibonacci-retracement" /* FibonacciRetracement */, { bands: void 0, reverse: void 0, showFill: void 0 } ], [ "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */, { bands: void 0, reverse: void 0, showFill: void 0 } ] ]); } createMemento() { return { colors: deepClone(this.colors), fontSizes: deepClone(this.fontSizes), lineStyles: deepClone(this.lineStyles), lineTextAlignments: deepClone(this.lineTextAlignments), lineTextPositions: deepClone(this.lineTextPositions), fibonacciOptions: deepClone(this.fibonacciOptions) }; } guardMemento(_blob) { return true; } restoreMemento(_version, _mementoVersion, blob) { this.colors = deepClone(blob.colors); this.fontSizes = deepClone(blob.fontSizes); this.lineStyles = deepClone(blob.lineStyles); this.lineTextAlignments = deepClone(blob.lineTextAlignments); this.lineTextPositions = deepClone(blob.lineTextPositions); this.fibonacciOptions = deepClone(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" /* FibonacciRetracement */ && type != "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */) 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 }); }); } } }; // packages/ag-charts-enterprise/src/features/annotations/annotationOptionsToolbar.ts var import_ag_charts_community50 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/components/color-picker/colorPicker.ts var import_ag_charts_community48 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/components/color-picker/colorPickerTemplate.html var colorPickerTemplate_default = '
'; // packages/ag-charts-enterprise/src/components/color-picker/colorPicker.ts var { Color: Color3, clamp: clamp3, createElement } = 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, initialFocus } = this.createColorPicker(options); const popover = this.showWithChildren([element], { 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 = createElement("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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/annotationsMenuOptions.ts var import_ag_charts_community49 = require("ag-charts-community"); function channelMenuItemVisible(scale) { return !(scale instanceof import_ag_charts_community49._ModuleSupport.LogScale) && !(scale 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" /* ParallelChannel */, visible: channelMenuItemVisible }, { label: "toolbarAnnotationsDisjointChannel", icon: "disjoint-channel-drawing", value: "disjoint-channel" /* DisjointChannel */, 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 } ]; // packages/ag-charts-enterprise/src/features/annotations/annotationOptionsToolbar.ts var { ARRAY: ARRAY2, BOOLEAN: BOOLEAN8, NUMBER: NUMBER8, OBJECT: OBJECT13, STRING: STRING16, UNION: UNION5, Color: Color4, FloatingToolbar, Listeners, Menu, PropertiesArray, ToolbarButtonProperties, ToolbarButtonWidget, Validate: Validate27 } = import_ag_charts_community50._ModuleSupport; var AnnotationOptionsButtonProperties = class extends ToolbarButtonProperties { constructor() { super(...arguments); this.checkedOverrides = new ToolbarButtonProperties(); } }; __decorateClass([ Validate27( UNION5([ "line-stroke-width", "line-style-type", "line-color", "fill-color", "text-color", "text-size", "delete", "settings", "lock" ]) ) ], AnnotationOptionsButtonProperties.prototype, "value", 2); __decorateClass([ Validate27(OBJECT13, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "checkedOverrides", 2); __decorateClass([ Validate27(STRING16, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "color", 2); __decorateClass([ Validate27(NUMBER8, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate27(Boolean, { optional: true }) ], AnnotationOptionsButtonProperties.prototype, "isMultiColor", 2); var AnnotationOptionsButtonWidget = class extends ToolbarButtonWidget { update(options) { super.update(options); if (options.value === "line-stroke-width" /* LineStrokeWidth */) { this.updateLineStrokeWidth(options); } if (options.value === "fill-color" /* FillColor */ || options.value === "line-color" /* LineColor */ || options.value === "text-color" /* TextColor */) { this.updateFillColor(options); } } updateFillColor(options) { const element = this.getElement(); element.classList.add("ag-charts-annotations__color-picker-button"); element.classList.toggle("ag-charts-annotations__color-picker-button--multi-color", options.isMultiColor); element.style.setProperty("--color", options.color ?? null); } updateLineStrokeWidth(options) { const element = this.getElement(); element.classList.add("ag-charts-annotations__stroke-width-button"); element.style.setProperty("--stroke-width", `${options.strokeWidth}px`); } }; var FloatingAnnotationOptionsToolbar = class extends FloatingToolbar { 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 PropertiesArray(AnnotationOptionsButtonProperties); this.destroyFns = []; this.events = new Listeners(); this.visibleButtons = []; this.toolbar = new FloatingAnnotationOptionsToolbar(this.ctx, "annotation-options"); this.colorPicker = new ColorPicker(this.ctx); this.textSizeMenu = new Menu(this.ctx, "text-size"); this.lineStyleTypeMenu = new Menu(this.ctx, "annotations-line-style-type"); this.lineStrokeWidthMenu = new Menu(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" /* LineColor */, datum.getDefaultColor("line-color" /* LineColor */), datum.getDefaultOpacity("line-color" /* LineColor */), "isMultiColor" in datum && datum?.isMultiColor ); this.updateColorPickerColor( "fill-color" /* FillColor */, datum.getDefaultColor("fill-color" /* FillColor */), datum.getDefaultOpacity("fill-color" /* FillColor */), "isMultiColor" in datum && datum?.isMultiColor ); this.updateColorPickerColor( "text-color" /* TextColor */, 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" /* TextSize */, { label: fontSize != null ? String(fontSize) : void 0 }); } updateLineStyleType(item) { this.updateButtonByValue("line-style-type" /* LineStyleType */, { icon: item.icon }); } updateStrokeWidth(item) { this.updateButtonByValue("line-stroke-width" /* LineStrokeWidth */, { 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" /* LineStyleType */: { 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" /* LineStrokeWidth */: { 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" /* LineColor */: case "fill-color" /* FillColor */: case "text-color" /* TextColor */: { 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" /* TextSize */: { 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" /* Delete */: { this.dispatch("pressed-delete"); break; } case "lock" /* Lock */: { datum.locked = !datum.locked; this.refreshButtons(datum); this.dispatch("pressed-lock"); break; } case "settings" /* 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" /* LineStrokeWidth */: this.lineStrokeWidthMenu.setAnchor(anchor, fallbackAnchor); break; case "line-style-type" /* LineStyleType */: this.lineStyleTypeMenu.setAnchor(anchor, fallbackAnchor); break; case "text-size" /* TextSize */: 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" /* 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 }); } }; __decorateClass([ Validate27(BOOLEAN8) ], AnnotationOptionsToolbar.prototype, "enabled", 2); __decorateClass([ Validate27(ARRAY2) ], AnnotationOptionsToolbar.prototype, "buttons", 2); // packages/ag-charts-enterprise/src/features/annotations/states/dragState.ts var import_ag_charts_community51 = require("ag-charts-community"); var { StateMachine, StateMachineProperty, Vec2: Vec22, Debug } = import_ag_charts_community51._ModuleSupport; var DragStateMachine = class extends StateMachine { 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, context }) => { this.hasMoved = false; this.dragStart = offset; this.offset = offset; this.node?.dragStart(this.datum, offset, context); } } }, dragging: { keyDown: actionKeyChange, keyUp: actionKeyChange, drag: ({ offset, context }) => { this.hasMoved = Vec22.lengthSquared(Vec22.sub(offset, this.dragStart)) > 0; this.offset = offset; this.node?.drag(this.datum, offset, context, this.snapping); ctx.update(); }, dragEnd: { target: StateMachine.parent, action: () => { this.node?.stopDragging(); if (this.hasMoved) ctx.recordAction("Move annotation"); ctx.update(); } } } }); this.debug = Debug.create(true, "annotations"); this.hasMoved = false; this.snapping = false; } }; __decorateClass([ StateMachineProperty() ], DragStateMachine.prototype, "snapping", 2); __decorateClass([ StateMachineProperty() ], DragStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty() ], DragStateMachine.prototype, "node", 2); // packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownProperties.ts var import_ag_charts_community52 = require("ag-charts-community"); var { STRING: STRING17, Validate: Validate28 } = import_ag_charts_community52._ModuleSupport; var ArrowDownProperties = class extends ShapePointProperties { constructor() { super(...arguments); this.type = "arrow-down" /* ArrowDown */; } static is(value) { return isObject(value) && value.type === "arrow-down" /* ArrowDown */; } }; __decorateClass([ Validate28(STRING17) ], ArrowDownProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownScene.ts var import_ag_charts_community58 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpScene.ts var import_ag_charts_community57 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/annotationScene.ts var import_ag_charts_community54 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/handle.ts var import_ag_charts_community53 = require("ag-charts-community"); var _Handle = class _Handle 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: handle2, locked } = this; if (locked) { return { point: { x: handle2.x, y: handle2.y }, offset: { x: 0, y: 0 } }; } return { point: target, offset: { x: target.x - handle2.x, y: target.y - handle2.y } }; } toggleActive(active) { this.active = active; if (!active) { this.handle.strokeWidth = _Handle.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 _InvariantHandle 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 = _InvariantHandle.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 _UnivariantHandle 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 = _UnivariantHandle.CORNER_RADIUS; this.handle.width = _UnivariantHandle.HANDLE_SIZE; this.handle.height = _UnivariantHandle.HANDLE_SIZE; this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH; this.handle.zIndex = 2; this.glow.cornerRadius = _UnivariantHandle.CORNER_RADIUS; this.glow.width = _UnivariantHandle.GLOW_SIZE; this.glow.height = _UnivariantHandle.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 offset = (_UnivariantHandle.HANDLE_SIZE - InvariantHandle.HANDLE_SIZE) / 2; this.handle.cornerRadius = 1; this.handle.fill = this.handle.stroke; this.handle.strokeWidth = 0; this.handle.x += offset; this.handle.y += offset; 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 = _UnivariantHandle.CORNER_RADIUS; this.handle.width = _UnivariantHandle.HANDLE_SIZE; this.handle.height = _UnivariantHandle.HANDLE_SIZE; this.glow.width = _UnivariantHandle.GLOW_SIZE; this.glow.height = _UnivariantHandle.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 offset = (_UnivariantHandle.HANDLE_SIZE - InvariantHandle.HANDLE_SIZE) / 2; styles.x -= offset; styles.y -= offset; this.cachedStyles.x -= offset; this.cachedStyles.y -= offset; } 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 _DivariantHandle 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 = _DivariantHandle.HANDLE_SIZE; this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH; this.handle.zIndex = 2; this.glow.size = _DivariantHandle.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 = _DivariantHandle.HANDLE_SIZE; this.glow.size = _DivariantHandle.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; // packages/ag-charts-enterprise/src/features/annotations/scenes/annotationScene.ts var { ZIndexMap: ZIndexMap2 } = import_ag_charts_community54._ModuleSupport; var AnnotationScene = class extends import_ag_charts_community54._ModuleSupport.Group { constructor() { super(...arguments); this.name = "AnnotationScene"; this.zIndex = ZIndexMap2.CHART_ANNOTATION; } static isCheck(value, type) { return isObject(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; } }; // packages/ag-charts-enterprise/src/features/annotations/scenes/pointScene.ts var import_ag_charts_community56 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/coords.ts var import_ag_charts_community55 = require("ag-charts-community"); var { Vec2: Vec23, toRadians: toRadians4 } = import_ag_charts_community55._ModuleSupport; function snapPoint(offset, context, snapping = false, origin, angleStep = 1) { if (!snapping) return invertCoords(offset, context); const center = origin ? convertPoint(origin, context) : Vec23.origin(); return invertCoords(snapToAngle(offset, center, angleStep), context); } function snapToAngle({ x, y }, center, step, direction = 1) { const { x: cx, y: cy } = center; 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 }; } // packages/ag-charts-enterprise/src/features/annotations/scenes/pointScene.ts 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: handle2 } = this; this.activeHandle = void 0; if (handle2.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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/scenes/shapePointScene.ts 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); } }; // packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpScene.ts 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" /* ArrowUp */; 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; } }; // packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownScene.ts 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" /* ArrowDown */; 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; } }; // packages/ag-charts-enterprise/src/features/annotations/states/pointState.ts var import_ag_charts_community59 = require("ag-charts-community"); var { StateMachine: StateMachine2, StateMachineProperty: StateMachineProperty2, Debug: Debug2 } = import_ag_charts_community59._ModuleSupport; var PointStateMachine = class extends StateMachine2 { 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: StateMachine2.parent, reset: StateMachine2.parent }, "waiting-first-render": { render: { target: StateMachine2.parent, action: actionFirstRender } } }); this.debug = Debug2.create(true, "annotations"); } }; __decorateClass([ StateMachineProperty2() ], PointStateMachine.prototype, "node", 2); // packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownState.ts var ArrowDownStateMachine = class extends PointStateMachine { createDatum() { return new ArrowDownProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownConfig.ts var arrowDownConfig = { type: "arrow-down" /* ArrowDown */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpProperties.ts var import_ag_charts_community60 = require("ag-charts-community"); var { STRING: STRING18, Validate: Validate29 } = import_ag_charts_community60._ModuleSupport; var ArrowUpProperties = class extends ShapePointProperties { constructor() { super(...arguments); this.type = "arrow-up" /* ArrowUp */; } static is(value) { return isObject(value) && value.type === "arrow-up" /* ArrowUp */; } }; __decorateClass([ Validate29(STRING18) ], ArrowUpProperties.prototype, "type", 2); // packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpState.ts var ArrowUpStateMachine = class extends PointStateMachine { createDatum() { return new ArrowUpProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpConfig.ts var arrowUpConfig = { type: "arrow-up" /* ArrowUp */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/callout/calloutScene.ts var import_ag_charts_community64 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/textualStartEndScene.ts var import_ag_charts_community63 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/startEndScene.ts var import_ag_charts_community62 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/linearScene.ts var import_ag_charts_community61 = require("ag-charts-community"); var { Vec2: Vec25, Vec4 } = 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, start, end, translation, context) { const { vectors, translateX, translateY } = translate({ start, end }, 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, Vec4.start(coords), Vec4.end(coords), translation, context); return copiedDatum; } }; // packages/ag-charts-enterprise/src/features/annotations/scenes/startEndScene.ts var { Vec4: Vec42 } = 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 [handle2, visible] of Object.entries(show)) { this[handle2].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((handle2) => handle2 !== 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, end } = this; this.activeHandle = void 0; if (start.containsPoint(x, y)) { this.activeHandle = "start"; return true; } if (end.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, handle2, _bbox) { return handle2 === "start" ? Vec42.start(coords) : Vec42.end(coords); } getHandleStyles(datum, _handle) { return { fill: datum.handle.fill, stroke: datum.handle.stroke, strokeOpacity: datum.handle.strokeOpacity, strokeWidth: datum.handle.strokeWidth }; } }; // packages/ag-charts-enterprise/src/features/annotations/scenes/textualStartEndScene.ts 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: text2 } = datum.getText(); return getBBox(datum, text2, Vec43.end(coords), this.textInputBBox); } updateLabel(datum, bbox, coords) { const { text: text2, isPlaceholder } = datum.getText(); updateTextNode(this.label, text2, isPlaceholder, datum, this.getLabelCoords(datum, bbox, coords)); } updateShape(_datum, _textBBox, _coords) { } getLabelCoords(_datum, _bbox, coords) { return Vec43.end(coords); } getHandleStyles(datum, handle2) { return { ...super.getHandleStyles(datum, handle2), stroke: datum.handle.stroke ?? datum.color }; } }; // packages/ag-charts-enterprise/src/features/annotations/callout/calloutScene.ts var { drawCorner, Path: Path5 } = import_ag_charts_community64._ModuleSupport; var CalloutScene = class extends TextualStartEndScene { constructor() { super(); this.type = "callout" /* 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, handle2) { return handle2 === "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, height } = bodyBounds; const top = y - height; const right = x + width; 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": { drawCorner( 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 width = textBBox.width + horizontalPadding; const height = Math.max(textBBox.height + verticalPadding, fontSize + verticalPadding); return { tailPoint: { x: coords.x1, y: coords.y1 }, bodyBounds: { x: textBBox.x, y: textBBox.y, width, height } }; } containsPoint(x, y) { const { start, end, shape } = this; this.activeHandle = void 0; if (start.containsPoint(x, y)) { this.activeHandle = "start"; return true; } const bodyContainsPoint = end.containsPoint(x, y) || shape.containsPoint(x, y); if (bodyContainsPoint) { this.activeHandle = "end"; } return bodyContainsPoint; } }; // packages/ag-charts-enterprise/src/features/annotations/states/textualStartEndState.ts var import_ag_charts_community65 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/states/textualStateUtils.ts function guardCancelAndExit({ key }) { return key === "Escape"; } function guardSaveAndExit({ key, shiftKey }) { return !shiftKey && key === "Enter"; } // packages/ag-charts-enterprise/src/features/annotations/states/textualStartEndState.ts 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"); } }; __decorateClass([ StateMachineProperty3() ], TextualStartEndStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty3() ], TextualStartEndStateMachine.prototype, "node", 2); // packages/ag-charts-enterprise/src/features/annotations/callout/calloutState.ts var CalloutStateMachine = class extends TextualStartEndStateMachine { createDatum() { return new CalloutProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/callout/calloutConfig.ts var calloutConfig = { type: "callout" /* 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) }; // packages/ag-charts-enterprise/src/features/annotations/comment/commentScene.ts var import_ag_charts_community67 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/textualPointScene.ts var import_ag_charts_community66 = require("ag-charts-community"); 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: text2 } = datum.getText(); return getBBox(datum, text2, { x: coords.x, y: coords.y }, this.textInputBBox); } updateLabel(datum, bbox) { const { text: text2, isPlaceholder } = datum.getText(); updateTextNode(this.label, text2, 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; } }; // packages/ag-charts-enterprise/src/features/annotations/comment/commentScene.ts var { drawCorner: drawCorner2 } = import_ag_charts_community67._ModuleSupport; var CommentScene = class extends TextualPointScene { constructor() { super(); this.type = "comment" /* 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, height } = bbox; const { fontSize } = datum; const horizontalPadding = padding.left + padding.right; const verticalPadding = padding.top + padding.bottom; width = width + horizontalPadding; height = Math.max(height + verticalPadding, fontSize + verticalPadding); const top = y - height; const right = x + width; const cornerRadius = (fontSize * ANNOTATION_TEXT_LINE_HEIGHT + verticalPadding) / 2; const { path } = this.shape; path.clear(); path.moveTo(x, y); path.lineTo(x, top + cornerRadius); drawCorner2( path, { x0: x, x1: x + cornerRadius, y0: top + cornerRadius, y1: top, cx: x + cornerRadius, cy: top + cornerRadius }, cornerRadius, false ); path.lineTo(right - cornerRadius, top); drawCorner2( path, { x0: right - cornerRadius, x1: right, y0: top, y1: top + cornerRadius, cx: right - cornerRadius, cy: top + cornerRadius }, cornerRadius, false ); path.lineTo(right, y - cornerRadius); drawCorner2( 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); } }; // packages/ag-charts-enterprise/src/features/annotations/states/textualPointState.ts var import_ag_charts_community68 = require("ag-charts-community"); 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"); } }; __decorateClass([ StateMachineProperty4() ], TextualPointStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty4() ], TextualPointStateMachine.prototype, "node", 2); // packages/ag-charts-enterprise/src/features/annotations/comment/commentState.ts var CommentStateMachine = class extends TextualPointStateMachine { createDatum() { return new CommentProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/comment/commentConfig.ts var commentConfig = { type: "comment" /* 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) }; // packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineScene.ts var import_ag_charts_community73 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/axisLabelScene.ts var import_ag_charts_community69 = require("ag-charts-community"); var { calculateLabelTranslation, 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 text2 = formatter ? formatter({ value }) : context.scaleValueFormatter()(value); this.label.setProperties({ fontWeight, fontSize, fontStyle, fontFamily, textAlign, fill: color, text: text2 }); } updateRect({ styles }) { const { rect } = this; const { cornerRadius, fill, fillOpacity, stroke: stroke2, strokeOpacity } = styles; rect.setProperties({ cornerRadius, fill, fillOpacity, stroke: stroke2, 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 } = calculateLabelTranslation({ 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"; // packages/ag-charts-enterprise/src/features/annotations/scenes/collidableLineScene.ts var import_ag_charts_community70 = require("ag-charts-community"); 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 height = strokeWidth + growCollisionBox; if (height % 2 === 0) height += 1; const topLeft = Vec27.from(x1, y1 - Math.floor(height / 2)); const bottomRight = Vec27.from(x2, y2); const width = Vec27.distance(topLeft, bottomRight); this.collisionBBox = new import_ag_charts_community70._ModuleSupport.BBox(topLeft.x, topLeft.y, width, height); } 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 end = Vec27.sub(v2, v1); const rotated = Vec27.rotate(point, Vec27.angle(point, end), 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(); } }; // packages/ag-charts-enterprise/src/features/annotations/scenes/collidableTextScene.ts var import_ag_charts_community71 = require("ag-charts-community"); 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); } }; // packages/ag-charts-enterprise/src/features/annotations/utils/lineWithText.ts var import_ag_charts_community72 = require("ag-charts-community"); var { Vec2: Vec28 } = import_ag_charts_community72._ModuleSupport; function updateLineText(id, line, coords, textProperties, textNode, text2, lineWidth) { if (!text2 || !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, text2, textProperties, point, numbers.angle, textBaseline); const { x, y, width, height } = textNode.getBBox(); const diameter = Vec28.length(Vec28.from(width, height)); const clipMask = { x: x + width / 2, y: y + height / 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, text2) { if (!text2 || !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, text2, 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 angle = Vec28.angle(normal); const inset = Vec28.multiply(normal, DivariantHandle.HANDLE_SIZE / 2 + (fontSize ?? 14) / 2); const offset = Vec28.multiply(normal, (strokeWidth ?? 2) / 2 + (fontSize ?? 14) / 3); return { left, right, normal, angle, inset, offset }; } function positionAndAlignment({ left, right, normal, angle, inset, offset }, 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(offset, angle + Math.PI / 2, point); textBaseline = "top"; } else if (position === "center" && !offsetInsideTextLabel) { textBaseline = "middle"; } else { point = Vec28.rotate(offset, angle - Math.PI / 2, point); } return { point, textBaseline }; } function setProperties(scene, text2, textProperties, point, angle, textBaseline) { scene.setProperties({ text: text2, x: point.x, y: point.y, rotation: angle, 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 }); } // packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineScene.ts 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: stroke2, strokeWidth, strokeOpacity } = datum; const { x1, y1, x2, y2 } = coords; line.setProperties({ x1, y1, x2, y2, lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke2, strokeWidth, strokeOpacity, fillOpacity: 0 }); } updateHandle(datum, coords) { const { middle } = this; const { locked, stroke: stroke2, strokeWidth, strokeOpacity } = datum; const handleStyles = { fill: datum.handle.fill, stroke: datum.handle.stroke ?? stroke2, 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 axisLabel2 = new AxisLabelScene(); context.attachLabel(axisLabel2); return axisLabel2; } updateAxisLabel(datum, axisContext, coords) { if (!this.axisLabel) { this.axisLabel = this.createAxisLabel(axisContext); } const { axisLabel: axisLabel2, seriesRect } = this; const { direction, position } = axisContext; if (datum.axisLabel.enabled) { axisLabel2.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)) { axisLabel2.visible = false; return; } const { value } = getGroupingValue(datum.value); axisLabel2.update({ ...Vec29.add(labelCorner, Vec29.required(seriesRect)), value, styles: datum.axisLabel, context: axisContext }); } else { axisLabel2.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: text2 } = this; this.activeHandle = void 0; if (middle.containsPoint(x, y)) { this.activeHandle = "middle"; return true; } return line.isPointInPath(x, y) || Boolean(text2?.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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineState.ts var import_ag_charts_community74 = require("ag-charts-community"); 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" /* HorizontalLine */ : "vertical-line" /* VerticalLine */} 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"); } }; __decorateClass([ StateMachineProperty5() ], CrossLineStateMachine.prototype, "node", 2); // packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineConfig.ts var horizontalLineConfig = { type: "horizontal-line" /* HorizontalLine */, 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" /* VerticalLine */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelScene.ts var import_ag_charts_community77 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/channelScene.ts var import_ag_charts_community76 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/withBackgroundScene.ts var import_ag_charts_community75 = require("ag-charts-community"); 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 }); } }; // packages/ag-charts-enterprise/src/features/annotations/scenes/channelScene.ts 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 handle2 of Object.values(this.handles)) { handle2.toggleLocked(locked ?? false); } } snapToAngle(target, context, handle2, originHandle, angle, direction) { const { handles } = this; const fixed = handles[originHandle].handle; const active = handles[handle2].drag(target).point; return invertCoords(snapToAngle(active, fixed, angle, direction), context); } toggleHandles(show) { const { handles } = this; if (typeof show === "boolean") { for (const [handle2, node] of Object.entries(handles)) { node.visible = show; node.toggleHovered(this.activeHandle === handle2); } return; } for (const [handle2, visible] of Object.entries(show)) { const node = handles[handle2]; node.visible = visible ?? true; node.toggleHovered(this.activeHandle === handle2); } } 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: text2 } = this; this.activeHandle = void 0; for (const [handle2, child] of Object.entries(handles)) { if (child.containsPoint(x, y)) { this.activeHandle = handle2; return true; } } return topLine.containsPoint(x, y) || bottomLine.containsPoint(x, y) || Boolean(text2?.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; } }; // packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelScene.ts 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 } = handles[activeHandle].drag(target); handles[activeHandle].toggleDragging(true); const invert2 = (coords) => invertCoords(coords, context); const prev = datum.toJson(); const angle = 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 start = snapping ? this.snapToAngle(target, context, "topLeft", "topRight", angle, direction) : invert2({ x: handles.topLeft.handle.x + offset.x, y: handles.topLeft.handle.y + offset.y * direction }); const bottomStart = snapping ? this.snapToAngle(target, context, "bottomLeft", "bottomRight", angle, -direction) : invert2({ x: handles.bottomLeft.handle.x + offset.x, y: handles.bottomLeft.handle.y + offset.y * -direction }); if (start?.y == null || bottomStart?.y == null || startY == null || !isNumber(startY)) return; const startHeight = datum.startHeight + (start.y - startY) * 2; datum.start.x = start.x; datum.start.y = start.y; datum.startHeight = startHeight; break; } case "topRight": { const end = snapping ? this.snapToAngle(target, context, "topRight", "topLeft", angle) : invert2({ x: handles.topRight.handle.x + offset.x, y: handles.topRight.handle.y + offset.y }); if (end?.y == null || endY == null || !isNumber(endY)) return; const endHeight = datum.endHeight + (end.y - endY) * 2; datum.end.x = end.x; datum.end.y = end.y; datum.endHeight = endHeight; break; } case "bottomRight": { const bottomStart = invert2({ x: handles.bottomLeft.handle.x + offset.x, y: handles.bottomLeft.handle.y + offset.y }); const bottomEnd = invert2({ x: handles.bottomRight.handle.x + offset.x, y: handles.bottomRight.handle.y + offset.y }); if (!bottomStart || !bottomEnd || datum.start.y == null || endY == null || !isNumber(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: stroke2, strokeOpacity, strokeWidth } = datum; const lineStyles = { lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke2, 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; } }; // packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelState.ts var import_ag_charts_community78 = require("ag-charts-community"); 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, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset, 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 || !isNumber(startY) || !isNumber(endY) || !isNumber(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 || !isNumber(startY) || !isNumber(endY) || !isNumber(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" /* DisjointChannel */} 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; } }; __decorateClass([ StateMachineProperty6() ], DisjointChannelStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty6() ], DisjointChannelStateMachine.prototype, "node", 2); __decorateClass([ StateMachineProperty6() ], DisjointChannelStateMachine.prototype, "snapping", 2); // packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelConfig.ts var disjointChannelConfig = { type: "disjoint-channel" /* DisjointChannel */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedScene.ts var import_ag_charts_community80 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/fibonacciScene.ts var import_ag_charts_community79 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/fibonacci.ts 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((ratio, index) => { const endY = yZero + verticalDistance * (ratio / 100) * direction; const yDatumVal = context.yAxis.scaleInvert(endY); data.push({ id: index, x1, x2, y1: startY, y2: endY, tag: ratio == 100 ? 0 /* OneLine */ : 1 /* HorizontalLine */, label: { x1: Math.min(x1, x2) - FIBONACCI_RANGE_LABEL_PADDING, x2, y1: endY, y2: endY, text: `${(ratio / 100).toFixed(3)} (${yDatumVal.toFixed(2)})` } }); startY = endY; }); return data; } // packages/ag-charts-enterprise/src/features/annotations/scenes/fibonacciScene.ts 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 } = context.xAxis.bounds; if (datum.extendEnd) { linePoints[x1 > x2 ? "x1" : "x2"] = x + width; } if (datum.extendStart) { linePoints[x1 > x2 ? "x2" : "x1"] = x; } return linePoints; } updateLine(datum, coords, line) { if (!coords || !line) { return; } const { lineDashOffset, strokeWidth, strokeOpacity, stroke: stroke2 } = datum; line.setProperties({ ...coords, lineCap: datum.getLineCap(), lineDash: [3, 4], lineDashOffset, strokeWidth, strokeOpacity, fillOpacity: 0, stroke: stroke2 }); } 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((range2, { x1, x2, y1, y2 }, index) => { const color = isMultiColor ? colors[index % colors.length] : rangeStroke; if (!showFill) { range2.visible = false; return; } range2.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: text2, ...coords } = datum.label; if (withinBounds) { textNode.setProperties({ ...labelProperties, text: text2, x: coords.x1, y: coords.y1, textBaseline: "middle", textAlign: "end", fill: textColor }); updateLineText(textNode.id, line, coords); } else { const textProperties = { ...labelProperties, label: text2, position: "center", alignment: "left", color: textColor }; updateLineText(textNode.id, line, coords, textProperties, textNode, text2, strokeWidth); } }); } checkWithinBounds(xAxis, fontOptions, textNode) { if (!textNode) { return false; } const { text: text2, ...coords } = textNode.datum.label; textNode.setProperties({ ...fontOptions, text: text2, 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: text2 } = this; let isInStrokePath = false; rangeStrokesGroupSelection.each((line) => isInStrokePath || (isInStrokePath = line.isPointInPath(x, y))); return isInStrokePath || trendLine.isPointInPath(x, y) || Boolean(text2?.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"; } }; // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedScene.ts 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, end, endRetracement, endRetracementLine } = this; this.activeHandle = void 0; if (start.containsPoint(x, y)) { this.activeHandle = "start"; return true; } if (end.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, end, endRetracement, translation, context }) { const { vectors, translateX, translateY } = translate( { start, end, 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 [handle2, visible] of Object.entries(show)) { this[handle2].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, handle2, _bbox) { return handle2 === "start" ? Vec48.start(coords) : Vec48.end(coords); } }; // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedState.ts var import_ag_charts_community81 = require("ag-charts-community"); 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, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset, 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, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ endRetracement: snapPoint(offset, 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(); } }; __decorateClass([ StateMachineProperty7() ], FibonacciRetracementTrendBasedStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty7() ], FibonacciRetracementTrendBasedStateMachine.prototype, "node", 2); __decorateClass([ StateMachineProperty7() ], FibonacciRetracementTrendBasedStateMachine.prototype, "snapping", 2); // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedConfig.ts var fibonacciRetracementTrendBasedConfig = { type: "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementScene.ts var import_ag_charts_community82 = require("ag-charts-community"); 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, end } = this; this.activeHandle = void 0; if (start.containsPoint(x, y)) { this.activeHandle = "start"; return true; } if (end.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((handle2) => handle2 !== 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, end, translation, context }) { const { vectors, translateX, translateY } = translate( { start, end }, 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 [handle2, visible] of Object.entries(show)) { this[handle2].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, handle2, _bbox) { return handle2 === "start" ? Vec49.start(coords) : Vec49.end(coords); } }; // packages/ag-charts-enterprise/src/features/annotations/line/lineState.ts var import_ag_charts_community83 = require("ag-charts-community"); 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, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset, 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; } }; __decorateClass([ StateMachineProperty8() ], LineTypeStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty8() ], LineTypeStateMachine.prototype, "node", 2); __decorateClass([ StateMachineProperty8() ], LineTypeStateMachine.prototype, "snapping", 2); var ArrowStateMachine = class extends LineTypeStateMachine { createDatum() { return new ArrowProperties(); } }; var LineStateMachine = class extends LineTypeStateMachine { createDatum() { return new LineProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementState.ts var FibonacciRetracementStateMachine = class extends LineTypeStateMachine { createDatum() { return new FibonacciRetracementProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementConfig.ts var fibonacciRetracementConfig = { type: "fibonacci-retracement" /* FibonacciRetracement */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/line/lineScene.ts var import_ag_charts_community85 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/scenes/capScene.ts var import_ag_charts_community84 = require("ag-charts-community"); 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, ...rest } = options; const origin = 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), angle + offsetAngle, origin); const rightEnd = Vec214.rotate(Vec214.from(armLength, 0), angle - offsetAngle, origin); path.setProperties(rest); path.fillOpacity = 0; path.path.clear(); path.path.moveTo(leftEnd.x, leftEnd.y); path.path.lineTo(origin.x, origin.y); path.path.lineTo(rightEnd.x, rightEnd.y); } }; // packages/ag-charts-enterprise/src/features/annotations/line/lineScene.ts 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: stroke2, strokeWidth, strokeOpacity } = datum; const linePoints = this.extendLine(coords, datum, context); line.setProperties({ ...linePoints, lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke2, 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: stroke2, strokeWidth, strokeOpacity } = datum; const [start, end] = Vec215.from(coords); const angle = Vec215.angle(Vec215.sub(end, start)); 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: start.x, y: start.y, angle: angle - Math.PI, stroke: stroke2, 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: end.x, y: end.y, angle, stroke: stroke2, 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: text2 } = this; return super.containsPoint(x, y) || line.isPointInPath(x, y) || Boolean(text2?.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, handle2, _bbox) { const { startCap, endCap } = this; let [startPoint, endPoint] = Vec215.from(coords); const angle = Vec215.angle(Vec215.sub(endPoint, startPoint)); if (startCap) { startPoint = Vec215.rotate(Vec215.from(0, -DivariantHandle.HANDLE_SIZE / 2), angle, startPoint); } if (endCap) { endPoint = Vec215.rotate(Vec215.from(0, DivariantHandle.HANDLE_SIZE / 2), angle, endPoint); } return handle2 === "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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/line/lineConfig.ts var lineConfig = { type: "line" /* 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" /* 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) }; // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerScene.ts var import_ag_charts_community88 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerStatisticsScene.ts var import_ag_charts_community87 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/annotations/utils/layout.ts var import_ag_charts_community86 = require("ag-charts-community"); 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; } } // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerStatisticsScene.ts 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, height } = context.seriesRect; const background = Vec411.from(this.background.getBBox()); let offsetX = 0; if (background.x1 < 0) offsetX = -background.x1; if (background.x2 > width) offsetX = width - background.x2; const offsetY = Math.min(padding, height - 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(time) { const range2 = []; const sign = time >= 0 ? "" : "-"; time = Math.abs(time); const MINUTE = 1e3 * 60; const HOUR = MINUTE * 60; const DAY2 = HOUR * 24; const minutes = Math.floor(time / MINUTE); const hours = Math.floor(time / HOUR); const days = Math.floor(time / DAY2); const remainderHours = hours % (DAY2 / HOUR); const remainderMinutes = minutes % (HOUR / MINUTE); if (days >= 1) range2.push(`${days}d`); if (hours >= 1 && (time < DAY2 || remainderHours !== 0)) range2.push(`${remainderHours}h`); if (time < HOUR || remainderMinutes !== 0) range2.push(`${remainderMinutes}m`); range2[0] = `${sign}${range2[0]}`; return range2.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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerScene.ts 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(); // These four bounding lines are named after the way they are drawn, e.g. the horizontalStartLine is a horizontal // line that is only shown when the measurer has the 'vertical' direction. 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 [start, end] = Vec216.from(context.yAxis.bounds); if (DateRangeProperties.is(datum)) { if (datum.extendAbove) extended.y1 = start.y; if (datum.extendBelow) extended.y2 = end.y; } else if (PriceRangeProperties.is(datum)) { if (datum.extendLeft) extended.x1 = start.x; if (datum.extendRight) extended.x2 = end.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 center = Vec216.round(Vec412.center(coords)); const lineStyles = this.getLineStyles(datum); if (direction !== "vertical") { horizontalLine.setProperties({ ...lineStyles, x1, x2, y1: center.y, y2: center.y }); } if (direction !== "horizontal") { verticalLine.setProperties({ ...lineStyles, x1: center.x, x2: center.x, y1, y2 }); } } updateText(datum, coords) { const { direction } = datum; const center = Vec216.round(Vec412.center(coords)); let line; const textCoords = { ...coords }; if (direction === "vertical") { line = this.verticalLine; textCoords.x1 = center.x; textCoords.x2 = center.x; } else { line = this.horizontalLine; textCoords.y1 = center.y; textCoords.y2 = center.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 } = clip.numbers; const crossesVerticalLine = textBBox.x1 <= center.x + offset.x && textBBox.x2 >= center.x - offset.x; if (crossesVerticalLine) { verticalClipMask = { x: center.x, y: clip.clipMask.y, radius: this.text.getBBox().height / 2 + Vec216.length(offset) }; } } this.verticalLine.setClipMask(id, verticalClipMask); } updateCaps(datum, coords) { const { horizontalEndCap, verticalEndCap } = this; const { direction } = datum; const { x1, y1, x2, y2 } = coords; const center = Vec216.round(Vec412.center(coords)); const { stroke: stroke2, strokeWidth, strokeOpacity } = this.getLineStyles(datum); const capStyles = { stroke: stroke2, strokeWidth, strokeOpacity }; if (direction !== "vertical") { const angle = x1 <= x2 ? 0 : Math.PI; let x = x2; if (direction === "horizontal") { x += x1 <= x2 ? -2 : 2; } horizontalEndCap.update({ ...capStyles, x, y: center.y, angle }); } if (direction !== "horizontal") { const angle = y1 <= y2 ? Math.PI / 2 : Math.PI / -2; let y = y2; if (direction === "vertical") { y += y1 <= y2 ? -2 : 2; } verticalEndCap.update({ ...capStyles, x: center.x, y, angle }); } } 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: stroke2, strokeWidth, strokeOpacity } = datum; return { lineCap: datum.getLineCap(), lineDash: datum.getLineDash(), lineDashOffset, stroke: stroke2, 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: text2, 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(text2?.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: start } = getGroupingValue(datum.start.x); const { value: end } = getGroupingValue(datum.end.x); if (!isDate(start) || !isDate(end)) { throw new Error("Can not create a date range measurement of non-date x-axis."); } return end.getTime() - start.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 (!isNumber(endY) || !isNumber(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 (!isNumber(endY) || !isNumber(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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerState.ts var import_ag_charts_community89 = require("ag-charts-community"); 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"); } }; __decorateClass([ StateMachineProperty9() ], MeasurerTypeStateMachine.prototype, "datum", 2); __decorateClass([ 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(); } }; // packages/ag-charts-enterprise/src/features/annotations/measurer/measurerConfig.ts var dateRangeConfig = { type: "date-range" /* DateRange */, 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" /* PriceRange */, 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" /* DatePriceRange */, 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" /* QuickDatePriceRange */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/note/noteScene.ts var import_ag_charts_community90 = require("ag-charts-community"); var { ZIndexMap: ZIndexMap3, TextWrapper: TextWrapper3, clamp: clamp4 } = import_ag_charts_community90._ModuleSupport; var NoteScene = class extends TextualPointScene { constructor() { super(); this.type = "note" /* 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); } }; // packages/ag-charts-enterprise/src/features/annotations/note/noteState.ts var NoteStateMachine = class extends TextualPointStateMachine { createDatum() { return new NoteProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/note/noteConfig.ts var noteConfig = { type: "note" /* 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) }; // packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelScene.ts var import_ag_charts_community91 = require("ag-charts-community"); 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 } = 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"]; offset.y -= UnivariantHandle.HANDLE_SIZE / 2; break; case "topRight": case "bottomRight": moves = ["topRight", "bottomRight"]; origins = ["topLeft", "bottomLeft"]; break; case "bottomMiddle": moves = ["bottomLeft", "bottomRight"]; offset.y -= UnivariantHandle.HANDLE_SIZE / 2; break; } const angle = datum.snapToAngle; const invertedMoves = moves.map( (handle2, index) => snapping && origins[index] ? this.snapToAngle(target, context, handle2, origins[index], angle) : invertCoords(Vec217.add(handles[handle2].handle, offset), 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 && isNumber(startY)) { const topLeft = invertCoords(Vec217.add(handles.topLeft.handle, offset), 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: stroke2, strokeOpacity, strokeWidth } = datum; const lineDash = datum.getLineDash(); const lineStyles = { lineCap: datum.getLineCap(), lineDash, lineDashOffset, stroke: stroke2, 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 ?? stroke2, 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; } }; // packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelState.ts var import_ag_charts_community92 = require("ag-charts-community"); 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, context }) => { const { datum, snapping } = this; if (!datum) return; datum.set({ end: snapPoint(offset, 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 || !isNumber(startY) || !isNumber(endY) || !isNumber(pointY)) return; const height = endY - (pointY ?? 0); const bottomStartY = startY - height; 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 }); 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 || !isNumber(startY) || !isNumber(endY) || !isNumber(pointY)) return; const height = endY - (pointY ?? 0); const bottomStartY = startY - height; 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 }); ctx.recordAction(`Create ${"parallel-channel" /* ParallelChannel */} 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; } }; __decorateClass([ StateMachineProperty10() ], ParallelChannelStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty10() ], ParallelChannelStateMachine.prototype, "node", 2); __decorateClass([ StateMachineProperty10() ], ParallelChannelStateMachine.prototype, "snapping", 2); // packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelConfig.ts var parallelChannelConfig = { type: "parallel-channel" /* ParallelChannel */, 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) }; // packages/ag-charts-enterprise/src/features/annotations/text/textScene.ts var TextScene = class extends TextualPointScene { constructor() { super(); this.type = "text" /* 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 }; } }; // packages/ag-charts-enterprise/src/features/annotations/text/textState.ts var TextStateMachine = class extends TextualPointStateMachine { createDatum() { return new TextProperties(); } }; // packages/ag-charts-enterprise/src/features/annotations/text/textConfig.ts var textConfig = { type: "text" /* 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) }; // packages/ag-charts-enterprise/src/features/annotations/annotationsConfig.ts 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; } } } // packages/ag-charts-enterprise/src/features/annotations/annotationsStateMachine.ts var import_ag_charts_community93 = require("ag-charts-community"); var { ActionOnSet, ParallelStateMachine, StateMachine: StateMachine11, StateMachineProperty: StateMachineProperty11, Debug: Debug11 } = import_ag_charts_community93._ModuleSupport; var AnnotationsStateMachine = class extends ParallelStateMachine { 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; } }; __decorateClass([ StateMachineProperty11() ], AnnotationsStateMachine.prototype, "snapping", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsStateMachine.prototype, "node", 2); var SnappingStateMachine = class extends StateMachine11 { constructor(setSnapping) { super("idle" /* 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" /* 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" /* Idle */]: { onEnter: () => { ctx.select(this.active, this.active); if (this.hoverCoords) { this.hovered = ctx.hoverAtCoords(this.hoverCoords, this.active, this.hovered); } }, hover: ({ offset }) => { this.hovered = ctx.hoverAtCoords(offset, this.active, this.hovered); this.hoverCoords = offset; }, 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 }) => { const nodeAtCoords = ctx.getNodeAtCoords(offset, this.active) === "text" ? "text" : "line"; ctx.showAnnotationSettings(this.active, void 0, nodeAtCoords); } }, dragStart: [ { guard: guardHovered, target: "dragging" /* 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" /* Idle */, action: actionSaveText }, click: { target: "idle" /* Idle */, action: actionSaveText }, drag: { target: "idle" /* Idle */, action: actionSaveText }, textInput: [ { guard: guardCancelAndExit, target: "idle" /* Idle */, action: actionCancel }, { guard: guardSaveAndExit, target: "idle" /* Idle */, action: actionSaveText } ], color: { guard: guardActive, action: actionColor }, fontSize: { guard: guardActive, action: actionFontSize }, cancel: { target: "idle" /* 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; } }; __decorateClass([ ActionOnSet({ changeValue(newValue) { this.setActive(newValue); } }), StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "active", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "hovered", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "hoverCoords", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "copied", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "snapping", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "datum", 2); __decorateClass([ StateMachineProperty11() ], AnnotationsMainStateMachine.prototype, "node", 2); // packages/ag-charts-enterprise/src/features/annotations/annotationsToolbar.ts var import_ag_charts_community94 = require("ag-charts-community"); var { ARRAY: ARRAY3, BOOLEAN: BOOLEAN9, UNION: UNION6, POSITIVE_NUMBER: POSITIVE_NUMBER5, ActionOnSet: ActionOnSet2, LayoutElement, Menu: Menu2, PropertiesArray: PropertiesArray2, ToolbarButtonProperties: ToolbarButtonProperties2, Validate: Validate30, ChartAxisDirection: ChartAxisDirection9 } = import_ag_charts_community94._ModuleSupport; var AnnotationsToolbarButtonProperties = class extends ToolbarButtonProperties2 { }; __decorateClass([ 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 PropertiesArray2(AnnotationsToolbarButtonProperties); this.events = new import_ag_charts_community94._ModuleSupport.Listeners(); this.annotationMenu = new Menu2(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(LayoutElement.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() }); } }; __decorateClass([ Validate30(BOOLEAN9), ActionOnSet2({ changeValue(enabled) { this.toolbar?.setHidden(!enabled); } }) ], AnnotationsToolbar.prototype, "enabled", 2); __decorateClass([ Validate30(POSITIVE_NUMBER5) ], AnnotationsToolbar.prototype, "padding", 2); __decorateClass([ Validate30(ARRAY3) ], AnnotationsToolbar.prototype, "buttons", 2); // packages/ag-charts-enterprise/src/features/annotations/axisButton.ts var import_ag_charts_community95 = require("ag-charts-community"); var { BaseModuleInstance, InteractionState, Validate: Validate31, BOOLEAN: BOOLEAN10, ChartAxisDirection: ChartAxisDirection10, getIconClassNames } = import_ag_charts_community95._ModuleSupport; var DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS = `ag-charts-annotations__axis-button`; var AxisButton = class extends BaseModuleInstance { 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(InteractionState.Clickable)) this.show(e); } onMouseDrag(e) { if (this.ctx.interactionManager.isState(InteractionState.AnnotationsMoveable)) this.show(e); } onMouseLeave() { if (this.ctx.interactionManager.isState(InteractionState.Clickable)) this.hide(); } onClick(e) { if (this.ctx.interactionManager.isState(InteractionState.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(InteractionState.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 offset = buttonHeight - Math.max(0, padding - crosshairLabelPadding); x = x - buttonWidth / 2; y = position === "top" ? minY - buttonHeight + offset : maxY - offset; } else { const crosshairLabelPadding = 9; const offset = buttonWidth - Math.max(0, padding - crosshairLabelPadding); x = position === "left" ? minX - buttonWidth + offset : maxX - offset; 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( `` ); } }; __decorateClass([ Validate31(BOOLEAN10) ], AxisButton.prototype, "enabled", 2); // packages/ag-charts-enterprise/src/features/annotations/settings-dialog/settingsDialog.ts var import_ag_charts_community97 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/components/dialog/dialog.ts var import_ag_charts_community96 = require("ag-charts-community"); var { Color: Color5, DraggablePopover, NativeWidget, Vec2: Vec218, createButton, createCheckbox, createElementId, createSelect, createTextArea, initRovingTabIndex, getIconClassNames: getIconClassNames2, mapValues, setAttribute, setAttributes, createElement: createElement2, getWindow } = import_ag_charts_community96._ModuleSupport; var _Dialog = class _Dialog extends DraggablePopover { 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)); getWindow().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 element = createElement2("div", "ag-charts-dialog__tabs"); const tabButtonIds = mapValues(tabs, () => createElementId("ag-charts-dialog__tab")); const tabPanelIds = mapValues(tabs, () => createElementId("ag-charts-dialog__tab-panel")); for (const [key, tab] of Object.entries(tabs)) { setAttributes(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); setAttribute(tabButtons[key], "aria-selected", key === active); if (key === active) tab.onShow?.(); } }; const header = new NativeWidget(createElement2("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 DragHandleWidget(); this.setDragHandle(dragHandle); const tabButtons = mapValues( tabs, (tab, key) => createButton( { 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 = createElement2("div", "ag-charts-dialog__tab-list"); setAttributes(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); element.append(header.getElement(), ...Object.values(tabs).map((t) => t.panel)); onPressTab(initial); initRovingTabIndex({ orientation: "horizontal", buttons: Object.values(tabButtons) }); return { tabs: element, initialFocus: tabButtons[initial] }; } createTabPanel() { return createElement2("div", "ag-charts-dialog__tab-panel"); } /********** * Inputs * **********/ createInputGroupLine() { return createElement2("div", "ag-charts-dialog__input-group-line"); } createRadioGroup({ label, options, value, onChange }) { const group = this.createInputGroup(label); setAttributes(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 = createButton( { 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); } initRovingTabIndex({ 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 = createSelect( { 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 createTextArea({ value, onChange }, { placeholder: placeholderT }); } createCheckbox({ label, checked, onChange }) { const id = `ag-charts__${label}`; const group = this.createInputGroup(label, { for: id }); const checkbox = createCheckbox( { 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 = createButton( { 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 createButton( { icon: "close", altText: this.ctx.localeManager.t("iconAltTextClose"), onPress: () => this.hide() }, { class: "ag-charts-dialog__close-button" } ); } createInputGroup(label, options) { const group = createElement2("div", "ag-charts-dialog__input-group"); const labelEl = createElement2("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 bottomCenter = Vec218.sub( Vec218.add(outerOffset, Vec218.multiply(outerSize, halfWidth)), Vec218.multiply(popoverSize, halfWidth) ); position = Vec218.sub(bottomCenter, Vec218.from(0, _Dialog.offset)); } else { const bottomRight = Vec218.sub(Vec218.add(outerOffset, outerSize), popoverSize); position = Vec218.sub(bottomRight, _Dialog.offset); } this.updatePosition(position); } getColorPickerAnchors(element) { if (element) this.colorPickerAnchorElement = element; 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 DragHandleWidget = class extends NativeWidget { constructor() { super(createElement2("div", "ag-charts-dialog__drag-handle")); const icon = new NativeWidget(createElement2("span", getIconClassNames2("drag-handle"))); icon.setAriaHidden(true); this.addChild(icon); } }; // packages/ag-charts-enterprise/src/features/annotations/settings-dialog/settingsDialog.ts var { Listeners: Listeners2, focusCursorAtEnd: focusCursorAtEnd2 } = import_ag_charts_community97._ModuleSupport; var AnnotationSettingsDialog = class extends Dialog { constructor(ctx) { super(ctx, "settings"); this.events = new Listeners2(); 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" /* DateRange */) { lineLabel = "dialogHeaderDateRange"; } else if (datum.type === "price-range" /* PriceRange */) { lineLabel = "dialogHeaderPriceRange"; } else if (datum.type === "date-price-range" /* DatePriceRange */) { 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: () => focusCursorAtEnd2(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 }); } }; // packages/ag-charts-enterprise/src/features/annotations/utils/axis.ts function calculateAxisLabelPadding(axisLayout) { return axisLayout.gridPadding + axisLayout.seriesAreaPadding + axisLayout.tickSize + axisLayout.label.spacing; } // packages/ag-charts-enterprise/src/features/annotations/utils/update.ts function updateAnnotation(node, datum, context) { for (const { update } of Object.values(annotationConfigs)) { update(node, datum, context); } } // packages/ag-charts-enterprise/src/features/annotations/annotations.ts var { BOOLEAN: BOOLEAN11, OBJECT: OBJECT14, ChartUpdateType, InteractionState: InteractionState2, ObserveChanges: ObserveChanges2, PropertiesArray: PropertiesArray3, Validate: Validate32, ChartAxisDirection: ChartAxisDirection11, Vec2: Vec219, keyProperty, valueProperty, Selection: Selection2, BBox: BBox3 } = import_ag_charts_community98._ModuleSupport; var _Annotations = class _Annotations 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; // Hidden options for use with measurer statistics this.data = void 0; this.xKey = void 0; this.volumeKey = void 0; this.annotationData = new PropertiesArray3( _Annotations.createAnnotationDatum ); this.defaults = new AnnotationDefaults(); this.container = new import_ag_charts_community98._ModuleSupport.Group({ name: "static-annotations" }); this.annotations = new Selection2( 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(InteractionState2.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(InteractionState2.AnnotationsSelected); selectedNode.toggleActive(true); optionsToolbar2.updateButtons(this.annotationData.at(index)); this.postUpdateFns.push(() => { optionsToolbar2.show(); optionsToolbar2.setAnchorScene(selectedNode); }); } else { this.popAnnotationState(InteractionState2.AnnotationsSelected); this.popAnnotationState(InteractionState2.Annotations); } this.deleteEphemeralAnnotations(); this.update(); }, selectLast: () => { this.pushAnnotationState(InteractionState2.AnnotationsSelected); return this.annotationData.length - 1; }, startInteracting: () => { this.pushAnnotationState(InteractionState2.Annotations); }, stopInteracting: () => { this.popAnnotationState(InteractionState2.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 = (height) => Vec219.add(datum.getTextInputCoords(context, height), 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(InteractionState2.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 = [ keyProperty(this.xKey, void 0, { id: "date" }), valueProperty(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 from = getGroupingValue(fromPoint).value; let to = getGroupingValue(toPoint).value; if (!isValidDate(from) || !isValidDate(to) || !dataModel || !processedData || this.volumeKey == null) return; if (from > to) { [from, to] = [to, from]; } const dateValues = dataModel.resolveKeysById({ id: "annotations" }, "date", processedData); const volumeValues = dataModel.resolveColumnById({ id: "annotations" }, "volume", processedData); let sum = 0; for (let datumIndex = 0; datumIndex < processedData.input.count; datumIndex++) { const key = dateValues[datumIndex]; if (isValidDate(key) && key >= from && key <= to) { sum += volumeValues[datumIndex]; } } return sum; } 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, to, phase }) { const { annotations } = this; this.ctx.animationManager?.animate({ from, 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 offset = Vec219.from(event); const point = invertCoords(offset, context); state.transition("hover", { offset, 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 offset = Vec219.from(event); state.transition("dblclick", { offset }); } onAxisButtonClick(coords, direction) { this.cancel(); this.reset(); const context = this.getAnnotationContext(); if (!this.annotationData || !context) return; const { state } = this; this.pushAnnotationState(InteractionState2.Annotations); const isHorizontal = direction === "horizontal"; state.transition(isHorizontal ? "horizontal-line" /* HorizontalLine */ : "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(InteractionState2.AnnotationsSelected)) { event.sourceEvent.preventDefault(); } } onDragStart(event) { if (!this.ctx.interactionManager.isState(InteractionState2.AnnotationsDraggable)) return; const context = this.getAnnotationContext(); if (!context) return; const offset = Vec219.from(event); const point = invertCoords(offset, context); const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); this.state.transition("dragStart", { context, offset, point, textInputValue, bbox }); } onDrag(event) { if (!this.ctx.interactionManager.isState(InteractionState2.AnnotationsDraggable)) return; const context = this.getAnnotationContext(); if (!context) return; const offset = Vec219.from(event); const point = invertCoords(offset, context); const shiftKey = event.sourceEvent.shiftKey; const textInputValue = this.textInput.getValue(); const bbox = this.textInput.getBBox(); this.state.transition("drag", { context, offset, 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(InteractionState2.Annotations) || this.ctx.interactionManager.isState(InteractionState2.AnnotationsSelected); } update(status = ChartUpdateType.PRE_SCENE_RENDER) { this.ctx.updateService.update(status); } }; __decorateClass([ ObserveChanges2((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); __decorateClass([ Validate32(OBJECT14) ], _Annotations.prototype, "toolbar", 2); __decorateClass([ Validate32(OBJECT14) ], _Annotations.prototype, "optionsToolbar", 2); __decorateClass([ Validate32(OBJECT14) ], _Annotations.prototype, "axesButtons", 2); __decorateClass([ Validate32(BOOLEAN11) ], _Annotations.prototype, "snap", 2); var Annotations = _Annotations; // packages/ag-charts-enterprise/src/features/annotations/annotationsTheme.ts var import_ag_charts_community99 = require("ag-charts-community"); var { FONT_SIZE_RATIO, ThemeSymbols } = import_ag_charts_community99._ModuleSupport; var stroke = { stroke: { $ref: "foregroundColor" }, strokeOpacity: 1, strokeWidth: 2 }; var handle = { fill: ThemeSymbols.DEFAULT_ANNOTATION_HANDLE_FILL, strokeOpacity: 1, strokeWidth: 2 }; var font = { color: { $ref: "backgroundColor" }, fontSize: { $rem: [FONT_SIZE_RATIO.LARGE] }, fontFamily: { $ref: "fontFamily" } }; var axisLabel = { ...font, enabled: true, fill: { $ref: "foregroundColor" }, fontSize: { $ref: "fontSize" } }; var text = { ...font, textAlign: "left" }; var lineText = { ...font, position: "top", alignment: "center", color: { $ref: "textColor" } }; var channelText = { ...font, position: "top", alignment: "center", color: { $ref: "textColor" } }; var measurerStatistics = { ...font, 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 measurer = { ...stroke, background: { fill: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, handle: { ...handle }, text: { ...lineText }, statistics: { ...measurerStatistics } }; 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 annotationsTheme = { enabled: false, // 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: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, handle: { ...handle }, text: { ...channelText } }, "parallel-channel": { ...stroke, middle: { lineDash: [6, 5], strokeWidth: 1 }, background: { fill: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, handle: { ...handle }, text: { ...channelText } }, // Fibonnaccis "fibonacci-retracement": { ...stroke, strokes: ThemeSymbols.DEFAULT_FIBONACCI_STROKES, rangeStroke: { $ref: "foregroundColor" }, handle: { ...handle }, text: { ...lineText, position: "center" }, label: { ...font, color: void 0, fontSize: { $round: [{ $mul: [{ $ref: "fontSize" }, 10 / 12] }] } } }, "fibonacci-retracement-trend-based": { ...stroke, strokes: ThemeSymbols.DEFAULT_FIBONACCI_STROKES, rangeStroke: { $ref: "foregroundColor" }, 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: { $ref: "foregroundColor" }, fillOpacity: 0.075 }, comment: { ...text, fontWeight: 700, handle: { ...handle }, fill: { $ref: "foregroundColor" } }, note: { ...text, color: ThemeSymbols.DEFAULT_TEXTBOX_COLOR, fill: ThemeSymbols.DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, stroke: { $ref: "backgroundColor" }, strokeWidth: 1, strokeOpacity: 1, handle: { ...handle }, background: { fill: ThemeSymbols.DEFAULT_TEXTBOX_FILL, stroke: ThemeSymbols.DEFAULT_TEXTBOX_STROKE, strokeWidth: 1 } }, text: { ...text, color: { $ref: "textColor" }, handle: { ...handle } }, // Shapes arrow: { ...stroke, handle: { ...handle }, text: { ...lineText } }, "arrow-up": { fill: ThemeSymbols.PALETTE_UP_FILL, handle: { ...handle, stroke: { $ref: "foregroundColor" } } }, "arrow-down": { fill: ThemeSymbols.PALETTE_DOWN_FILL, handle: { ...handle, stroke: { $ref: "foregroundColor" } } }, // Measurers "date-range": { ...measurer }, "price-range": { ...measurer }, "date-price-range": { ...measurer }, "quick-date-price-range": { up: { ...stroke, fill: ThemeSymbols.DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, fillOpacity: 0.2, handle: { ...handle }, statistics: { ...measurerStatistics, color: "#fff", fill: ThemeSymbols.DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, strokeWidth: 0, divider: { stroke: "#fff", strokeWidth: 1, strokeOpacity: 0.5 } } }, down: { ...stroke, stroke: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, fill: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, fillOpacity: 0.2, handle: { ...handle, stroke: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE }, statistics: { ...measurerStatistics, color: "#fff", fill: ThemeSymbols.DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, strokeWidth: 0, divider: { stroke: "#fff", strokeWidth: 1, strokeOpacity: 0.5 } } } }, axesButtons: {}, // Toolbars toolbar, optionsToolbar }; // packages/ag-charts-enterprise/src/features/annotations/annotationsModule.ts var AnnotationsModule = { type: "root", optionsKey: "annotations", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new Annotations(ctx), themeTemplate: { annotations: annotationsTheme } }; // packages/ag-charts-enterprise/src/features/background/background.ts var import_ag_charts_community101 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/image/image.ts var import_ag_charts_community100 = require("ag-charts-community"); var { BaseProperties: BaseProperties12, ObserveChanges: ObserveChanges3, ProxyProperty, Validate: Validate33, NUMBER: NUMBER9, POSITIVE_NUMBER: POSITIVE_NUMBER6, RATIO: RATIO5, calculatePlacement, createElement: createElement3 } = import_ag_charts_community100._ModuleSupport; var Image = 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 = calculatePlacement(this.imageElement.width, this.imageElement.height, container, this); this.node.setProperties( this.complete ? { visible: true, opacity: this.opacity, ...placement } : { visible: false } ); return placement; } }; __decorateClass([ Validate33(NUMBER9, { optional: true }) ], Image.prototype, "top", 2); __decorateClass([ Validate33(NUMBER9, { optional: true }) ], Image.prototype, "right", 2); __decorateClass([ Validate33(NUMBER9, { optional: true }) ], Image.prototype, "bottom", 2); __decorateClass([ Validate33(NUMBER9, { optional: true }) ], Image.prototype, "left", 2); __decorateClass([ Validate33(POSITIVE_NUMBER6, { optional: true }) ], Image.prototype, "width", 2); __decorateClass([ Validate33(POSITIVE_NUMBER6, { optional: true }) ], Image.prototype, "height", 2); __decorateClass([ Validate33(RATIO5) ], Image.prototype, "opacity", 2); __decorateClass([ ProxyProperty("imageElement.src"), ObserveChanges3((target) => target.loadedSynchronously = target.complete) ], Image.prototype, "url", 2); // packages/ag-charts-enterprise/src/features/background/background.ts var { ActionOnSet: ActionOnSet3, OBJECT: OBJECT15, Validate: Validate34 } = import_ag_charts_community101._ModuleSupport; var Background2 = class extends import_ag_charts_community101._ModuleSupport.Background { constructor() { super(...arguments); this.image = new Image(); } onLayoutComplete(event) { super.onLayoutComplete(event); if (this.image) { const { width, height } = event.chart; this.image.performLayout(width, height); } } onImageLoad() { this.ctx.updateService.update(import_ag_charts_community101._ModuleSupport.ChartUpdateType.SCENE_RENDER); } }; __decorateClass([ 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; } }) ], Background2.prototype, "image", 2); // packages/ag-charts-enterprise/src/features/background/backgroundModule.ts var BackgroundModule = { type: "root", optionsKey: "background", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Background2(ctx) }; // packages/ag-charts-enterprise/src/features/chart-toolbar/chartToolbarModule.ts var import_ag_charts_community103 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/chart-toolbar/chartToolbar.ts var import_ag_charts_community102 = require("ag-charts-community"); var { BOOLEAN: BOOLEAN12, ActionOnSet: ActionOnSet4, LayoutElement: LayoutElement2, 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(LayoutElement2.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_exports.error(e)); } getChartType() { const chartType = this.ctx.chartService.publicApi?.getOptions()?.chartType; if (chartType == null || !menuItems.some((item) => item.value === chartType)) { return "candlestick"; } return chartType; } }; __decorateClass([ Validate35(BOOLEAN12), ActionOnSet4({ changeValue(enabled) { this.toolbar?.setHidden(!enabled); } }) ], ChartToolbar.prototype, "enabled", 2); // packages/ag-charts-enterprise/src/features/chart-toolbar/chartToolbarModule.ts var ChartToolbarModule = { type: "root", optionsKey: "chartToolbar", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new ChartToolbar(ctx) }; // packages/ag-charts-enterprise/src/features/context-menu/contextMenuModule.ts var import_ag_charts_community105 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/context-menu/contextMenu.ts var import_ag_charts_community104 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/context-menu/contextMenuStyles.ts var DEFAULT_CONTEXT_MENU_CLASS = "ag-charts-context-menu"; var DEFAULT_CONTEXT_MENU_DARK_CLASS = "ag-charts-dark-context-menu"; // packages/ag-charts-enterprise/src/features/context-menu/contextMenu.ts var { BOOLEAN: BOOLEAN13, Validate: Validate36, initMenuKeyNav, makeAccessibleClickListener, ContextMenuRegistry, 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; /** * Extra menu actions with a label and callback. */ this.extraActions = []; /** * Extra menu actions that only appear when clicking on a node. */ this.extraNodeActions = []; /** * Extra menu actions that only appear when clicking on a series. */ this.extraSeriesAreaActions = []; /** * Extra menu actions that only appear when clicking on a legend item */ 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_exports.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 (ContextMenuRegistry.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 (ContextMenuRegistry.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 groupCount = [def, extra, extraSeriesArea, extraNode, extraLegendItem].reduce((count, e) => { return e.length + count; }, 0); if (groupCount === 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 = initMenuKeyNav({ 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, callback) { if (ContextMenuRegistry.checkCallback("legend", type, callback)) { return (event) => { if (this.pickedLegendItem) { const { seriesId, itemId } = this.pickedLegendItem; callback({ type: "contextmenu", seriesId, itemId, event }); this.hide(); } }; } else if (ContextMenuRegistry.checkCallback("series-area", type, callback)) { return () => { callback({ type: "seriesContextMenuAction", event: this.showEvent }); this.hide(); }; } else if (ContextMenuRegistry.checkCallback("node", type, callback)) { return () => { const { pickedNode, showEvent } = this; const event = pickedNode?.series.createNodeContextMenuActionEvent(showEvent, pickedNode); if (event) { callback(event); } else { logger_exports.error("series node not found"); } this.hide(); }; } return () => { callback({ type: "contextMenuEvent", event: this.showEvent }); this.hide(); }; } createButtonElement(type, label, callback, 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 = makeAccessibleClickListener(el, this.createButtonOnClick(type, callback)); 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: width, offsetHeight: height } = this.element; x = import_ag_charts_community104._ModuleSupport.clamp(0, x, canvasRect.width - width); y = import_ag_charts_community104._ModuleSupport.clamp(0, y, canvasRect.height - height); 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); } }; __decorateClass([ Validate36(BOOLEAN13) ], ContextMenu.prototype, "enabled", 2); __decorateClass([ Validate36(BOOLEAN13) ], ContextMenu.prototype, "darkTheme", 2); // packages/ag-charts-enterprise/src/features/context-menu/contextMenuModule.ts 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 } } }; // packages/ag-charts-enterprise/src/features/crosshair/crosshairModule.ts var import_ag_charts_community108 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/crosshair/crosshair.ts var import_ag_charts_community107 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/crosshair/crosshairLabel.ts var import_ag_charts_community106 = require("ag-charts-community"); var { BaseProperties: BaseProperties13, BOOLEAN: BOOLEAN14, FUNCTION: FUNCTION2, NUMBER: NUMBER10, STRING: STRING19, Validate: Validate37, createId: createId2, setAttribute: setAttribute2 } = 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; } }; __decorateClass([ Validate37(BOOLEAN14) ], CrosshairLabelProperties.prototype, "enabled", 2); __decorateClass([ Validate37(NUMBER10) ], CrosshairLabelProperties.prototype, "xOffset", 2); __decorateClass([ Validate37(NUMBER10) ], CrosshairLabelProperties.prototype, "yOffset", 2); __decorateClass([ Validate37(STRING19, { optional: true }) ], CrosshairLabelProperties.prototype, "format", 2); __decorateClass([ Validate37(FUNCTION2, { optional: true }) ], CrosshairLabelProperties.prototype, "renderer", 2); var CrosshairLabel = class extends BaseProperties13 { constructor(domManager, key, axisId) { super(); this.domManager = domManager; this.id = createId2(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); setAttribute2(this.element, "aria-hidden", true); this.element.setAttribute("data-key", key); this.element.setAttribute("data-axis-id", axisId); } show(meta) { const { element } = this; const left = meta.x + this.xOffset; const top = meta.y + this.yOffset; element.style.top = `${Math.round(top)}px`; element.style.left = `${Math.round(left)}px`; this.toggle(true); } setLabelHtml(html) { if (html !== void 0) { this.element.innerHTML = html; } } getBBox() { const { element } = this; return new import_ag_charts_community106._ModuleSupport.BBox( element.clientLeft, element.clientTop, element.clientWidth, element.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: text2 = defaults.text ?? "", color = defaults.color, backgroundColor = defaults.backgroundColor, opacity = defaults.opacity ?? 1 } = input; const style = `opacity: ${opacity}; background-color: ${backgroundColor?.toLowerCase()}; color: ${color}`; return `
${text2}
`; } }; __decorateClass([ Validate37(BOOLEAN14) ], CrosshairLabel.prototype, "enabled", 2); __decorateClass([ Validate37(NUMBER10) ], CrosshairLabel.prototype, "xOffset", 2); __decorateClass([ Validate37(NUMBER10) ], CrosshairLabel.prototype, "yOffset", 2); __decorateClass([ Validate37(STRING19, { optional: true }) ], CrosshairLabel.prototype, "format", 2); __decorateClass([ Validate37(FUNCTION2, { optional: true }) ], CrosshairLabel.prototype, "renderer", 2); // packages/ag-charts-enterprise/src/features/crosshair/crosshair.ts var { Group: Group5, TranslatableGroup, 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, isInteger, 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 TranslatableGroup({ 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: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset, axisLayout } = this; if (!axisLayout) return; const isVertical = this.isVertical(); lineGroupSelection.each((line) => { line.stroke = stroke2; 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) + (isInteger(value) ? 0 : 1); return formatNumber(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, height } = 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 - width / 2, y: axisPosition === "bottom" ? bounds.y + bounds.height + padding : bounds.y - height - padding }); } else { padding -= 8; label.show({ x: axisPosition === "right" ? bounds.x + bounds.width + padding : bounds.x - width - padding, y: y - height / 2 }); } } hideCrosshairs() { this.crosshairGroup.visible = false; for (const key of Object.keys(this.labels)) { this.hideLabel(key); } } hideLabel(key) { this.labels[key]?.toggle(false); } }; __decorateClass([ Validate38(BOOLEAN15) ], Crosshair.prototype, "enabled", 2); __decorateClass([ Validate38(COLOR_STRING4, { optional: true }) ], Crosshair.prototype, "stroke", 2); __decorateClass([ Validate38(LINE_DASH3, { optional: true }) ], Crosshair.prototype, "lineDash", 2); __decorateClass([ Validate38(POSITIVE_NUMBER7) ], Crosshair.prototype, "lineDashOffset", 2); __decorateClass([ Validate38(POSITIVE_NUMBER7) ], Crosshair.prototype, "strokeWidth", 2); __decorateClass([ Validate38(RATIO6) ], Crosshair.prototype, "strokeOpacity", 2); __decorateClass([ Validate38(BOOLEAN15) ], Crosshair.prototype, "snap", 2); __decorateClass([ Validate38(OBJECT16) ], Crosshair.prototype, "label", 2); // packages/ag-charts-enterprise/src/features/crosshair/crosshairModule.ts 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 } } } }; // packages/ag-charts-enterprise/src/features/data-source/dataSource.ts var import_ag_charts_community109 = require("ag-charts-community"); 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(); } } }; __decorateClass([ ActionOnSet5({ newValue(enabled) { this.updateCallback(enabled, this.getData); } }), Validate39(BOOLEAN16) ], DataSource.prototype, "enabled", 2); __decorateClass([ ActionOnSet5({ newValue(getData) { this.updateCallback(this.enabled, getData); } }), Validate39(FUNCTION3) ], DataSource.prototype, "getData", 2); __decorateClass([ ActionOnSet5({ newValue(requestThrottle) { this.dataService.requestThrottle = requestThrottle; } }) ], DataSource.prototype, "requestThrottle", 2); __decorateClass([ ActionOnSet5({ newValue(updateThrottle) { this.dataService.dispatchThrottle = updateThrottle; } }) ], DataSource.prototype, "updateThrottle", 2); __decorateClass([ ActionOnSet5({ newValue(updateDuringInteraction) { this.dataService.dispatchOnlyLatest = !updateDuringInteraction; } }) ], DataSource.prototype, "updateDuringInteraction", 2); // packages/ag-charts-enterprise/src/features/data-source/dataSourceModule.ts 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 } } }; // packages/ag-charts-enterprise/src/features/error-bar/errorBarModule.ts var import_ag_charts_community114 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/error-bar/errorBar.ts var import_ag_charts_community112 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/error-bar/errorBarNode.ts var import_ag_charts_community110 = require("ag-charts-community"); var { nearestSquaredInContainer, partialAssign, mergeDefaults, 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 } = capsTheme; const { lengthRatioMultiplier, lengthMax } = capDefaults; const desiredLength = length ?? 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 = mergeDefaults(result, whiskerStyle); capsStyle = mergeDefaults(result?.cap, result, capsStyle); } return { whiskerStyle, capsStyle }; } applyStyling(target, source) { partialAssign( ["visible", "stroke", "strokeWidth", "strokeOpacity", "lineDash", "lineDashOffset"], target, source ); } update(style, formatters, highlighted) { if (this.datum === void 0) { return; } const { whiskerStyle, capsStyle } = this.formatStyles(style, formatters, 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 } = BBox5.nearestBox(x, y, bboxes.components); return { nearest: this, distanceSquared }; } }; var ErrorBarGroup = class extends import_ag_charts_community110._ModuleSupport.Group { nearestSquared(x, y) { const { nearest, distanceSquared } = nearestSquaredInContainer(x, y, { children: this.children() }); if (nearest !== void 0 && !isNaN(distanceSquared)) { return { datum: nearest.datum, distanceSquared }; } } }; // packages/ag-charts-enterprise/src/features/error-bar/errorBarProperties.ts var import_ag_charts_community111 = require("ag-charts-community"); 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 { }; __decorateClass([ Validate40(BOOLEAN17, { optional: true }) ], ErrorBarCap.prototype, "visible", 2); __decorateClass([ Validate40(COLOR_STRING5, { optional: true }) ], ErrorBarCap.prototype, "stroke", 2); __decorateClass([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarCap.prototype, "strokeWidth", 2); __decorateClass([ Validate40(RATIO7, { optional: true }) ], ErrorBarCap.prototype, "strokeOpacity", 2); __decorateClass([ Validate40(LINE_DASH4, { optional: true }) ], ErrorBarCap.prototype, "lineDash", 2); __decorateClass([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarCap.prototype, "lineDashOffset", 2); __decorateClass([ Validate40(NUMBER11, { optional: true }) ], ErrorBarCap.prototype, "length", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yLowerKey", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yLowerName", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yUpperKey", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "yUpperName", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xLowerKey", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xLowerName", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xUpperKey", 2); __decorateClass([ Validate40(STRING20, { optional: true }) ], ErrorBarProperties.prototype, "xUpperName", 2); __decorateClass([ Validate40(BOOLEAN17, { optional: true }) ], ErrorBarProperties.prototype, "visible", 2); __decorateClass([ Validate40(COLOR_STRING5, { optional: true }) ], ErrorBarProperties.prototype, "stroke", 2); __decorateClass([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate40(RATIO7, { optional: true }) ], ErrorBarProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate40(LINE_DASH4, { optional: true }) ], ErrorBarProperties.prototype, "lineDash", 2); __decorateClass([ Validate40(POSITIVE_NUMBER8, { optional: true }) ], ErrorBarProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate40(FUNCTION4, { optional: true }) ], ErrorBarProperties.prototype, "itemStyler", 2); __decorateClass([ Validate40(OBJECT17) ], ErrorBarProperties.prototype, "cap", 2); // packages/ag-charts-enterprise/src/features/error-bar/errorBar.ts var { fixNumericExtent, groupAccumulativeValueProperty, mergeDefaults: mergeDefaults2, valueProperty: valueProperty2, 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 isDefined(xLowerKey) && isDefined(xUpperKey) || isDefined(yLowerKey) && isDefined(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( valueProperty2(yLowerKey, yScaleType, { id: `${yErrorsID}-lower` }), valueProperty2(yUpperKey, yScaleType, { id: `${yErrorsID}-upper` }) ); } if (xLowerKey != null && xUpperKey != null) { props.push( valueProperty2(xLowerKey, xScaleType, { id: `${xErrorsID}-lower` }), valueProperty2(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 groupAccumulativeValueProperty( 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 ? isDefined(xLowerKey) && isDefined(xUpperKey) : isDefined(yLowerKey) && isDefined(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 fixNumericExtent(domain); } } return []; } onDataUpdate(event) { this.dataModel = event.dataModel; this.processedData = event.processedData; if (isDefined(event.dataModel) && isDefined(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 (isDefined(xLower) && isDefined(xUpper)) { xBar = { lowerPoint: { x: this.convert(xScale, xLower), y: midPoint.y }, upperPoint: { x: this.convert(xScale, xUpper), y: midPoint.y } }; } if (isDefined(yLower) && isDefined(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, offset) { if (key == null) { return; } const value = datum.datum[key]; if (value == null) { return; } if (typeof value !== "number") { logger_exports.warnOnce(`Found [${key}] error value of type ${typeof value}. Expected number type`); return; } return value + offset; } 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(scale, value) { const offset = (scale.bandwidth ?? 0) / 2; return scale.convert(value) + offset; } 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: mergeDefaults2(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: stroke2, strokeWidth, visible, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { stroke: stroke2, strokeWidth, visible, strokeOpacity, lineDash, lineDashOffset }; } }; // packages/ag-charts-enterprise/src/features/error-bar/errorBarTheme.ts var import_ag_charts_community113 = require("ag-charts-community"); var ERROR_BARS_THEME = { series: { errorBar: { visible: true, stroke: { $ref: "foregroundColor" }, strokeWidth: 1, strokeOpacity: 1, cap: { length: void 0, lengthRatio: void 0 } } } }; // packages/ag-charts-enterprise/src/features/error-bar/errorBarModule.ts 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 }; // packages/ag-charts-enterprise/src/features/foreground/foreground.ts var import_ag_charts_community115 = require("ag-charts-community"); var { ZIndexMap: ZIndexMap5, ActionOnSet: ActionOnSet6, Validate: Validate41, ProxyPropertyOnWrite: ProxyPropertyOnWrite2, 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 Image(); 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, height } = event.chart; let placement = { x: 0, y: 0, width, height }; if (this.image) { placement = this.image.performLayout(width, height); } 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; } }; __decorateClass([ 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); __decorateClass([ Validate41(COLOR_STRING6, { optional: true }), ProxyPropertyOnWrite2("rectNode", "fill") ], Foreground.prototype, "fill", 2); __decorateClass([ Validate41(RATIO8, { optional: true }), ProxyPropertyOnWrite2("rectNode", "fillOpacity") ], Foreground.prototype, "fillOpacity", 2); // packages/ag-charts-enterprise/src/features/foreground/foregroundModule.ts var ForegroundModule = { type: "root", optionsKey: "foreground", packageType: "enterprise", chartTypes: ["cartesian", "polar", "hierarchy", "topology", "flow-proportion", "standalone", "gauge"], moduleFactory: (ctx) => new Foreground(ctx) }; // packages/ag-charts-enterprise/src/features/navigator/navigatorModule.ts var import_ag_charts_community123 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/navigator/navigator.ts var import_ag_charts_community122 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/navigator/miniChart.ts var import_ag_charts_community117 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/navigator/shapes/miniChartGroup.ts var import_ag_charts_community116 = require("ag-charts-community"); var { TranslatableGroup: TranslatableGroup2, ScenePathChangeDetection } = import_ag_charts_community116._ModuleSupport; var MiniChartGroup = class extends TranslatableGroup2 { constructor() { super(...arguments); this.inset = 0; this.cornerRadius = 0; } applyClip(ctx, clipRect) { const { cornerRadius, inset } = this; const { x, y, width, height } = clipRect; ctx.beginPath(); ctx.roundRect(x + inset, y + inset, width - 2 * inset, height - 2 * inset, cornerRadius); ctx.clip(); } }; __decorateClass([ ScenePathChangeDetection() ], MiniChartGroup.prototype, "inset", 2); __decorateClass([ ScenePathChangeDetection() ], MiniChartGroup.prototype, "cornerRadius", 2); // packages/ag-charts-enterprise/src/features/navigator/miniChart.ts var { Validate: Validate42, BOOLEAN: BOOLEAN18, POSITIVE_NUMBER: POSITIVE_NUMBER9, ZIndexMap: ZIndexMap6, ActionOnSet: ActionOnSet7, CategoryAxis, TextUtils: TextUtils2, Padding, Group: Group6, BBox: BBox6, ProxyProperty: ProxyProperty2 } = import_ag_charts_community117._ModuleSupport; var MiniChartPadding = class { constructor() { this.top = 0; this.bottom = 0; } }; __decorateClass([ Validate42(POSITIVE_NUMBER9) ], MiniChartPadding.prototype, "top", 2); __decorateClass([ 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_exports.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_exports.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 Padding(); 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 ? TextUtils2.getLineHeight(label.fontSize ?? 0) + label.spacing : 0); } padding[position] = Math.ceil(size); }); return padding; } async layout(width, height) { const { padding } = this; const animated = this.seriesRect != null; const seriesRect = new BBox6(0, 0, width, height - (padding.top + padding.bottom)); this.seriesRect = seriesRect; this.seriesRoot.translationY = padding.top; this.seriesRoot.setClipRectCanvasSpace(new BBox6(0, -padding.top, width, height)); 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 CategoryAxis; 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 = width; } else if (position === "bottom") { axis.translation.y = height; } if (!animated) { axis.resetAnimation("initial"); } axis.calculateLayout(); axis.update(); }); await Promise.all(this.series.map((series) => series.update({ seriesRect }))); } }; __decorateClass([ Validate42(BOOLEAN18) ], MiniChart.prototype, "enabled", 2); __decorateClass([ ProxyProperty2(["seriesRoot", "inset"]) ], MiniChart.prototype, "inset", 2); __decorateClass([ ProxyProperty2(["seriesRoot", "cornerRadius"]) ], MiniChart.prototype, "cornerRadius", 2); __decorateClass([ 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); __decorateClass([ ActionOnSet7({ changeValue(newValue, oldValue) { this.onSeriesChange(newValue, oldValue); } }) ], MiniChart.prototype, "series", 2); // packages/ag-charts-enterprise/src/features/navigator/navigatorDOMProxy.ts var import_ag_charts_community118 = require("ag-charts-community"); var { clamp: clamp5, SliderWidget } = 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 = SliderWidget.STEP_HUNDRETH; slider.keyboardStep = SliderWidget.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 ratio = this.sliders[1].getValueRatio(); const span = this._max - this._min; this._min = clamp5(0, ratio, 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(); } }; // packages/ag-charts-enterprise/src/features/navigator/shapes/rangeHandle.ts var import_ag_charts_community119 = require("ag-charts-community"); var { Validate: Validate43, ScenePathChangeDetection: ScenePathChangeDetection2, POSITIVE_NUMBER: POSITIVE_NUMBER10, BOOLEAN: BOOLEAN19, BBox: BBox7, ExtendedPath2D } = 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 ExtendedPath2D(); } 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, width, height, min, max, pixelAlign) { const minHandleX = minHandle.align(x + width * min) + pixelAlign; const maxHandleX = minHandleX + minHandle.align(x + width * min, width * (max - min)) - 2 * pixelAlign; const handleY = minHandle.align(y + height / 2); minHandle.setCenter(minHandleX, handleY); maxHandle.setCenter(maxHandleX, handleY); } computeBBox() { const { centerX, centerY, width, height } = this; const x = centerX - width / 2; const y = centerY - height / 2; return new BBox7(x, y, width, height); } 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: stroke2 } = this; super.renderFill(ctx, path); ctx.fillStyle = typeof stroke2 === "string" ? stroke2 : "black"; ctx.fill(this.gripPath.getPath2D()); } }; RangeHandle.className = "RangeHandle"; __decorateClass([ Validate43(POSITIVE_NUMBER10), ScenePathChangeDetection2() ], RangeHandle.prototype, "width", 2); __decorateClass([ Validate43(POSITIVE_NUMBER10), ScenePathChangeDetection2() ], RangeHandle.prototype, "height", 2); __decorateClass([ Validate43(POSITIVE_NUMBER10), ScenePathChangeDetection2() ], RangeHandle.prototype, "cornerRadius", 2); __decorateClass([ Validate43(BOOLEAN19), ScenePathChangeDetection2() ], RangeHandle.prototype, "grip", 2); // packages/ag-charts-enterprise/src/features/navigator/shapes/rangeMask.ts var import_ag_charts_community120 = require("ag-charts-community"); var { Path: Path6, BBox: BBox8, ExtendedPath2D: ExtendedPath2D2, clippedRoundRect, 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 ExtendedPath2D2(); } layout(x, y, width, height, min, max) { min = isNaN(min) ? this.min : min; max = isNaN(max) ? this.max : max; if (x !== this.x || y !== this.y || width !== this.width || this.height !== height || min !== this.min || max !== this.max) { this.x = x; this.y = y; this.width = width; this.height = height; this.min = min; this.max = max; this.dirtyPath = true; this.markDirty(); } } computeBBox() { const { x, y, width, height } = this; return new BBox8(x, y, width, height); } computeVisibleRangeBBox() { const { x, y, width, height, min, max } = this; const minX = x + width * min; const maxX = x + width * max; return new BBox8(minX, y, maxX - minX, height); } updatePath() { const { path, visiblePath, x, y, width, height, 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, width) - 2 * pixelAlign; const ah = this.align(y, height) - 2 * pixelAlign; const minX = this.align(x + width * min) + pixelAlign; const maxX = minX + this.align(x + width * min, width * (max - min)) - 2 * pixelAlign; const cornerRadiusParams = { topLeft: cornerRadius, topRight: cornerRadius, bottomRight: cornerRadius, bottomLeft: cornerRadius }; clippedRoundRect(path, ax, ay, aw, ah, cornerRadiusParams, new BBox8(ax, ay, minX - ax, ah)); clippedRoundRect(path, ax, ay, aw, ah, cornerRadiusParams, new BBox8(maxX, ay, aw + ax - maxX, ah)); if (maxX - minX > 1) { clippedRoundRect(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"; __decorateClass([ Validate44(POSITIVE_NUMBER11), ScenePathChangeDetection3() ], RangeMask.prototype, "cornerRadius", 2); // packages/ag-charts-enterprise/src/features/navigator/shapes/rangeSelector.ts var import_ag_charts_community121 = require("ag-charts-community"); 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, width, height, lOffset, rOffset) { this.x = x; this.y = y; this.width = width; this.height = height; 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, height, lOffset, rOffset } = this; return new import_ag_charts_community121._ModuleSupport.BBox(x - lOffset, y, width + (lOffset + rOffset), height); } }; // packages/ag-charts-enterprise/src/features/navigator/navigator.ts var { clamp: clamp6, BaseModuleInstance: BaseModuleInstance2, ObserveChanges: ObserveChanges4, Validate: Validate45, BOOLEAN: BOOLEAN20, POSITIVE_NUMBER: POSITIVE_NUMBER12 } = import_ag_charts_community122._ModuleSupport; var Navigator = class extends BaseModuleInstance2 { 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 } = opts.series.rect; const { y, height } = this; this.domProxy.updateVisibility(this.enabled); if (this.enabled) { const { _min: min, _max: max } = this.domProxy; this.layoutNodes(x, y, width, height, min, max); this.domProxy.updateBounds({ x, y, width, height }); } this.x = x; this.width = width; this.miniChart?.layout(width, height).catch((e) => logger_exports.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 } = this; const { minRange } = this.domProxy; let { _min: min, _max: max } = this.domProxy; const ratio = (offsetX - x) / width; if (dragging === "min") { min = clamp6(0, ratio, max - minRange); } else if (dragging === "max") { max = clamp6(min + minRange, ratio, 1); } else if (dragging === "pan" && panStart != null) { const span = max - min; min = clamp6(0, ratio - 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, height } = this; const { min, max } = xZoom; this.domProxy.updateMinMax(min, max); this.layoutNodes(x, y, width, height, min, max); } layoutNodes(x, y, width, height, min, max) { const { rangeSelector, mask, minHandle, maxHandle } = this; mask.layout(x, y, width, height, min, max); rangeSelector.layout(x, y, width, height, minHandle.width / 2, maxHandle.width / 2); RangeHandle.align(minHandle, maxHandle, x, y, width, height, 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); } } }; __decorateClass([ ObserveChanges4((target, value, oldValue) => { target.updateBackground(oldValue?.root, value?.root); }) ], Navigator.prototype, "miniChart", 2); __decorateClass([ Validate45(BOOLEAN20), ObserveChanges4((target, value) => { target.ctx.zoomManager.setNavigatorEnabled(Boolean(value)); target.updateGroupVisibility(); }) ], Navigator.prototype, "enabled", 2); __decorateClass([ Validate45(POSITIVE_NUMBER12) ], Navigator.prototype, "height", 2); __decorateClass([ Validate45(POSITIVE_NUMBER12), ObserveChanges4((target, value) => { target.mask.cornerRadius = value; }) ], Navigator.prototype, "cornerRadius", 2); __decorateClass([ Validate45(POSITIVE_NUMBER12) ], Navigator.prototype, "spacing", 2); // packages/ag-charts-enterprise/src/features/navigator/navigatorModule.ts 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 } } } } }; // packages/ag-charts-enterprise/src/features/ranges/ranges.ts var import_ag_charts_community125 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/ranges/rangesButtonProperties.ts var import_ag_charts_community124 = require("ag-charts-community"); 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 { }; __decorateClass([ Validate46(OR3(NUMBER12, AND4(ARRAY4, ARRAY4.restrict({ length: 2 })), FUNCTION5)) ], RangesButtonProperties.prototype, "value", 2); // packages/ag-charts-enterprise/src/features/ranges/ranges.ts var { BOOLEAN: BOOLEAN21, OBJECT: OBJECT19, ChartAxisDirection: ChartAxisDirection14, LayoutElement: LayoutElement3, PropertiesArray: PropertiesArray4, Toolbar, 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 Toolbar(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 height = toolbar2.getBounds().height; toolbar2.setBounds({ x: layoutBox.x, y: layoutBox.y + layoutBox.height - height, width: layoutBox.width, height }); layoutBox.shrink({ bottom: height + 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); } }; __decorateClass([ Validate47(BOOLEAN21) ], Ranges.prototype, "enabled", 2); __decorateClass([ Validate47(OBJECT19) ], Ranges.prototype, "buttons", 2); // packages/ag-charts-enterprise/src/features/ranges/rangesModule.ts 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, end) => [(/* @__PURE__ */ new Date(`${new Date(end).getFullYear()}-01-01`)).getTime(), end] }, { label: "toolbarRange1Year", ariaLabel: "toolbarRange1YearAria", value: YEAR }, { label: "toolbarRangeAll", ariaLabel: "toolbarRangeAllAria", value: (start, end) => [start, end] } ] } } }; // packages/ag-charts-enterprise/src/features/shared-toolbar/sharedToolbarModule.ts var import_ag_charts_community127 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/shared-toolbar/sharedToolbar.ts var import_ag_charts_community126 = require("ag-charts-community"); var _SharedToolbar = class _SharedToolbar 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 width = sharedToolbar.getBounds().width; sharedToolbar.setBounds({ x: layoutBox.x, y: layoutBox.y, width }); layoutBox.shrink({ left: width + 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 = _SharedToolbar.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 sum = 0; for (const order of _SharedToolbar.SECTION_ORDER) { if (order !== section) { sum += this.sectionButtons[order].length; continue; } for (const index of this.sectionButtons[section].keys()) { sharedToolbar.setButtonHiddenByIndex(sum + 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 sum = 0; for (const order of _SharedToolbar.SECTION_ORDER) { if (order === section) return sum + index; sum += this.sectionButtons[order].length; } return -1; } getSectionIndex(section, index) { let sum = 0; for (const order of _SharedToolbar.SECTION_ORDER) { if (order === section) { if (index >= sum + this.sectionButtons[section].length) return -1; return index - sum; } sum += this.sectionButtons[order].length; } return -1; } }; _SharedToolbar.SECTION_ORDER = ["chartToolbar", "annotations"]; var SharedToolbar = _SharedToolbar; // packages/ag-charts-enterprise/src/features/shared-toolbar/sharedToolbarModule.ts var SharedToolbarModule = { type: "context", contextKey: "sharedToolbar", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new SharedToolbar(ctx) }; // packages/ag-charts-enterprise/src/features/status-bar/statusBarModule.ts var import_ag_charts_community129 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/status-bar/statusBar.ts var import_ag_charts_community128 = require("ag-charts-community"); var { CachedTextMeasurerPool: CachedTextMeasurerPool2, ZIndexMap: ZIndexMap7, LayoutElement: LayoutElement4, Validate: Validate48, BaseProperties: BaseProperties15, OBJECT: OBJECT20, BOOLEAN: BOOLEAN22, STRING: STRING21, COLOR_STRING: COLOR_STRING7, RATIO: RATIO9, valueProperty: valueProperty3, TextUtils: TextUtils3, Group: Group7, Label: Label2, Rect, Text } = import_ag_charts_community128._ModuleSupport; var chartConfigurations = { ohlc: 2 /* Open */ | 4 /* Close */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */, candlestick: 2 /* Open */ | 4 /* Close */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */, "hollow-candlestick": 2 /* Open */ | 4 /* Close */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */, line: 64 /* UnlabelledClose */ | 32 /* Volume */, "step-line": 64 /* UnlabelledClose */ | 32 /* Volume */, hlc: 128 /* NeutralClose */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */, "high-low": 512 /* NeutralLow */ | 256 /* NeutralHigh */ | 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; } }; __decorateClass([ Validate48(COLOR_STRING7) ], StatusBarBackground.prototype, "fill", 2); __decorateClass([ 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 Label2(); this.positive = new Label2(); this.negative = new Label2(); this.neutral = new Label2(); this.altNeutral = new Label2(); 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 Rect()); this.labels = [ { label: "O", configuration: 2 /* Open */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), id: "openValue", key: "openKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "H", configuration: 16 /* High */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), id: "highValue", key: "highKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "H", configuration: 256 /* NeutralHigh */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), style: "neutral", id: "highValue", key: "highKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "L", configuration: 8 /* Low */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), id: "lowValue", key: "lowKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "L", configuration: 512 /* NeutralLow */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), style: "neutral", id: "lowValue", key: "lowKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "C", configuration: 4 /* Close */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), id: "closeValue", key: "closeKey", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "C", configuration: 128 /* NeutralClose */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), id: "closeValue", key: "closeKey", style: "neutral", domain: void 0, formatter: new Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }, { label: "", configuration: 64 /* UnlabelledClose */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), 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 /* Volume */, title: this.labelGroup.appendChild(new Text()), value: this.labelGroup.appendChild(new Text()), 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( CachedTextMeasurerPool2.measureText(formatter.format(domain[0]), { font: this.positive.getFont(), textBaseline: textVAlign, textAlign: "left" }).width, CachedTextMeasurerPool2.measureText(formatter.format(domain[1]), { font: this.positive.getFont(), textBaseline: textVAlign, textAlign: "left" }).width, CachedTextMeasurerPool2.measureText(formatter.format(domain[0]), { font: this.negative.getFont(), textBaseline: textVAlign, textAlign: "left" }).width, CachedTextMeasurerPool2.measureText(formatter.format(domain[1]), { font: this.negative.getFont(), textBaseline: textVAlign, textAlign: "left" }).width ); title.visible = true; value.visible = true; const titleMetrics = CachedTextMeasurerPool2.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; } }; __decorateClass([ Validate48(BOOLEAN22) ], StatusBar.prototype, "enabled", 2); __decorateClass([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "openKey", 2); __decorateClass([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "highKey", 2); __decorateClass([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "lowKey", 2); __decorateClass([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "closeKey", 2); __decorateClass([ Validate48(STRING21, { optional: true }) ], StatusBar.prototype, "volumeKey", 2); __decorateClass([ Validate48(OBJECT20) ], StatusBar.prototype, "title", 2); __decorateClass([ Validate48(OBJECT20) ], StatusBar.prototype, "positive", 2); __decorateClass([ Validate48(OBJECT20) ], StatusBar.prototype, "negative", 2); __decorateClass([ Validate48(OBJECT20) ], StatusBar.prototype, "neutral", 2); __decorateClass([ Validate48(OBJECT20) ], StatusBar.prototype, "altNeutral", 2); __decorateClass([ Validate48(OBJECT20) ], StatusBar.prototype, "background", 2); __decorateClass([ Validate48(STRING21) ], StatusBar.prototype, "layoutStyle", 2); // packages/ag-charts-enterprise/src/features/status-bar/statusBarModule.ts 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" } } } }; // packages/ag-charts-enterprise/src/features/sync/chartSync.ts var import_ag_charts_community130 = require("ag-charts-community"); var { BOOLEAN: BOOLEAN23, STRING: STRING22, UNION: UNION7, BaseProperties: BaseProperties16, CartesianAxis: CartesianAxis2, ChartUpdateType: ChartUpdateType2, ObserveChanges: ObserveChanges5, TooltipManager, 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 = ChartUpdateType2.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 (!CartesianAxis2.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 = isDate(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(isDefined); 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 = TooltipManager.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, ChartUpdateType2.SERIES_UPDATE); } } } }); } getSyncedDomain(axis) { if (!CartesianAxis2.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 && (isFiniteNumber(min) || isFiniteNumber(mainAxis.min)) || max !== mainAxis.max && (isFiniteNumber(max) || isFiniteNumber(mainAxis.max))) { logger_exports.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 unique( 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"; __decorateClass([ Validate49(BOOLEAN23), ObserveChanges5((target) => target.onEnabledChange()) ], ChartSync.prototype, "enabled", 2); __decorateClass([ Validate49(STRING22, { optional: true }), ObserveChanges5((target, newValue, oldValue) => target.onGroupIdChange(newValue, oldValue)) ], ChartSync.prototype, "groupId", 2); __decorateClass([ Validate49(UNION7(["x", "y", "xy"], "an axis")), ObserveChanges5((target) => target.onAxesChange()) ], ChartSync.prototype, "axes", 2); __decorateClass([ Validate49(BOOLEAN23), ObserveChanges5((target) => target.onNodeInteractionChange()) ], ChartSync.prototype, "nodeInteraction", 2); __decorateClass([ Validate49(BOOLEAN23), ObserveChanges5((target) => target.onZoomChange()) ], ChartSync.prototype, "zoom", 2); // packages/ag-charts-enterprise/src/features/sync/syncModule.ts var SyncModule = { type: "root", optionsKey: "sync", packageType: "enterprise", chartTypes: ["cartesian"], moduleFactory: (ctx) => new ChartSync(ctx), themeTemplate: { sync: { enabled: false } } }; // packages/ag-charts-enterprise/src/features/zoom/zoom.ts var import_ag_charts_community140 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/zoom/scenes/zoomRect.ts var import_ag_charts_community131 = require("ag-charts-community"); 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"; __decorateClass([ Validate50(COLOR_STRING8) ], ZoomRect.prototype, "fill", 2); __decorateClass([ Validate50(RATIO10) ], ZoomRect.prototype, "fillOpacity", 2); // packages/ag-charts-enterprise/src/features/zoom/zoomAxisDragger.ts var import_ag_charts_community133 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/features/zoom/zoomUtils.ts var import_ag_charts_community132 = require("ag-charts-community"); var { UNION: UNION8, clamp: clamp7, isNumberEqual: isNumberEqual8, round } = 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, epsilon = 1e-10) { return isNumberEqual8(left.min, right.min, epsilon) && isNumberEqual8(left.max, right.max, epsilon); } function isZoomEqual(left, right, epsilon) { return isZoomRangeEqual(left.x, right.x, epsilon) && isZoomRangeEqual(left.y, right.y, epsilon); } 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, origin) { const { min, max } = oldState; const center = 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: center - diff8 / 2, max: center + diff8 / 2 }; case "pointer": return scaleZoomAxisWithPoint(newState, oldState, origin ?? center); default: return { min, max }; } } function scaleZoomAxisWithPoint(newState, oldState, origin) { const newDelta = newState.max - newState.min; const oldDelta = oldState.max - oldState.min; const scaledOrigin = origin * (1 - (oldDelta - newDelta)); const translation = origin - 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 }; } // packages/ag-charts-enterprise/src/features/zoom/zoomAxisDragger.ts 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 origin = 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 - origin.x) * dx(oldZoom); newZoom.x.max += scaleX; newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchor, origin.x); newZoom = constrainZoom(newZoom); return newZoom.x; } const scaleY = (target.y - origin.y) * dy(oldZoom); newZoom.y.max -= scaleY; newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchor, origin.y); newZoom = constrainZoom(newZoom); return newZoom.y; } }; // packages/ag-charts-enterprise/src/features/zoom/zoomContextMenu.ts 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 origin = pointToRatio(rect, event.x, event.y); return this.iterateFindNextZoomAtPoint(origin) != 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 origin = this.computeOrigin(event); if (!origin) return; const zoom = this.iterateFindNextZoomAtPoint(origin); if (zoom == null) return; this.updateZoom(zoom); } onPanToHere({ event }) { const origin = this.computeOrigin(event); if (!origin) return; const zoom = definedZoomState(this.zoomManager.getZoom()); const scaleX = dx(zoom); const scaleY = dy(zoom); const scaledOriginX = origin.x * scaleX; const scaledOriginY = origin.y * scaleY; const halfSize = (UNIT.max - UNIT.min) / 2; let newZoom = { x: { min: origin.x - halfSize, max: origin.x + halfSize }, y: { min: origin.y - halfSize, max: origin.y + halfSize } }; newZoom = scaleZoomCenter(newZoom, scaleX, scaleY); newZoom = translateZoom(newZoom, zoom.x.min - origin.x + scaledOriginX, zoom.y.min - origin.y + scaledOriginY); this.updateZoom(constrainZoom(newZoom)); } iterateFindNextZoomAtPoint(origin) { const { scrollingStep } = this.getModuleProperties(); for (let i = scrollingStep; i <= 1 - scrollingStep; i += scrollingStep) { const zoom = this.getNextZoomAtPoint(origin, i); if (this.isZoomValid(zoom)) { return zoom; } } } getNextZoomAtPoint(origin, step) { const { isScalingX, isScalingY } = this.getModuleProperties(); const zoom = definedZoomState(this.zoomManager.getZoom()); const scaledOriginX = origin.x * dx(zoom); const scaledOriginY = origin.y * dy(zoom); const size = UNIT.max - UNIT.min; const halfSize = size / 2; let newZoom = { x: { min: origin.x - halfSize, max: origin.x + halfSize }, y: { min: origin.y - halfSize, max: origin.y + halfSize } }; newZoom = scaleZoomCenter(newZoom, isScalingX ? dx(zoom) * step : size, isScalingY ? dy(zoom) * step : size); newZoom = translateZoom(newZoom, zoom.x.min - origin.x + scaledOriginX, zoom.y.min - origin.y + scaledOriginY); return constrainZoom(newZoom); } }; // packages/ag-charts-enterprise/src/features/zoom/zoomDOMProxy.ts var import_ag_charts_community134 = require("ag-charts-community"); var { BBoxValues } = 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(BBoxValues.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 }; } }; // packages/ag-charts-enterprise/src/features/zoom/zoomPanner.ts var import_ag_charts_community135 = require("ag-charts-community"); 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 angle = Math.atan2(yVelocity, xVelocity); const t0 = performance.now(); this.inertiaHandle = import_ag_charts_community135._ModuleSupport.getWindow().requestAnimationFrame((t) => { this.animateInertia(t, t, t0, velocity, angle); }); } } 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, angle) { 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(angle) * (s1 - s0), deltaY: -Math.sin(angle) * (s1 - s0) }); if (s1 >= maxS - 1) return; this.inertiaHandle = requestAnimationFrame((nextT) => { this.animateInertia(nextT, t, t0, velocity, angle); }); } 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 offset = pointToRatio(bbox, bbox.x + Math.abs(deltaX), bbox.y + bbox.height - Math.abs(deltaY)); const offsetX = Math.sign(deltaX) * offset.x; const offsetY = -Math.sign(deltaY) * offset.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; } }; // packages/ag-charts-enterprise/src/features/zoom/zoomScrollPanner.ts var import_ag_charts_community136 = require("ag-charts-community"); 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 offset = pointToRatio(bbox, bbox.x + Math.abs(deltaX), 0); const offsetX = deltaX < 0 ? -offset.x : offset.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; } }; // packages/ag-charts-enterprise/src/features/zoom/zoomScroller.ts var import_ag_charts_community137 = require("ag-charts-community"); var ZoomScroller = class { updateAxes(event, props, bbox, zooms) { const sourceEvent = event.sourceEvent; const newZooms = {}; const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props; const origin = 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, origin.x); } else if (direction === import_ag_charts_community137._ModuleSupport.ChartAxisDirection.Y && isScalingY) { newZoom.max += delta4; newZoom = scaleZoomAxisWithAnchor(newZoom, zoom, anchorPointY, origin.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 origin = 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, origin.x); } if (isScalingY) { newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchorPointY, origin.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; } }; // packages/ag-charts-enterprise/src/features/zoom/zoomSelector.ts 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, height } = normal; let { x, y } = normal; x = Math.max(x, bbox.x); x -= Math.max(0, x + width - (bbox.x + bbox.width)); y = Math.max(y, bbox.y); y -= Math.max(0, y + height - (bbox.y + bbox.height)); rect.x = x; rect.y = y; rect.width = width; rect.height = height; 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 origin = 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 = origin.x * dx(oldZoom); const translateY = origin.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 width = x1 <= x2 ? x2 - x1 : x1 - x2; const height = y1 <= y2 ? y2 - y1 : y1 - y2; return { x, y, width, height }; } }; // packages/ag-charts-enterprise/src/features/zoom/zoomToolbar.ts var import_ag_charts_community138 = require("ag-charts-community"); var { ARRAY: ARRAY5, BOOLEAN: BOOLEAN24, STRING: STRING23, UNION: UNION9, ActionOnSet: ActionOnSet8, BaseProperties: BaseProperties17, ChartAxisDirection: ChartAxisDirection15, NativeWidget: NativeWidget2, PropertiesArray: PropertiesArray5, Toolbar: Toolbar2, ToolbarButtonProperties: ToolbarButtonProperties4, Validate: Validate51, createElement: createElement5 } = import_ag_charts_community138._ModuleSupport; var ZoomButtonProperties = class extends ToolbarButtonProperties4 { }; __decorateClass([ Validate51(UNION9(["reset", "zoom-in", "zoom-out", "pan-left", "pan-right", "pan-start", "pan-end"])) ], ZoomButtonProperties.prototype, "value", 2); __decorateClass([ 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 NativeWidget2(createElement5("div")); this.container.addClass("ag-charts-zoom-buttons"); ctx.domManager.addChild("canvas-overlay", "zoom-buttons", this.container.getElement()); this.toolbar = new Toolbar2(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 height = container.getBounds().height; container.setBounds({ y: rect.y + rect.height - height }); } onHover(event) { if (!this.enabled || this.visible !== "hover" || this.toolbar.isHidden()) return; const { container, detectionRange, ctx: { scene } } = this; const { currentY, sourceEvent: { target } } = event; const element = container.getElement(); const detectionY = element.offsetTop - detectionRange; const visible = currentY > detectionY && currentY < scene.canvas.element.offsetHeight || target === element; 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 element = toolbar2.getElement(); element.style.transitionDuration = immediate ? "0s" : ""; element.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 scale = event.value === "zoom-in" ? 1 - scrollingStep : 1 + scrollingStep; if (!isScalingDirection) scale = 1; const anchorPoint = isDirectionX ? this.getAnchorPointX(props) : this.getAnchorPointY(props); newZoom.max = newZoom.min + (newZoom.max - newZoom.min) * scale; 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 scale = button === "zoom-in" ? 1 - scrollingStep : 1 + scrollingStep; const zoom = scaleZoom(oldZoom, isScalingX ? scale : 1, isScalingY ? scale : 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; } }; __decorateClass([ Validate51(BOOLEAN24), ActionOnSet8({ changeValue(enabled) { this.toolbar?.setHidden(!enabled); } }) ], ZoomToolbar.prototype, "enabled", 2); __decorateClass([ Validate51(ARRAY5) ], ZoomToolbar.prototype, "buttons", 2); __decorateClass([ Validate51(UNION9(["always", "zoomed", "hover"])), ActionOnSet8({ changeValue(visible, oldValue) { if (oldValue == null) return; this.toggleVisibility(visible === "always"); } }) ], ZoomToolbar.prototype, "visible", 2); __decorateClass([ Validate51(ANCHOR_POINT) ], ZoomToolbar.prototype, "anchorPointX", 2); __decorateClass([ Validate51(ANCHOR_POINT) ], ZoomToolbar.prototype, "anchorPointY", 2); // packages/ag-charts-enterprise/src/features/zoom/zoomTwoFingers.ts var import_ag_charts_community139 = require("ag-charts-community"); 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 }; } } // packages/ag-charts-enterprise/src/features/zoom/zoom.ts var { BOOLEAN: BOOLEAN25, NUMBER: NUMBER13, POSITIVE_NUMBER: POSITIVE_NUMBER13, RATIO: RATIO11, UNION: UNION10, OBJECT: OBJECT21, OR: OR4, ActionOnSet: ActionOnSet9, ChartAxisDirection: ChartAxisDirection16, ChartUpdateType: ChartUpdateType3, Deprecated, Validate: Validate52, InteractionState: InteractionState4, ProxyProperty: ProxyProperty3, round: sharedRound } = import_ag_charts_community140._ModuleSupport; var round2 = (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; } }; __decorateClass([ Validate52(BOOLEAN25), ActionOnSet9({ changeValue(enabled) { this.onChange({ enabled, padding: this.padding }); } }) ], ZoomAutoScaling.prototype, "enabled", 2); __decorateClass([ 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) ); // Zoom methods this.axisDragger = new ZoomAxisDragger(); this.panner = new ZoomPanner(); this.scroller = new ZoomScroller(); this.scrollPanner = new ZoomScrollPanner(); this.twoFingers = new ZoomTwoFingers(); this.deceleration = "short"; // State this.dragState = 0 /* None */; 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 /* None */ || this.isIgnoredTouch(event)) { return; } } this.panner.stopInteractions(); let newDragState = 0 /* None */; if (enableAxisDragging && hoveredAxis) { newDragState = 1 /* Axis */; } else if (event != null) { const panKeyPressed = this.isPanningKeyPressed(event.sourceEvent); if (enablePanning && (!enableSelecting || panKeyPressed)) { domManager.updateCursor(CURSOR_ID, "grabbing"); newDragState = 2 /* Pan */; this.panner.start(); } else if (enableSelecting && !panKeyPressed) { newDragState = 3 /* Select */; } } if ((this.dragState = newDragState) !== 0 /* None */) { 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 /* Axis */: { 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 /* Pan */: panner.update(event); break; case 3 /* Select */: selector.update(event, this.getModuleProperties(), paddedRect); break; case 0 /* None */: 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 /* None */) return; switch (dragState) { case 1 /* Axis */: this.hoveredAxis = void 0; axisDragger.stop(); break; case 2 /* Pan */: panner.stop(); break; case 3 /* Select */: { if (!selector.didUpdate()) break; const zoom = this.getZoom(); const newZoom = selector.stop(this.seriesRect, this.paddedRect, zoom); this.updateZoom(newZoom); break; } } this.dragState = 0 /* None */; 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 /* None */) return; if (this.twoFingers.start(event, current, this.getZoom())) { this.dragState = 4 /* TwoFingers */; } } onTouchMove(event, current) { if (!this.enableTwoFingerZoom || this.dragState !== 4 /* TwoFingers */) return; const newZoom = this.twoFingers.update(event, current); this.updateZoom(constrainZoom(newZoom)); } onTouchEnd(event) { if (!this.enableTwoFingerZoom || this.dragState !== 4 /* TwoFingers */) return; event.sourceEvent.preventDefault(); if (this.twoFingers.end(event)) { this.dragState = 0 /* None */; } } 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 = round2(dx(newZoom)) < round2(dx(zoom)); const zoomedInY = round2(dy(newZoom)) < round2(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 }; } }; __decorateClass([ ActionOnSet9({ newValue(enabled) { this.onEnabledChange(enabled); } }), Validate52(BOOLEAN25) ], Zoom.prototype, "enabled", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableAxisDragging", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableDoubleClickToReset", 2); __decorateClass([ ActionOnSet9({ changeValue(newValue) { this.ctx.zoomManager.setIndependentAxes(Boolean(newValue)); } }), Validate52(BOOLEAN25, { optional: true }) ], Zoom.prototype, "enableIndependentAxes", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "enablePanning", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableScrolling", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableSelecting", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "enableTwoFingerZoom", 2); __decorateClass([ Validate52(UNION10(["alt", "ctrl", "meta", "shift"], "a pan key")) ], Zoom.prototype, "panKey", 2); __decorateClass([ Validate52(UNION10(["x", "y", "xy"], "an axis")) ], Zoom.prototype, "axes", 2); __decorateClass([ Validate52(RATIO11) ], Zoom.prototype, "scrollingStep", 2); __decorateClass([ Validate52(BOOLEAN25) ], Zoom.prototype, "keepAspectRatio", 2); __decorateClass([ Validate52(POSITIVE_NUMBER13) ], Zoom.prototype, "minVisibleItems", 2); __decorateClass([ Deprecated("Use [minVisibleItems] instead."), Validate52(NUMBER13.restrict({ min: 1 })) ], Zoom.prototype, "minVisibleItemsX", 2); __decorateClass([ Deprecated("Use [minVisibleItems] instead."), Validate52(NUMBER13.restrict({ min: 1 })) ], Zoom.prototype, "minVisibleItemsY", 2); __decorateClass([ Validate52(ANCHOR_POINT) ], Zoom.prototype, "anchorPointX", 2); __decorateClass([ Validate52(ANCHOR_POINT) ], Zoom.prototype, "anchorPointY", 2); __decorateClass([ Validate52(OBJECT21) ], Zoom.prototype, "autoScaling", 2); __decorateClass([ Validate52(OBJECT21) ], Zoom.prototype, "buttons", 2); __decorateClass([ ProxyProperty3("panner.deceleration"), Validate52(OR4(RATIO11, UNION10(["off", "short", "long"], "a deceleration"))) ], Zoom.prototype, "deceleration", 2); // packages/ag-charts-enterprise/src/features/zoom/zoomModule.ts 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 } } } }; // packages/ag-charts-enterprise/src/gradient-legend/gradientLegendModule.ts var import_ag_charts_community142 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/gradient-legend/gradientLegend.ts var import_ag_charts_community141 = require("ag-charts-community"); var { BOOLEAN: BOOLEAN26, OBJECT: OBJECT22, POSITION, POSITIVE_NUMBER: POSITIVE_NUMBER14, BaseProperties: BaseProperties18, AxisTicks, ZIndexMap: ZIndexMap8, ProxyProperty: ProxyProperty4, Validate: Validate53, LayoutElement: LayoutElement5, createId: createId4, Group: Group8, Rect: Rect2, Marker, TranslatableGroup: TranslatableGroup3, LinearGradient } = import_ag_charts_community141._ModuleSupport; var GradientBar = class extends BaseProperties18 { constructor() { super(...arguments); this.thickness = 16; this.preferredLength = 100; } }; __decorateClass([ Validate53(POSITIVE_NUMBER14) ], GradientBar.prototype, "thickness", 2); __decorateClass([ Validate53(POSITIVE_NUMBER14) ], GradientBar.prototype, "preferredLength", 2); var GradientLegendScale = class { constructor(axisTicks) { this.axisTicks = axisTicks; } }; __decorateClass([ ProxyProperty4("axisTicks.label") ], GradientLegendScale.prototype, "label", 2); __decorateClass([ ProxyProperty4("axisTicks.interval") ], GradientLegendScale.prototype, "interval", 2); __decorateClass([ 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 Rect2(); this.arrow = new Marker({ 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 AxisTicks(); 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 angle; if (this.isVertical()) { angle = 0; gradientRect.width = thickness; gradientRect.height = Math.min(shrinkRect.height, preferredLength); } else { angle = 90; gradientRect.width = Math.min(shrinkRect.width, preferredLength); gradientRect.height = thickness; } gradientRect.fill = new LinearGradient( "oklch", colorRange.map((color, i) => ({ offset: i / (colorRange.length - 1), color })), angle ); } 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, label } = this.axisTicks; const size = label.fontSize ?? 0; const t = scale.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, height } = this.gradientRect; if (this.isVertical()) { width += axisBox.width + 5; } else { height += axisBox.height + 5; } switch (this.position) { case "left": top += shrinkRect.height / 2 - height / 2; shrinkRect.shrink(width + this.spacing, "left"); break; case "right": left += shrinkRect.width - width; top += shrinkRect.height / 2 - height / 2; shrinkRect.shrink(width + this.spacing, "right"); break; case "top": left += shrinkRect.width / 2 - width / 2; shrinkRect.shrink(height + this.spacing, "top"); break; case "bottom": left += shrinkRect.width / 2 - width / 2; top += shrinkRect.height - height; shrinkRect.shrink(height + this.spacing, "bottom"); } return { top, left }; } onChartHoverChange() { if (!this.enabled) return; this.updateArrow(); } }; GradientLegend.className = "GradientLegend"; __decorateClass([ Validate53(BOOLEAN26) ], GradientLegend.prototype, "enabled", 2); __decorateClass([ Validate53(POSITION) ], GradientLegend.prototype, "position", 2); __decorateClass([ Validate53(BOOLEAN26) ], GradientLegend.prototype, "reverseOrder", 2); __decorateClass([ Validate53(OBJECT22) ], GradientLegend.prototype, "gradient", 2); __decorateClass([ Validate53(POSITIVE_NUMBER14) ], GradientLegend.prototype, "spacing", 2); // packages/ag-charts-enterprise/src/gradient-legend/gradientLegendModule.ts 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" }; // packages/ag-charts-enterprise/src/license/watermark.ts var import_ag_charts_community143 = require("ag-charts-community"); function injectWatermark(domManager, text2) { const element = domManager.addChild("canvas-overlay", "watermark"); const textElement = import_ag_charts_community143._ModuleSupport.createElement("span"); textElement.innerText = text2; element.addEventListener("animationend", () => { domManager.removeChild("canvas-overlay", "watermark"); domManager.removeStyles("watermark"); }); element.classList.add("ag-watermark"); element.appendChild(textElement); } // packages/ag-charts-enterprise/src/series/bar/barModule.ts var import_ag_charts_community147 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/bar/barSeries.ts var import_ag_charts_community146 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/bar/barAggregation.ts var import_ag_charts_community145 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/utils/aggregation.ts var import_ag_charts_community144 = require("ag-charts-community"); var { findMinMax: findMinMax2 } = import_ag_charts_community144._ModuleSupport; var X_MIN = 0; var X_MAX = 1; var Y_MIN = 2; var Y_MAX = 3; var SPAN = 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 findMinMax2(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) * SPAN | 0; } function createAggregationIndices(xValues, yMaxValues, yMinValues, d0, d1, maxRange) { const indexData = new Int32Array(maxRange * SPAN).fill(-1); const valueData = new Float64Array(maxRange * SPAN).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_MIN] === -1; if (unset || xRatio < valueData[aggIndex + X_MIN]) { indexData[aggIndex + X_MIN] = datumIndex; valueData[aggIndex + X_MIN] = xRatio; } if (unset || xRatio > valueData[aggIndex + X_MAX]) { indexData[aggIndex + X_MAX] = datumIndex; valueData[aggIndex + X_MAX] = xRatio; } if (unset || yMin < valueData[aggIndex + Y_MIN]) { indexData[aggIndex + Y_MIN] = datumIndex; valueData[aggIndex + Y_MIN] = yMin; } if (unset || yMax > valueData[aggIndex + Y_MAX]) { indexData[aggIndex + Y_MAX] = datumIndex; valueData[aggIndex + Y_MAX] = yMax; } } return { indexData, valueData }; } function compactAggregationIndices(indexData, valueData, maxRange, { inPlace = false } = {}) { const nextMaxRange = maxRange / 2 | 0; const nextIndexData = !inPlace ? new Int32Array(nextMaxRange * SPAN) : indexData; const nextValueData = !inPlace ? new Float64Array(nextMaxRange * SPAN) : valueData; for (let i = 0; i < nextMaxRange; i += 1) { const aggIndex = i * SPAN | 0; const index0 = aggIndex * 2 | 0; const index1 = index0 + SPAN | 0; const index1Unset = indexData[index1 + X_MIN] === -1; const xMinAggIndex = index1Unset || valueData[index0 + X_MIN] < valueData[index1 + X_MIN] ? index0 : index1; nextIndexData[aggIndex + X_MIN] = indexData[xMinAggIndex + X_MIN]; nextValueData[aggIndex + X_MIN] = valueData[xMinAggIndex + X_MIN]; const xMaxAggIndex = index1Unset || valueData[index0 + X_MAX] > valueData[index1 + X_MAX] ? index0 : index1; nextIndexData[aggIndex + X_MAX] = indexData[xMaxAggIndex + X_MAX]; nextValueData[aggIndex + X_MAX] = valueData[xMaxAggIndex + X_MAX]; const yMinAggIndex = index1Unset || valueData[index0 + Y_MIN] < valueData[index1 + Y_MIN] ? index0 : index1; nextIndexData[aggIndex + Y_MIN] = indexData[yMinAggIndex + Y_MIN]; nextValueData[aggIndex + Y_MIN] = valueData[yMinAggIndex + Y_MIN]; const yMaxAggIndex = index1Unset || valueData[index0 + Y_MAX] > valueData[index1 + Y_MAX] ? index0 : index1; nextIndexData[aggIndex + Y_MAX] = indexData[yMaxAggIndex + Y_MAX]; nextValueData[aggIndex + Y_MAX] = valueData[yMaxAggIndex + Y_MAX]; } return { maxRange: nextMaxRange, indexData: nextIndexData, valueData: nextValueData }; } // packages/ag-charts-enterprise/src/series/bar/barAggregation.ts var indexes = { xMin: X_MIN, xMax: X_MAX, yMin: Y_MIN, yMax: Y_MAX, span: SPAN }; var AGGREGATION_THRESHOLD = 1e3; var PRECISION = 5; function getIndices(maxRange, indexData) { return Array.from({ length: maxRange }, (_, index) => { const aggIndex = index * SPAN; const xMinIndex = indexData[aggIndex + X_MIN]; const xMaxIndex = indexData[aggIndex + X_MAX]; 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; } // packages/ag-charts-enterprise/src/series/bar/barSeries.ts var { ChartAxisDirection: ChartAxisDirection17, ContinuousScale: ContinuousScale2, OrdinalTimeScale: OrdinalTimeScale2 } = import_ag_charts_community146._ModuleSupport; var BarSeries = 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 || !(ContinuousScale2.is(xAxis.scale) || OrdinalTimeScale2.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); } }; // packages/ag-charts-enterprise/src/series/bar/barModule.ts var { BarSeriesModule } = import_ag_charts_community147._ModuleSupport; var BarModule = { ...BarSeriesModule, type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "bar", moduleFactory: (ctx) => new BarSeries(ctx) }; // packages/ag-charts-enterprise/src/series/box-plot/boxPlotModule.ts var import_ag_charts_community152 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeries.ts var import_ag_charts_community150 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/box-plot/blotPlotUtil.ts function prepareBoxPlotFromTo(isVertical) { const from = isVertical ? { scalingX: 1, scalingY: 0 } : { scalingX: 0, scalingY: 1 }; const to = { scalingX: 1, scalingY: 1 }; return { from, to }; } function resetBoxPlotSelectionsScalingCenterFn(isVertical) { return (_node, datum) => { if (isVertical) { return { scalingCenterY: datum.scaledValues.medianValue }; } return { scalingCenterX: datum.scaledValues.medianValue }; }; } // packages/ag-charts-enterprise/src/series/box-plot/boxPlotGroup.ts var import_ag_charts_community148 = require("ag-charts-community"); var { ScalableGroup, Rect: Rect3, Line: Line4, BBox: BBox9, Selection: Selection3 } = import_ag_charts_community148._ModuleSupport; var BoxPlotGroup = class extends ScalableGroup { 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, width, height) => isVertical ? { y: x, x: y, width: height, height: width } : { x, y, width, height }; 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, width, height) => { ({ x, y, width, height } = position(x, y, width, height)); return new BBox9(x, y, width, height); }; const { fill, fillOpacity, stroke: stroke2, 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 element of boxes) { element.setProperties({ fill, fillOpacity, strokeWidth: strokeWidth * 2, strokeOpacity: 0 }); } median.setProperties({ fill: stroke2, fillOpacity: strokeOpacity, strokeWidth: 0 }); for (const element of [...whiskers, ...caps]) { element.setProperties(whiskerStyles); } outline.setProperties({ stroke: stroke2, 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_exports.error("BoxPlotGroup.datum.midPoint is undefined"); return { x: NaN, y: NaN }; } return datum.midPoint; } }; // packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeriesProperties.ts var import_ag_charts_community149 = require("ag-charts-community"); var { BaseProperties: BaseProperties19, AbstractBarSeriesProperties, SeriesTooltip, 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; } }; __decorateClass([ Validate54(RATIO12) ], BoxPlotSeriesCap.prototype, "lengthRatio", 2); var BoxPlotSeriesWhisker = class extends BaseProperties19 { }; __decorateClass([ Validate54(COLOR_STRING9, { optional: true }) ], BoxPlotSeriesWhisker.prototype, "stroke", 2); __decorateClass([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesWhisker.prototype, "strokeWidth", 2); __decorateClass([ Validate54(RATIO12) ], BoxPlotSeriesWhisker.prototype, "strokeOpacity", 2); __decorateClass([ Validate54(LINE_DASH5, { optional: true }) ], BoxPlotSeriesWhisker.prototype, "lineDash", 2); __decorateClass([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesWhisker.prototype, "lineDashOffset", 2); var BoxPlotSeriesProperties = class extends AbstractBarSeriesProperties { 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 SeriesTooltip(); // Internal: Set by paletteFactory. this.backgroundFill = "white"; } toJson() { const { stroke: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this; const properties = super.toJson(); properties.whisker = mergeDefaults3(properties.whisker, { stroke: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset }); return properties; } }; __decorateClass([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "minKey", 2); __decorateClass([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "q1Key", 2); __decorateClass([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "medianKey", 2); __decorateClass([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "q3Key", 2); __decorateClass([ Validate54(STRING24) ], BoxPlotSeriesProperties.prototype, "maxKey", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "minName", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "q1Name", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "medianName", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "q3Name", 2); __decorateClass([ Validate54(STRING24, { optional: true }) ], BoxPlotSeriesProperties.prototype, "maxName", 2); __decorateClass([ Validate54(COLOR_STRING9, { optional: true }) ], BoxPlotSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate54(RATIO12) ], BoxPlotSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate54(COLOR_STRING9) ], BoxPlotSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate54(RATIO12) ], BoxPlotSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate54(LINE_DASH5) ], BoxPlotSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate54(POSITIVE_NUMBER15) ], BoxPlotSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate54(FUNCTION6, { optional: true }) ], BoxPlotSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate54(OBJECT23) ], BoxPlotSeriesProperties.prototype, "cap", 2); __decorateClass([ Validate54(OBJECT23) ], BoxPlotSeriesProperties.prototype, "whisker", 2); __decorateClass([ Validate54(OBJECT23) ], BoxPlotSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate54(COLOR_STRING9) ], BoxPlotSeriesProperties.prototype, "backgroundFill", 2); // packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeries.ts var { extractDecoratedProperties, fixNumericExtent: fixNumericExtent2, keyProperty: keyProperty2, mergeDefaults: mergeDefaults4, SeriesNodePickMode, SMALLEST_KEY_INTERVAL, valueProperty: valueProperty4, diff, animationValidation, computeBarFocusBounds, createDatumId, Color: Color6, ContinuousScale: ContinuousScale3, ChartAxisDirection: ChartAxisDirection18, motion } = 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: [SeriesNodePickMode.NEAREST_NODE, SeriesNodePickMode.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(diff(this.id, this.processedData)); } if (animationEnabled) { extraProps.push(animationValidation()); } const { processedData } = await this.requestDataModel(dataController, this.data, { props: [ keyProperty2(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_INTERVAL] : [], ...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 fixNumericExtent2(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: stroke2, 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 height = Math.abs(scaledValues.q3Value - scaledValues.q1Value); const midX = scaledValues.xValue + bandwidth / 2; const midY = Math.min(scaledValues.q3Value, scaledValues.q1Value) + height / 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: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset, midPoint, focusRect }); }); return context; } legendItemSymbol() { const { fill, fillOpacity, stroke: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { marker: { fill, fillOpacity, stroke: stroke2, 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, to } = prepareBoxPlotFromTo(isVertical); motion.resetMotion([datumSelection], resetBoxPlotSelectionsScalingCenterFn(isVertical)); motion.staticFromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], from, 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(createDatumId(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: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = activeStyles; activeStyles.whisker = mergeDefaults4(activeStyles.whisker, { stroke: stroke2, 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: stroke2, 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: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius, cap: extractDecoratedProperties(cap), whisker: extractDecoratedProperties(whisker) }; if (itemStyler) { const formatStyles = this.cachedDatumCallback( createDatumId(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 computeBarFocusBounds(this, this.contextNodeData?.nodeData[datumIndex].focusRect); } }; BoxPlotSeries.className = "BoxPlotSeries"; BoxPlotSeries.type = "box-plot"; // packages/ag-charts-enterprise/src/series/box-plot/boxPlotThemes.ts var import_ag_charts_community151 = require("ag-charts-community"); var { CARTESIAN_AXIS_TYPE } = 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_TYPE.NUMBER]: { crosshair: { snap: false } }, [CARTESIAN_AXIS_TYPE.CATEGORY]: { groupPaddingInner: 0.2, crosshair: { enabled: false, snap: false } } } }; // packages/ag-charts-enterprise/src/series/box-plot/boxPlotModule.ts var { Color: Color7, swapAxisCondition, ThemeSymbols: { DEFAULT_BACKGROUND_COLOUR }, ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE2, CARTESIAN_POSITION } } = 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: swapAxisCondition( [ { type: CARTESIAN_AXIS_TYPE2.NUMBER, position: CARTESIAN_POSITION.LEFT }, { type: CARTESIAN_AXIS_TYPE2.CATEGORY, position: CARTESIAN_POSITION.BOTTOM } ], (series) => series?.direction === "horizontal" ), themeTemplate: BOX_PLOT_SERIES_THEME, groupable: true, paletteFactory: ({ takeColors, themeTemplateParameters }) => { const themeBackgroundColor = themeTemplateParameters.get(DEFAULT_BACKGROUND_COLOUR); const backgroundFill = (Array.isArray(themeBackgroundColor) ? themeBackgroundColor[0] : themeBackgroundColor) ?? "white"; const { fills: [fill], strokes: [stroke2] } = takeColors(1); let fakeFill; try { fakeFill = Color7.mix(Color7.fromString(backgroundFill), Color7.fromString(fill), 0.3).toString(); } catch { fakeFill = fill; } return { fill: fakeFill, stroke: stroke2, backgroundFill }; } }; // packages/ag-charts-enterprise/src/series/candlestick/candlestickModule.ts var import_ag_charts_community160 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/candlestick/candlestickSeries.ts var import_ag_charts_community158 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesBase.ts var import_ag_charts_community153 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/ohlc/ohlcAggregation.ts var AGGREGATION_THRESHOLD2 = 1e3; var OPEN = X_MIN; var HIGH = Y_MAX; var LOW = Y_MIN; var CLOSE = X_MAX; 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; } // packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesBase.ts var { fixNumericExtent: fixNumericExtent3, keyProperty: keyProperty3, createDatumId: createDatumId2, SeriesNodePickMode: SeriesNodePickMode2, ChartAxisDirection: ChartAxisDirection19, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL2, valueProperty: valueProperty5, diff: diff2, animationValidation: animationValidation2, computeBarFocusBounds: computeBarFocusBounds2, visibleRangeIndices, ContinuousScale: ContinuousScale4, OrdinalTimeScale: OrdinalTimeScale3, BandScale: BandScale2 } = 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: [SeriesNodePickMode2.AXIS_ALIGNED, SeriesNodePickMode2.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(diff2(this.id, this.processedData)); } extraProps.push(animationValidation2()); } 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_INTERVAL2] : [], ...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 = BandScale2.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, width, crisp) => { const datum = rawData[datumIndex]; const xOffset = applyWidthOffset ? width / 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 height = Math.max(yHigh, yLow) - y; const midPoint = { x: centerX, y: y + height / 2 }; nodeData.push({ series: this, itemId, datum, datumIndex, xKey, xValue, openValue, closeValue, highValue, lowValue, midPoint, aggregatedValue: closeValue, isRising, centerX, width, y, height, yOpen, yClose, crisp }); }; const { dataAggregationFilters } = this; const xScale = xAxis.scale; const [r0, r1] = xScale.range; const range2 = r1 - r0; const xPosition = (index) => xScale.convert(xValues[index]) + groupOffset; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range2); if (dataAggregationFilter == null) { let [start, end] = visibleRangeIndices(rawData.length, xAxis.range, (index) => { const x = xPosition(index); return [x, x + effectiveBarWidth]; }); if (processedData.input.count < 1e3) { start = 0; end = processedData.input.count; } for (let datumIndex = start; datumIndex < end; 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_exports.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_exports.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 [start, end] = visibleRangeIndices(maxRange, xAxis.range, (index) => { const aggIndex = index * SPAN; const openIndex = indexData[aggIndex + OPEN]; const closeIndex = indexData[aggIndex + CLOSE]; if (openIndex === -1) return; return [xPosition(openIndex), xPosition(closeIndex) + effectiveBarWidth]; }); for (let i = start; i < end; i += 1) { const aggIndex = i * SPAN; 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 width = Math.abs(xPosition(closeIndex) - xPosition(openIndex)) + effectiveBarWidth; handleDatum(midDatumIndex, xValue, openValue, closeValue, highValue, lowValue, width, 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(createDatumId2(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 createDatumId2(datum.xValue); } computeFocusBounds(opts) { const nodeDatum = this.getNodeData()?.at(opts.datumIndex); if (nodeDatum == null) return; const { centerX, y, width, height } = nodeDatum; const datum = { x: centerX - width / 2, y, width, height }; return computeBarFocusBounds2(this, datum); } }; // packages/ag-charts-enterprise/src/series/candlestick/candlestickNode.ts var import_ag_charts_community155 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/ohlc/ohlcNode.ts var import_ag_charts_community154 = require("ag-charts-community"); 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, height } = this; return new BBox10(centerX - width / 2, y, width, height); } 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, height, crisp, strokeAlignment } = this; let { centerX, yOpen, yClose } = this; let x0 = centerX - width / 2; let x1 = centerX + width / 2; let y0 = y; let y1 = y + height; if (crisp && width > 1) { centerX = this.align(centerX); yOpen = this.align(yOpen); yClose = this.align(yClose); const halfWidth = this.align(width / 2); x0 = centerX - halfWidth; x1 = centerX + halfWidth; y0 = this.align(y); y1 = y0 + this.align(y0, height); } 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, strokeWidth } = this; if (width < strokeWidth) { ctx.lineWidth = width; } super.executeStroke(ctx, path); } }; __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "centerX", 2); __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "y", 2); __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "width", 2); __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "height", 2); __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "yOpen", 2); __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "yClose", 2); __decorateClass([ ScenePathChangeDetection4() ], OhlcBaseNode.prototype, "crisp", 2); __decorateClass([ 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); } } }; // packages/ag-charts-enterprise/src/series/candlestick/candlestickNode.ts 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: stroke2, 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 !== stroke2 || 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: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset, wickStroke = stroke2, 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()); } }; __decorateClass([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickStroke", 2); __decorateClass([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickStrokeWidth", 2); __decorateClass([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickStrokeOpacity", 2); __decorateClass([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickLineDash", 2); __decorateClass([ ScenePathChangeDetection5() ], CandlestickNode.prototype, "wickLineDashOffset", 2); // packages/ag-charts-enterprise/src/series/candlestick/candlestickSeriesProperties.ts var import_ag_charts_community157 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesProperties.ts var import_ag_charts_community156 = require("ag-charts-community"); var { BaseProperties: BaseProperties20, Validate: Validate55, AbstractBarSeriesProperties: AbstractBarSeriesProperties2, SeriesTooltip: SeriesTooltip2, 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; } }; __decorateClass([ Validate55(COLOR_STRING10) ], OhlcSeriesItem.prototype, "stroke", 2); __decorateClass([ Validate55(POSITIVE_NUMBER16) ], OhlcSeriesItem.prototype, "strokeWidth", 2); __decorateClass([ Validate55(RATIO13) ], OhlcSeriesItem.prototype, "strokeOpacity", 2); __decorateClass([ Validate55(LINE_DASH6) ], OhlcSeriesItem.prototype, "lineDash", 2); __decorateClass([ Validate55(POSITIVE_NUMBER16) ], OhlcSeriesItem.prototype, "lineDashOffset", 2); var OhlcSeriesItems = class extends BaseProperties20 { constructor() { super(...arguments); this.up = new OhlcSeriesItem(); this.down = new OhlcSeriesItem(); } }; __decorateClass([ Validate55(OBJECT24) ], OhlcSeriesItems.prototype, "up", 2); __decorateClass([ Validate55(OBJECT24) ], OhlcSeriesItems.prototype, "down", 2); var OhlcSeriesBaseProperties = class extends AbstractBarSeriesProperties2 { }; __decorateClass([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "xKey", 2); __decorateClass([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "openKey", 2); __decorateClass([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "closeKey", 2); __decorateClass([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "highKey", 2); __decorateClass([ Validate55(STRING25) ], OhlcSeriesBaseProperties.prototype, "lowKey", 2); __decorateClass([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "xName", 2); __decorateClass([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "yName", 2); __decorateClass([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "openName", 2); __decorateClass([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "closeName", 2); __decorateClass([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "highName", 2); __decorateClass([ Validate55(STRING25, { optional: true }) ], OhlcSeriesBaseProperties.prototype, "lowName", 2); var OhlcSeriesProperties = class extends OhlcSeriesBaseProperties { constructor() { super(...arguments); this.tooltip = new SeriesTooltip2(); this.item = new OhlcSeriesItems(); } }; __decorateClass([ Validate55(OBJECT24) ], OhlcSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate55(OBJECT24) ], OhlcSeriesProperties.prototype, "item", 2); __decorateClass([ Validate55(FUNCTION7, { optional: true }) ], OhlcSeriesProperties.prototype, "itemStyler", 2); // packages/ag-charts-enterprise/src/series/candlestick/candlestickSeriesProperties.ts 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 { }; __decorateClass([ Validate56(COLOR_STRING11, { optional: true }) ], CandlestickSeriesWick.prototype, "stroke", 2); __decorateClass([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesWick.prototype, "strokeWidth", 2); __decorateClass([ Validate56(RATIO14) ], CandlestickSeriesWick.prototype, "strokeOpacity", 2); __decorateClass([ Validate56(LINE_DASH7, { optional: true }) ], CandlestickSeriesWick.prototype, "lineDash", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate56(COLOR_STRING11, { optional: true }) ], CandlestickSeriesItem.prototype, "fill", 2); __decorateClass([ Validate56(RATIO14) ], CandlestickSeriesItem.prototype, "fillOpacity", 2); __decorateClass([ Validate56(COLOR_STRING11) ], CandlestickSeriesItem.prototype, "stroke", 2); __decorateClass([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesItem.prototype, "strokeWidth", 2); __decorateClass([ Validate56(RATIO14) ], CandlestickSeriesItem.prototype, "strokeOpacity", 2); __decorateClass([ Validate56(LINE_DASH7) ], CandlestickSeriesItem.prototype, "lineDash", 2); __decorateClass([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesItem.prototype, "lineDashOffset", 2); __decorateClass([ Validate56(POSITIVE_NUMBER17) ], CandlestickSeriesItem.prototype, "cornerRadius", 2); __decorateClass([ Validate56(OBJECT25) ], CandlestickSeriesItem.prototype, "wick", 2); var CandlestickSeriesItems = class extends BaseProperties21 { constructor() { super(...arguments); this.up = new CandlestickSeriesItem(); this.down = new CandlestickSeriesItem(); } }; __decorateClass([ Validate56(OBJECT25) ], CandlestickSeriesItems.prototype, "up", 2); __decorateClass([ Validate56(OBJECT25) ], CandlestickSeriesItems.prototype, "down", 2); var CandlestickSeriesProperties = class extends OhlcSeriesBaseProperties { constructor() { super(...arguments); this.item = new CandlestickSeriesItems(); this.tooltip = new SeriesTooltip3(); } }; __decorateClass([ Validate56(OBJECT25) ], CandlestickSeriesProperties.prototype, "item", 2); __decorateClass([ Validate56(OBJECT25) ], CandlestickSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate56(FUNCTION8, { optional: true }) ], CandlestickSeriesProperties.prototype, "itemStyler", 2); // packages/ag-charts-enterprise/src/series/candlestick/candlestickSeries.ts 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, y, height, yOpen, yClose, crisp } = datum; let style; if (itemStyler != null) { const { fill, fillOpacity, stroke: stroke2, 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: stroke2, strokeWidth, lineDash, lineDashOffset, highlighted: isHighlight }) ); } node.centerX = centerX; node.width = width; node.y = y; node.height = height; 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 stroke2 = 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: stroke2, 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"; // packages/ag-charts-enterprise/src/series/candlestick/candlestickThemes.ts var import_ag_charts_community159 = require("ag-charts-community"); 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 } } } }; // packages/ag-charts-enterprise/src/series/candlestick/candlestickModule.ts var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE4, CARTESIAN_POSITION: CARTESIAN_POSITION2 } = 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_POSITION2.LEFT }, { type: CARTESIAN_AXIS_TYPE4.ORDINAL_TIME, position: CARTESIAN_POSITION2.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 } }; } }; // packages/ag-charts-enterprise/src/series/chord/chordModule.ts var import_ag_charts_community165 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/chord/chordSeries.ts var import_ag_charts_community164 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/flow-proportion/flowProportionSeries.ts var import_ag_charts_community161 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/flow-proportion/flowProportionUtil.ts 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_exports.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; } // packages/ag-charts-enterprise/src/series/flow-proportion/flowProportionSeries.ts var { Series, DataController, Validate: Validate57, ARRAY: ARRAY6, keyProperty: keyProperty4, valueProperty: valueProperty6, Selection: Selection4, Group: Group9, TransformableText } = 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 /* Node */ ? nodeDatum?.label : void 0; } }; var FlowProportionSeries = class extends Series { 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, TransformableText ); 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 DataController("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 /* Node */, index: datumIndex }, type: 1 /* Node */, 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 /* Node */, index: datumIndex }, type: 1 /* Node */, 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 /* Link */, index: datumIndex }, type: 0 /* Link */, 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 */ && 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 /* Node */) { focusLinkSelection = nodeData.filter((node) => { return node.type === 0 /* Link */ && (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 /* Link */) { 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: stroke2 = strokes[nodeIndex % strokes.length], strokeWidth = 0, strokeOpacity = 1, lineDash = [0], lineDashOffset = 0 } = format; return { marker: { fill, fillOpacity, stroke: stroke2, 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 /* Node */, nodeIndex), hideInLegend: !showInLegend, isFixed: true }) ); } pickNodeClosestDatum({ x, y }) { let minDistanceSquared = Infinity; let minDatum; this.linkSelection.each((node, datum) => { const distanceSquared = node.containsPoint(x, y) ? 0 : Infinity; if (distanceSquared < minDistanceSquared) { minDistanceSquared = distanceSquared; minDatum = datum; } }); this.nodeSelection.each((node, datum) => { const distanceSquared = node.distanceSquared(x, y); if (distanceSquared < minDistanceSquared) { minDistanceSquared = distanceSquared; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } getDatumAriaText(datum, description) { if (datum.type === 0 /* Link */) { 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 /* Node */) { 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 /* Link */) { 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 /* Node */) { 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 /* Node */ ? 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 }; } }; __decorateClass([ Validate57(ARRAY6, { optional: true, property: "nodes" }) ], FlowProportionSeries.prototype, "_chartNodes", 2); // packages/ag-charts-enterprise/src/series/chord/chordLink.ts var import_ag_charts_community162 = require("ag-charts-community"); 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 width = Math.max(...outer.x, ...inner.x) - x; const y = Math.min(...outer.y, ...inner.y); const height = Math.max(...outer.y, ...inner.y) - y; return new BBox11(centerX + x, centerY + y, width, height); } tensionedCurveTo(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y) { const { path, tension } = this; const scale = 1 - tension; path.cubicCurveTo( (cp1x - cp0x) * scale + cp0x, (cp1y - cp0y) * scale + cp0y, (cp2x - cp3x) * scale + cp3x, (cp2y - cp3y) * scale + 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(); } }; __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "centerX", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "centerY", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "radius", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "startAngle1", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "endAngle1", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "startAngle2", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "endAngle2", 2); __decorateClass([ ScenePathChangeDetection6() ], ChordLink.prototype, "tension", 2); // packages/ag-charts-enterprise/src/series/chord/chordSeriesProperties.ts var import_ag_charts_community163 = require("ag-charts-community"); var { BaseProperties: BaseProperties22, SeriesTooltip: SeriesTooltip4, SeriesProperties, ARRAY: ARRAY7, COLOR_STRING: COLOR_STRING12, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY2, 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; } }; __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLabelProperties.prototype, "spacing", 2); __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLabelProperties.prototype, "maxWidth", 2); var ChordSeriesLinkProperties = class extends BaseProperties22 { 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; } }; __decorateClass([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesLinkProperties.prototype, "fill", 2); __decorateClass([ Validate58(RATIO15) ], ChordSeriesLinkProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesLinkProperties.prototype, "stroke", 2); __decorateClass([ Validate58(RATIO15) ], ChordSeriesLinkProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLinkProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate58(LINE_DASH8) ], ChordSeriesLinkProperties.prototype, "lineDash", 2); __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesLinkProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate58(RATIO15) ], ChordSeriesLinkProperties.prototype, "tension", 2); __decorateClass([ Validate58(FUNCTION9, { optional: true }) ], ChordSeriesLinkProperties.prototype, "itemStyler", 2); var ChordSeriesNodeProperties = class extends BaseProperties22 { 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; } }; __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "spacing", 2); __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "width", 2); __decorateClass([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesNodeProperties.prototype, "fill", 2); __decorateClass([ Validate58(RATIO15) ], ChordSeriesNodeProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate58(COLOR_STRING12, { optional: true }) ], ChordSeriesNodeProperties.prototype, "stroke", 2); __decorateClass([ Validate58(RATIO15) ], ChordSeriesNodeProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate58(LINE_DASH8) ], ChordSeriesNodeProperties.prototype, "lineDash", 2); __decorateClass([ Validate58(POSITIVE_NUMBER18) ], ChordSeriesNodeProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate58(FUNCTION9, { optional: true }) ], ChordSeriesNodeProperties.prototype, "itemStyler", 2); var ChordSeriesProperties = class extends SeriesProperties { 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(); } }; __decorateClass([ Validate58(STRING26) ], ChordSeriesProperties.prototype, "fromKey", 2); __decorateClass([ Validate58(STRING26) ], ChordSeriesProperties.prototype, "toKey", 2); __decorateClass([ Validate58(STRING26) ], ChordSeriesProperties.prototype, "idKey", 2); __decorateClass([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "idName", 2); __decorateClass([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "sizeKey", 2); __decorateClass([ Validate58(STRING26, { optional: true }) ], ChordSeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate58(ARRAY7, { optional: true }) ], ChordSeriesProperties.prototype, "nodes", 2); __decorateClass([ Validate58(COLOR_STRING_ARRAY2) ], ChordSeriesProperties.prototype, "fills", 2); __decorateClass([ Validate58(COLOR_STRING_ARRAY2) ], ChordSeriesProperties.prototype, "strokes", 2); __decorateClass([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "label", 2); __decorateClass([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "link", 2); __decorateClass([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "node", 2); __decorateClass([ Validate58(OBJECT26) ], ChordSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/chord/chordSeries.ts var { SeriesNodePickMode: SeriesNodePickMode3, CachedTextMeasurerPool: CachedTextMeasurerPool3, TextWrapper: TextWrapper4, TextUtils: TextUtils4, createDatumId: createDatumId4, angleBetween: angleBetween2, normalizeAngle360: normalizeAngle3605, isBetweenAngles: isBetweenAngles2, Sector: Sector3, evaluateBezier, applyShapeStyle } = import_ag_charts_community164._ModuleSupport; var nodeMidAngle = (node) => node.startAngle + angleBetween2(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 text2 = TextWrapper4.wrapText(label, { maxWidth: labelMaxWidth, font: this.properties.label, textWrap: "never" }); const { width } = CachedTextMeasurerPool3.measureText(text2, { font: canvasFont, textAlign: "left", textBaseline: "middle" }); maxMeasuredLabelWidth = Math.max(width, maxMeasuredLabelWidth); labelData.push({ id, text: text2, 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_exports.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: angleBetween2(nodeMidAngle(l.node.datum), midAngle), after: false })), ...linksAfter.map((l) => ({ link: l.link, distance: angleBetween2(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 = evaluateBezier(...outer.x, 0.5); const outerY = evaluateBezier(...outer.y, 0.5); const innerX = evaluateBezier(...inner.x, 0.5); const innerY = evaluateBezier(...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 + angleBetween2(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 (isBetweenAngles2(minAngle, a0, a1)) return false; if (isBetweenAngles2(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: text2, centerX, centerY, radius, angle }) => { label.visible = true; label.translationX = centerX + radius * Math.cos(angle); label.translationY = centerY + radius * Math.sin(angle); label.text = text2; label.fill = fill; label.fontStyle = fontStyle; label.fontWeight = fontWeight; label.fontSize = fontSize; label.fontFamily = fontFamily; label.textBaseline = "middle"; if (Math.cos(angle) >= 0) { label.textAlign = "left"; label.rotation = angle; } else { label.textAlign = "right"; label.rotation = angle - 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: stroke2, 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 ?? stroke2, 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 stroke2 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } 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: stroke2, 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: stroke2, 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 ?? stroke2, 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 stroke2 = format.stroke ?? strokes[fromNodeDatumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } 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: stroke2, 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; applyShapeStyle(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 /* Link */ ? seriesDatum.fromNode.index : seriesDatum.index; const title = seriesDatum.type === 0 /* Link */ ? `${seriesDatum.fromNode.label} - ${seriesDatum.toNode.label}` : seriesDatum.label; const datum = datumIndex.type === 0 /* Link */ ? linksProcessedData?.dataSources.get(this.id)?.[datumIndex.index] : nodesProcessedData?.dataSources.get(this.id)?.[datumIndex.index]; const size = seriesDatum.size; let format; if (seriesDatum.type === 0 /* Link */) { 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"; // packages/ag-charts-enterprise/src/series/chord/chordModule.ts 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 }; } }; // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelModule.ts var import_ag_charts_community173 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/funnel/funnelThemes.ts var import_ag_charts_community166 = require("ag-charts-community"); var { ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE5, CARTESIAN_POSITION: CARTESIAN_POSITION3 }, ThemeSymbols: { DEFAULT_SHADOW_COLOUR } } = 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_COLOUR, 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 } } } }; // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelSeries.ts var import_ag_charts_community171 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/funnel/baseFunnelSeries.ts var import_ag_charts_community169 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/funnel/funnelConnector.ts var import_ag_charts_community167 = require("ag-charts-community"); var { lineDistanceSquared, BBox: BBox12, Path: Path9, ScenePathChangeDetection: ScenePathChangeDetection7 } = import_ag_charts_community167._ModuleSupport; var delta = 1e-6; function pointsEq([ax, ay], [bx, by]) { return Math.abs(ax - bx) <= delta && Math.abs(ay - by) <= delta; } 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( lineDistanceSquared(x, y, x0, y0, x1, y1, Infinity), lineDistanceSquared(x, y, x1, y1, x2, y2, Infinity), lineDistanceSquared(x, y, x2, y2, x3, y3, Infinity), lineDistanceSquared(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 width = Math.max(x0, x1, x2, x3) - x; const y = Math.min(y0, y1, y2, y3); const height = Math.max(y0, y1, y2, y3) - y; return new BBox12(x, y, width, height); } 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 start; let current; points.forEach((p) => { if (start != null && pointsEq(start, p) || current != null && pointsEq(current, p)) { return; } const [x, y] = p; if (start == null) { path.moveTo(x, y); } else { path.lineTo(x, y); } start ?? (start = p); current = p; }); path.closePath(); } }; __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x0", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y0", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x1", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y1", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x2", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y2", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "x3", 2); __decorateClass([ ScenePathChangeDetection7() ], FunnelConnector.prototype, "y3", 2); // packages/ag-charts-enterprise/src/series/funnel/funnelUtil.ts var import_ag_charts_community168 = require("ag-charts-community"); var { NODE_UPDATE_STATE_TO_PHASE_MAPPING } = 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_MAPPING[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 }; } // packages/ag-charts-enterprise/src/series/funnel/baseFunnelSeries.ts var { SeriesNodePickMode: SeriesNodePickMode4, SeriesZIndexMap, valueProperty: valueProperty7, keyProperty: keyProperty5, ChartAxisDirection: ChartAxisDirection20, updateLabelNode, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL3, LARGEST_KEY_INTERVAL, diff: diff3, fixNumericExtent: fixNumericExtent4, seriesLabelFadeInAnimation, resetMotion, resetLabelFn, animationValidation: animationValidation3, computeBarFocusBounds: computeBarFocusBounds3, ContinuousScale: ContinuousScale5, Group: Group10, Selection: Selection5, PointerEvents, motion: motion2, checkCrisp, 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: resetLabelFn } }); // @ts-expect-error xKey/yKey renamed this.NodeEvent = FunnelSeriesNodeEvent; this.connectorNodeGroup = this.contentGroup.appendChild( new Group10({ name: `${this.id}-series-connectorNodes`, zIndex: SeriesZIndexMap.BACKGROUND }) ); this.connectorSelection = Selection5.select( this.connectorNodeGroup, () => this.connectionFactory() ); this.connectorNodeGroup.pointerEvents = PointerEvents.None; } get pickModeAxis() { return "main-category"; } setSeriesIndex(index) { if (!super.setSeriesIndex(index)) return false; this.connectorNodeGroup.zIndex = [SeriesZIndexMap.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_INTERVAL] : [], ...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 = checkCrisp( 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: stroke2, 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 = stroke2 ?? 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, (text2) => { text2.pointerEvents = PointerEvents.None; }); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode(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); resetMotion([this.connectorSelection], resetConnectorSelectionsFn); } animateEmptyUpdateReady({ labelSelection }) { const { connectorSelection } = this; const isVertical = this.isVertical(); const mode = "normal"; const connectorFns = prepareConnectorAnimationFunctions(isVertical, mode); motion2.fromToMotion(this.id, "connectors", this.ctx.animationManager, [connectorSelection], connectorFns); seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection); } animateWaitingUpdateReady(data) { const { labelSelection: labelSelections } = data; this.ctx.animationManager.stopByAnimationGroupId(this.id); seriesLabelFadeInAnimation(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 stroke2 = strokes[datumIndex % strokes.length] ?? "black"; return { marker: { fill, fillOpacity, stroke: stroke2, 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); } }; // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelProperties.ts var import_ag_charts_community170 = require("ag-charts-community"); var { Label: Label4, AbstractBarSeriesProperties: AbstractBarSeriesProperties3, SeriesTooltip: SeriesTooltip5, AxisLabel: AxisLabel2, 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; } }; __decorateClass([ Validate59(UNION11(["before", "middle", "after"], "a placement")) ], ConeFunnelSeriesLabel.prototype, "placement", 2); __decorateClass([ Validate59(POSITIVE_NUMBER19) ], ConeFunnelSeriesLabel.prototype, "spacing", 2); var ConeFunnelSeriesStageLabel = class extends AxisLabel2 { }; __decorateClass([ 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(); } }; __decorateClass([ Validate59(STRING27) ], ConeFunnelProperties.prototype, "stageKey", 2); __decorateClass([ Validate59(STRING27) ], ConeFunnelProperties.prototype, "valueKey", 2); __decorateClass([ Validate59(COLOR_STRING_ARRAY3) ], ConeFunnelProperties.prototype, "fills", 2); __decorateClass([ Validate59(RATIO16) ], ConeFunnelProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate59(COLOR_STRING_ARRAY3) ], ConeFunnelProperties.prototype, "strokes", 2); __decorateClass([ Validate59(POSITIVE_NUMBER19) ], ConeFunnelProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate59(RATIO16) ], ConeFunnelProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate59(LINE_DASH9) ], ConeFunnelProperties.prototype, "lineDash", 2); __decorateClass([ Validate59(POSITIVE_NUMBER19) ], ConeFunnelProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate59(OBJECT27) ], ConeFunnelProperties.prototype, "label", 2); __decorateClass([ Validate59(OBJECT27) ], ConeFunnelProperties.prototype, "stageLabel", 2); __decorateClass([ Validate59(OBJECT27) ], ConeFunnelProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelUtil.ts function resetLineSelectionsFn(_node, { x, y, width, height, opacity }) { return { x1: x, y1: y, x2: x + width, y2: y + height, opacity }; } // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelSeries.ts var { formatValue, 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) => formatValue(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 stroke2 = strokes[datumIndex % strokes.length] ?? "black"; const { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.barStyle(); return { fill, fillOpacity, stroke: stroke2, strokeOpacity, strokeWidth, lineDash, lineDashOffset }; } }; ConeFunnelSeries.className = "ConeFunnelSeries"; ConeFunnelSeries.type = "cone-funnel"; // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelThemes.ts var import_ag_charts_community172 = require("ag-charts-community"); 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 } } } }; // packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelModule.ts 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) }; } }; // packages/ag-charts-enterprise/src/series/funnel/funnelSeries.ts var import_ag_charts_community175 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/funnel/funnelProperties.ts var import_ag_charts_community174 = require("ag-charts-community"); var { Label: Label5, DropShadow, 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 { }; __decorateClass([ 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; } }; __decorateClass([ Validate60(BOOLEAN27) ], FunnelDropOff.prototype, "enabled", 2); __decorateClass([ Validate60(COLOR_STRING13, { optional: true }) ], FunnelDropOff.prototype, "fill", 2); __decorateClass([ Validate60(RATIO17) ], FunnelDropOff.prototype, "fillOpacity", 2); __decorateClass([ Validate60(COLOR_STRING13, { optional: true }) ], FunnelDropOff.prototype, "stroke", 2); __decorateClass([ Validate60(POSITIVE_NUMBER20) ], FunnelDropOff.prototype, "strokeWidth", 2); __decorateClass([ Validate60(RATIO17) ], FunnelDropOff.prototype, "strokeOpacity", 2); __decorateClass([ Validate60(LINE_DASH10) ], FunnelDropOff.prototype, "lineDash", 2); __decorateClass([ 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 DropShadow().set({ enabled: false }); this.label = new FunnelSeriesLabel(); this.stageLabel = new FunnelSeriesStageLabel(); this.tooltip = new SeriesTooltip6(); } }; __decorateClass([ Validate60(STRING28) ], FunnelProperties.prototype, "stageKey", 2); __decorateClass([ Validate60(STRING28) ], FunnelProperties.prototype, "valueKey", 2); __decorateClass([ Validate60(COLOR_STRING_ARRAY4) ], FunnelProperties.prototype, "fills", 2); __decorateClass([ Validate60(RATIO17) ], FunnelProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate60(COLOR_STRING_ARRAY4) ], FunnelProperties.prototype, "strokes", 2); __decorateClass([ Validate60(POSITIVE_NUMBER20) ], FunnelProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate60(RATIO17) ], FunnelProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate60(LINE_DASH10) ], FunnelProperties.prototype, "lineDash", 2); __decorateClass([ Validate60(POSITIVE_NUMBER20) ], FunnelProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate60(RATIO17) ], FunnelProperties.prototype, "spacingRatio", 2); __decorateClass([ Validate60(FUNCTION10, { optional: true }) ], FunnelProperties.prototype, "itemStyler", 2); __decorateClass([ Validate60(OBJECT28) ], FunnelProperties.prototype, "dropOff", 2); __decorateClass([ Validate60(OBJECT28) ], FunnelProperties.prototype, "shadow", 2); __decorateClass([ Validate60(OBJECT28) ], FunnelProperties.prototype, "label", 2); __decorateClass([ Validate60(OBJECT28) ], FunnelProperties.prototype, "stageLabel", 2); __decorateClass([ Validate60(OBJECT28) ], FunnelProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/funnel/funnelSeries.ts var { ChartAxisDirection: ChartAxisDirection21, resetBarSelectionsFn, prepareBarAnimationFunctions, midpointStartingBarPosition, createDatumId: createDatumId6, formatValue: formatValue2, Rect: Rect4, motion: motion3, applyShapeStyle: applyShapeStyle2 } = import_ag_charts_community175._ModuleSupport; var FunnelSeries = class extends BaseFunnelSeries { constructor(moduleCtx) { super({ moduleCtx, animationResetFns: { datum: resetBarSelectionsFn } }); 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: stroke2, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.dropOff; return { fill, fillOpacity, stroke: stroke2, 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) => formatValue2(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 stroke2 = format.stroke ?? strokes[datumIndex % strokes.length] ?? "black"; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } 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: stroke2, 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 ); applyShapeStyle2(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 = prepareBarAnimationFunctions(midpointStartingBarPosition(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 = prepareBarAnimationFunctions(midpointStartingBarPosition(this.isVertical(), "fade")); motion3.fromToMotion( this.id, "datums", this.ctx.animationManager, [datumSelections], fns, (_, datum) => datum.xValue, dataDiff ); } }; FunnelSeries.className = "FunnelSeries"; FunnelSeries.type = "funnel"; // packages/ag-charts-enterprise/src/series/funnel/funnelModule.ts 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 }; } }; // packages/ag-charts-enterprise/src/series/heatmap/heatmapModule.ts var import_ag_charts_community181 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/heatmap/heatmapSeries.ts var import_ag_charts_community179 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/util/labelFormatter.ts var import_ag_charts_community176 = require("ag-charts-community"); 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_exports.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, text2, maxWidth, maxHeight, font2, textWrap, overflow) { const lines = TextWrapper5.wrapLines(text2, { maxWidth, maxHeight, font: font2, textWrap, overflow }); if (!lines.length) return; const lineHeight = getLineHeight(props, font2.fontSize); const { width } = CachedTextMeasurerPool4.measureLines(lines, { font: font2 }); return { width, lineHeight, text: lines.join("\n"), height: lines.length * lineHeight, fontSize: font2.fontSize }; } function clipLines(lines, { font: font2, lineHeight = TextUtils5.defaultLineHeight, maxWidth, maxHeight = Infinity }) { let height = lineHeight * lines.length; while (height > maxHeight) { if (lines.length === 1) return; lines.pop(); lines[lines.length - 1] = TextWrapper5.appendEllipsis(lines.at(-1)); height = lineHeight * lines.length; } const metrics = CachedTextMeasurerPool4.measureLines(lines, { font: font2 }); let text2, width; if (metrics.width > maxWidth) { const clippedLines = []; width = 0; for (const line of metrics.lineMetrics) { if (line.width > maxWidth) { if (!clippedLines.length) return; break; } clippedLines.push(line.text); width = Math.max(width, line.width); } text2 = TextWrapper5.appendEllipsis(clippedLines.join("\n")); } else { text2 = lines.join("\n"); width = metrics.width; } return { text: text2, width, height }; } // packages/ag-charts-enterprise/src/series/heatmap/heatmapSeriesProperties.ts var import_ag_charts_community178 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/util/autoSizedLabel.ts var import_ag_charts_community177 = require("ag-charts-community"); var { Validate: Validate61, NUMBER: NUMBER14, POSITIVE_NUMBER: POSITIVE_NUMBER21, TEXT_WRAP, OVERFLOW_STRATEGY } = 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"; } }; __decorateClass([ Validate61(TEXT_WRAP) ], BaseAutoSizedLabel.prototype, "wrapping", 2); __decorateClass([ Validate61(OVERFLOW_STRATEGY) ], BaseAutoSizedLabel.prototype, "overflowStrategy", 2); __decorateClass([ Validate61(POSITIVE_NUMBER21, { optional: true }) ], BaseAutoSizedLabel.prototype, "lineHeight", 2); __decorateClass([ Validate61(POSITIVE_NUMBER21, { optional: true }) ], BaseAutoSizedLabel.prototype, "minimumFontSize", 2); var AutoSizedLabel = class extends BaseAutoSizedLabel { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass([ Validate61(NUMBER14) ], AutoSizedLabel.prototype, "spacing", 2); var AutoSizedSecondaryLabel = class extends BaseAutoSizedLabel { }; // packages/ag-charts-enterprise/src/series/heatmap/heatmapSeriesProperties.ts var { CartesianSeriesProperties, 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_NUMBER22, RATIO: RATIO18, STRING: STRING29, TEXT_ALIGN: TEXT_ALIGN2, VERTICAL_ALIGN } = import_ag_charts_community178._ModuleSupport; var HeatmapSeriesProperties = class extends CartesianSeriesProperties { 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(); } }; __decorateClass([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "title", 2); __decorateClass([ Validate62(STRING29) ], HeatmapSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate62(STRING29) ], HeatmapSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate62(STRING29, { optional: true }) ], HeatmapSeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate62(AND5(COLOR_STRING_ARRAY5, ARRAY8.restrict({ minLength: 1 }))) ], HeatmapSeriesProperties.prototype, "colorRange", 2); __decorateClass([ Validate62(COLOR_STRING14, { optional: true }) ], HeatmapSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate62(RATIO18) ], HeatmapSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate62(POSITIVE_NUMBER22, { optional: true }) ], HeatmapSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate62(TEXT_ALIGN2) ], HeatmapSeriesProperties.prototype, "textAlign", 2); __decorateClass([ Validate62(VERTICAL_ALIGN) ], HeatmapSeriesProperties.prototype, "verticalAlign", 2); __decorateClass([ Validate62(POSITIVE_NUMBER22) ], HeatmapSeriesProperties.prototype, "itemPadding", 2); __decorateClass([ Validate62(FUNCTION11, { optional: true }) ], HeatmapSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate62(OBJECT29) ], HeatmapSeriesProperties.prototype, "label", 2); __decorateClass([ Validate62(OBJECT29) ], HeatmapSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/heatmap/heatmapSeries.ts var { SeriesNodePickMode: SeriesNodePickMode5, computeBarFocusBounds: computeBarFocusBounds4, getMissCount, valueProperty: valueProperty8, ChartAxisDirection: ChartAxisDirection22, DEFAULT_CARTESIAN_DIRECTION_KEYS, DEFAULT_CARTESIAN_DIRECTION_NAMES, createDatumId: createDatumId7, ColorScale, Rect: Rect5, PointerEvents: PointerEvents2, 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_KEYS, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES, pickModes: [SeriesNodePickMode5.NEAREST_NODE, SeriesNodePickMode5.EXACT_SHAPE_MATCH], pathsPerSeries: [], hasMarkers: false, hasHighlightedLabels: true }); this.properties = new HeatmapSeriesProperties(); this.NodeEvent = HeatmapSeriesNodeEvent; this.colorScale = new ColorScale(); } async processData(dataController) { const xAxis = this.axes[ChartAxisDirection22.X]; const yAxis = this.axes[ChartAxisDirection22.Y]; if (!xAxis || !yAxis || !this.properties.isValid() || !this.data?.length) { return; } const { xKey, yKey, colorRange, colorKey } = this.properties; const xScale = this.axes[ChartAxisDirection22.X]?.scale; const yScale = this.axes[ChartAxisDirection22.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 = getMissCount(this, processedData.defs.values[colorDataIdx].missing); const colorDataMissing = dataCount === 0 || dataCount === missCount; return !colorDataMissing; } xCoordinateRange(xValue, pixelSize) { const xScale = this.axes[ChartAxisDirection22.X].scale; const xOffset = pixelSize * (xScale.bandwidth ?? 0) / 2; const x = xScale.convert(xValue) + xOffset; const width = pixelSize * (xScale.bandwidth ?? 10); return [x, x + width]; } yCoordinateRange(yValues, pixelSize) { const yScale = this.axes[ChartAxisDirection22.Y].scale; const yOffset = pixelSize * (yScale.bandwidth ?? 0) / 2; const y = yScale.convert(yValues[0]) + yOffset; const height = pixelSize * (yScale.bandwidth ?? 10); return [y, y + height]; } getSeriesDomain(direction) { const { dataModel, processedData } = this; if (!dataModel || !processedData) return []; if (direction === ChartAxisDirection22.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[ChartAxisDirection22.X]; const yAxis = axes[ChartAxisDirection22.Y]; if (!(data && dataModel && processedData && visible && xAxis && yAxis)) return; if (xAxis.type !== "category" || yAxis.type !== "category") { logger_exports.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 width = xScale.bandwidth ?? 10; const height = yScale.bandwidth ?? 10; const textAlignFactor = (width - 2 * itemPadding) * textAlignFactors[textAlign]; const verticalAlignFactor = (height - 2 * itemPadding) * verticalAlignFactors[verticalAlign]; const sizeFittingHeight = () => ({ width, height, 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, height, midPoint: { x, y }, missing: colorValue == null }); if (labels?.label != null) { const { text: text2, fontSize, lineHeight, height: labelHeight } = labels.label; const { fontStyle, fontFamily, fontWeight, color } = this.properties.label; const lx = point.x + textAlignFactor * (width - 2 * itemPadding); const ly = point.y + verticalAlignFactor * (height - 2 * itemPadding) - (labels.height - labelHeight) * 0.5; labelData.push({ series: this, itemId: yKey, datum, datumIndex, text: text2, 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[ChartAxisDirection22.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, height } = nodeDatum; const overrides = this.getItemStyleOverrides( String(datumIndex), datum, colorValue, style, isDatumHighlighted ); rect.crisp = crisp; rect.x = Math.floor(point.x - width / 2); rect.y = Math.floor(point.y - height / 2); rect.width = Math.ceil(width); rect.height = Math.ceil(height); 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((text2, datum) => { text2.text = datum.text; text2.fontSize = datum.fontSize; text2.lineHeight = datum.lineHeight; text2.fontStyle = datum.fontStyle; text2.fontFamily = datum.fontFamily; text2.fontWeight = datum.fontWeight; text2.fill = datum.color; text2.textAlign = datum.textAlign; text2.textBaseline = datum.verticalAlign; text2.x = datum.x; text2.y = datum.y; text2.pointerEvents = PointerEvents2.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[ChartAxisDirection22.X]; const yAxis = axes[ChartAxisDirection22.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, height, midPoint } = datum; const focusRect = { x: midPoint.x - width / 2, y: midPoint.y - height / 2, width, height }; return computeBarFocusBounds4(this, focusRect); } }; HeatmapSeries.className = "HeatmapSeries"; HeatmapSeries.type = "heatmap"; // packages/ag-charts-enterprise/src/series/heatmap/heatmapThemes.ts var import_ag_charts_community180 = require("ag-charts-community"); 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 } }; // packages/ag-charts-enterprise/src/series/heatmap/heatmapModule.ts var { ThemeSymbols: { DEFAULT_DIVERGING_SERIES_COLOR_RANGE, DEFAULT_BACKGROUND_COLOUR: DEFAULT_BACKGROUND_COLOUR2 }, 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_RANGE); const defaultBackgroundColor = themeTemplateParameters.get(DEFAULT_BACKGROUND_COLOUR2); 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]] }; } }; // packages/ag-charts-enterprise/src/series/line/lineModule.ts var import_ag_charts_community184 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/line/lineSeries.ts var import_ag_charts_community183 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/line/lineAggregation.ts var import_ag_charts_community182 = require("ag-charts-community"); 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_MIN] || datumIndex === indexData[aggIndex + X_MAX] || datumIndex === indexData[aggIndex + Y_MIN] || datumIndex === indexData[aggIndex + Y_MAX]; } 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; } // packages/ag-charts-enterprise/src/series/line/lineSeries.ts var { ChartAxisDirection: ChartAxisDirection23, ContinuousScale: ContinuousScale6, OrdinalTimeScale: OrdinalTimeScale4 } = import_ag_charts_community183._ModuleSupport; var LineSeries = 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); } }; // packages/ag-charts-enterprise/src/series/line/lineModule.ts var { LineSeriesModule } = import_ag_charts_community184._ModuleSupport; var LineModule = { ...LineSeriesModule, type: "series", optionsKey: "series[]", packageType: "enterprise", chartTypes: ["cartesian"], identifier: "line", moduleFactory: (ctx) => new LineSeries(ctx) }; // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeModule.ts var import_ag_charts_community193 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/gauge-util/defaultColorStops.ts var import_ag_charts_community185 = require("ag-charts-community"); var { ColorScale: ColorScale2 } = import_ag_charts_community185._ModuleSupport; function defaultColorStops(colors) { if (colors == null) return []; const colorScale = new ColorScale2(); colorScale.domain = [0, 1]; colorScale.range = colors; const stopCount = 5; return Array.from({ length: 5 }, (_, i) => { return colorScale.convert(i / (stopCount - 1)); }); } // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeSeries.ts var import_ag_charts_community192 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/gauge-util/datumUnion.ts 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 first = 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 = first.datum; nodeUpdater(this.node, first, last); } } }; // packages/ag-charts-enterprise/src/series/gauge-util/label.ts 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); } // packages/ag-charts-enterprise/src/series/gauge-util/lineMarker.ts var import_ag_charts_community186 = require("ag-charts-community"); function lineMarker({ path, x, y, size }) { path.moveTo(x, y - size / 2); path.lineTo(x, y + size / 2); } // packages/ag-charts-enterprise/src/series/gauge-util/pick.ts var import_ag_charts_community187 = require("ag-charts-community"); var { clamp: clamp8 } = import_ag_charts_community187._ModuleSupport; function pickGaugeNearestDatum(self, point) { const it = iterate(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 }; } } } // packages/ag-charts-enterprise/src/series/gauge-util/properties.ts var import_ag_charts_community188 = require("ag-charts-community"); var { MARKER_SHAPE, UNION: UNION13, OR: OR5 } = import_ag_charts_community188._ModuleSupport; var FILL_MODE = UNION13(["continuous", "discrete"], "a fill mode"); var TARGET_MARKER_SHAPE = OR5(MARKER_SHAPE, UNION13(["line"], "a marker shape")); var CORNER_MODE = UNION13(["container", "item"], "a corner mode"); function parseUnknownGaugeNodeDatum(nodeDatum) { let value; let text2; if (typeof nodeDatum.value === "number") value = nodeDatum.value; if (typeof nodeDatum.text === "string") text2 = nodeDatum.text; return { value, text: text2 }; } // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeSeriesProperties.ts var import_ag_charts_community190 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/gauge-util/segmentation.ts var import_ag_charts_community189 = require("ag-charts-community"); var { BaseProperties: BaseProperties24, Validate: Validate63, OBJECT: OBJECT30, BOOLEAN: BOOLEAN28, NUMBER: NUMBER15, NUMBER_ARRAY } = import_ag_charts_community189._ModuleSupport; var GaugeSegmentationIntervalProperties = class extends BaseProperties24 { getSegments(scale, maxTicks) { const { values, step, count } = this; const d0 = Math.min(...scale.domain); const d1 = Math.max(...scale.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 = scale.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_exports.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; } }; __decorateClass([ Validate63(NUMBER_ARRAY, { optional: true }) ], GaugeSegmentationIntervalProperties.prototype, "values", 2); __decorateClass([ Validate63(NUMBER15, { optional: true }) ], GaugeSegmentationIntervalProperties.prototype, "step", 2); __decorateClass([ 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; } }; __decorateClass([ Validate63(BOOLEAN28) ], GaugeSegmentationProperties.prototype, "enabled", 2); __decorateClass([ Validate63(OBJECT30) ], GaugeSegmentationProperties.prototype, "interval", 2); __decorateClass([ Validate63(NUMBER15) ], GaugeSegmentationProperties.prototype, "spacing", 2); // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeSeriesProperties.ts var { BaseProperties: BaseProperties25, SeriesTooltip: SeriesTooltip8, SeriesProperties: SeriesProperties2, 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: 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_PLACEMENT = UNION14( [ "inside-start", "outside-start", "inside-end", "outside-end", "inside-center", "bar-inside", "bar-inside-end", "bar-outside-end", "bar-end" ], "an placement" ); var DIRECTION = UNION14(["horizontal", "vertical"], "an orientation"); var LinearGaugeDefaultTargetLabelProperties = class extends Label6 { }; __decorateClass([ Validate64(NUMBER16, { optional: true }) ], LinearGaugeDefaultTargetLabelProperties.prototype, "spacing", 2); var LinearGaugeTargetProperties = class extends BaseProperties25 { constructor() { super(...arguments); this.value = 0; this.label = new LinearGaugeDefaultTargetLabelProperties(); } }; __decorateClass([ Validate64(STRING30, { optional: true }) ], LinearGaugeTargetProperties.prototype, "text", 2); __decorateClass([ Validate64(NUMBER16) ], LinearGaugeTargetProperties.prototype, "value", 2); __decorateClass([ Validate64(TARGET_MARKER_SHAPE, { optional: true }) ], LinearGaugeTargetProperties.prototype, "shape", 2); __decorateClass([ Validate64(TARGET_PLACEMENT, { optional: true }) ], LinearGaugeTargetProperties.prototype, "placement", 2); __decorateClass([ Validate64(NUMBER16, { optional: true }) ], LinearGaugeTargetProperties.prototype, "spacing", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeTargetProperties.prototype, "size", 2); __decorateClass([ Validate64(NUMBER16, { optional: true }) ], LinearGaugeTargetProperties.prototype, "rotation", 2); __decorateClass([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeTargetProperties.prototype, "fill", 2); __decorateClass([ Validate64(RATIO19, { optional: true }) ], LinearGaugeTargetProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeTargetProperties.prototype, "stroke", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeTargetProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate64(RATIO19, { optional: true }) ], LinearGaugeTargetProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate64(LINE_DASH11, { optional: true }) ], LinearGaugeTargetProperties.prototype, "lineDash", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeTargetProperties.prototype, "lineDashOffset", 2); __decorateClass([ 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; } }; __decorateClass([ Validate64(BOOLEAN29) ], LinearGaugeBarProperties.prototype, "enabled", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23, { optional: true }) ], LinearGaugeBarProperties.prototype, "thickness", 2); __decorateClass([ Validate64(RATIO19) ], LinearGaugeBarProperties.prototype, "thicknessRatio", 2); __decorateClass([ Validate64(OBJECT_ARRAY) ], LinearGaugeBarProperties.prototype, "fills", 2); __decorateClass([ Validate64(FILL_MODE) ], LinearGaugeBarProperties.prototype, "fillMode", 2); __decorateClass([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeBarProperties.prototype, "fill", 2); __decorateClass([ Validate64(RATIO19) ], LinearGaugeBarProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate64(COLOR_STRING15) ], LinearGaugeBarProperties.prototype, "stroke", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeBarProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate64(RATIO19) ], LinearGaugeBarProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate64(LINE_DASH11) ], LinearGaugeBarProperties.prototype, "lineDash", 2); __decorateClass([ 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"; } }; __decorateClass([ Validate64(OBJECT_ARRAY) ], LinearGaugeScaleProperties.prototype, "fills", 2); __decorateClass([ Validate64(FILL_MODE) ], LinearGaugeScaleProperties.prototype, "fillMode", 2); __decorateClass([ Validate64(COLOR_STRING15, { optional: true }) ], LinearGaugeScaleProperties.prototype, "fill", 2); __decorateClass([ Validate64(RATIO19) ], LinearGaugeScaleProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate64(COLOR_STRING15) ], LinearGaugeScaleProperties.prototype, "stroke", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeScaleProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate64(RATIO19) ], LinearGaugeScaleProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate64(LINE_DASH11) ], LinearGaugeScaleProperties.prototype, "lineDash", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeScaleProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate64(COLOR_STRING15) ], LinearGaugeScaleProperties.prototype, "defaultFill", 2); var LinearGaugeLabelProperties = class extends AutoSizedLabel { constructor() { super(...arguments); this.placement = "inside-center"; this.avoidCollisions = true; } }; __decorateClass([ Validate64(STRING30, { optional: true }) ], LinearGaugeLabelProperties.prototype, "text", 2); __decorateClass([ Validate64(LABEL_PLACEMENT) ], LinearGaugeLabelProperties.prototype, "placement", 2); __decorateClass([ Validate64(BOOLEAN29) ], LinearGaugeLabelProperties.prototype, "avoidCollisions", 2); var LinearGaugeSeriesProperties = class extends SeriesProperties2 { 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(); } }; __decorateClass([ Validate64(NUMBER16) ], LinearGaugeSeriesProperties.prototype, "value", 2); __decorateClass([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "segmentation", 2); __decorateClass([ Validate64(COLOR_STRING_ARRAY6) ], LinearGaugeSeriesProperties.prototype, "defaultColorRange", 2); __decorateClass([ Validate64(OBJECT_ARRAY) ], LinearGaugeSeriesProperties.prototype, "targets", 2); __decorateClass([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "defaultTarget", 2); __decorateClass([ Validate64(DIRECTION) ], LinearGaugeSeriesProperties.prototype, "direction", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeSeriesProperties.prototype, "thickness", 2); __decorateClass([ Validate64(POSITIVE_NUMBER23) ], LinearGaugeSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate64(CORNER_MODE) ], LinearGaugeSeriesProperties.prototype, "cornerMode", 2); __decorateClass([ Validate64(NUMBER16) ], LinearGaugeSeriesProperties.prototype, "margin", 2); __decorateClass([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "scale", 2); __decorateClass([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "bar", 2); __decorateClass([ Validate64(FUNCTION12, { optional: true }) ], LinearGaugeSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "label", 2); __decorateClass([ Validate64(OBJECT31) ], LinearGaugeSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeUtil.ts var import_ag_charts_community191 = require("ag-charts-community"); 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 width = Math.max(Math.abs(x1 - x0) - 2 * horizontalInset, 0); const height = Math.max(Math.abs(y1 - y0) - 2 * verticalInset, 0); return { x, y, width, height }; } 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, height } = 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 + width, clipX + clipWidth); clipY1 = Math.min(y + height, 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, height } = datumRect(datum); const clipBBox = computeClipBBox(datum); const visible = clipBBoxVisibility(datum, clipBBox); return { x, y, width, height, 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, bar } = bboxes; const { padding, horizontal } = opts; selection.each((label, labelDatum) => { const labelText = getLabelText(series, labelDatum, datumOverrides?.label); const sizeFittingHeight = () => ({ width: scale.width, height: scale.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 font2 = { fontSize: labelDatum.fontSize, fontStyle: labelDatum.fontStyle, fontWeight: labelDatum.fontWeight, fontFamily: labelDatum.fontFamily, lineHeight: labelDatum.lineHeight }; const { width, height } = CachedTextMeasurerPool5.measureText(labelText, { font: font2 }); layout = { text: labelText, fontSize: labelDatum.fontSize, lineHeight: getLineHeight(labelDatum, labelDatum.fontSize), width, height }; } if (layout == null) { label.visible = false; return; } const scale0 = horizontal ? scale.x : scale.y + scale.height; const scale1 = horizontal ? scale.x + scale.width : scale.y; const bar0 = horizontal ? bar.x : bar.y + bar.height; const bar1 = horizontal ? bar.x + bar.width : bar.y; const offset = labelDatum.spacing * (horizontal ? 1 : -1); let bounds0; let bounds1; let s; let align; switch (labelDatum.placement) { case "outside-start": bounds0 = -Infinity; bounds1 = Infinity; s = scale0 - offset; align = "Before" /* Before */; break; case "outside-end": bounds0 = -Infinity; bounds1 = Infinity; s = scale1 + offset; align = "After" /* After */; break; case "inside-start": bounds0 = scale0; bounds1 = bar1; s = scale0 + offset; align = "After" /* After */; break; case "inside-end": bounds0 = bar1; bounds1 = scale1; s = scale1 - offset; align = "Before" /* Before */; break; case "inside-center": bounds0 = scale0; bounds1 = scale1; s = (scale0 + scale1) / 2; align = "Center" /* Center */; break; case "bar-inside": bounds0 = bar0; bounds1 = bar1; s = (bar0 + bar1) / 2; align = "Center" /* Center */; break; case "bar-inside-end": bounds0 = bar0; bounds1 = bar1; s = bar1 - offset; align = "Before" /* Before */; break; case "bar-outside-end": bounds0 = bar1; bounds1 = scale1; s = bar1 + offset; align = "After" /* After */; break; case "bar-end": bounds0 = -Infinity; bounds1 = Infinity; s = bar1; align = "Center" /* Center */; break; } const x = horizontal ? s : scale.x + scale.width / 2; const y = horizontal ? scale.y + scale.height / 2 : s; let s0; let s1; if (horizontal) { s0 = x + horizontalAlignFactors[align] * layout.width; s1 = s0 + layout.width; } else { s0 = y + verticalAlignFactors2[align] * 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[align] : "center"; label.textBaseline = horizontal ? "middle" : verticalTextBaselines[align]; label.x = x; label.y = y; }); } // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeSeries.ts var { fromToMotion, resetMotion: resetMotion2, SeriesNodePickMode: SeriesNodePickMode6, StateMachine: StateMachine12, createDatumId: createDatumId8, ChartAxisDirection: ChartAxisDirection24, CachedTextMeasurerPool: CachedTextMeasurerPool6, toRadians: toRadians5, BBox: BBox14, Group: Group11, PointerEvents: PointerEvents3, Selection: Selection6, Rect: Rect6, Text: Text2, LinearGradient: LinearGradient2, Marker: Marker2, easing, getColorStops } = 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, Text2); this.labelSelection = Selection6.select( this.itemLabelGroup, Text2 ); 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 font2 = label.getFont(); const linesOrTicks = lines ?? ticks.map((tick) => getLabelText(this, this.labelDatum(label, tick)) ?? ""); size = linesOrTicks.reduce((accum, text2) => { const { width } = CachedTextMeasurerPool6.measureText(text2, { font: font2 }); return Math.max(accum, width); }, 0); } return factor * (label.spacing + size); } get hasData() { return true; } nodeFactory() { const rect = new Rect6(); rect.crisp = true; return rect; } markerFactory() { return new Marker2(); } 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: range2 } = mainAxis.scale; const length = range2[1] - range2[0]; const stops = getColorStops(fills, defaultColorRange, domain, fillMode); return new LinearGradient2( "oklch", stops, horizontal ? 90 : 0, new BBox14(originX, originY, horizontal ? length : thickness, horizontal ? thickness : length) ); } getTargets() { const { properties } = this; const defaultTarget = properties.defaultTarget; return Array.from(properties.targets).map((target) => { const { text: text2 = 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: stroke2 = 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: text2, value, shape, placement, spacing, size, rotation, fill, fillOpacity, stroke: stroke2, 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 offset = size / 2 + spacing; let textAlign; let textBaseline; let offsetX = 0; let offsetY = 0; if (this.horizontal) { textAlign = "center"; if (placement === "after") { textBaseline = "top"; offsetY = offset; } else { textBaseline = "bottom"; offsetY = -offset; } } else { textBaseline = "middle"; if (placement === "before") { textAlign = "right"; offsetX = -offset; } else { textAlign = "left"; offsetX = offset; } } return { offsetX, offsetY, fill, textAlign, textBaseline, fontStyle, fontWeight, fontSize, fontFamily, lineHeight }; } labelDatum(label, value) { const { placement, avoidCollisions, spacing, text: text2, color: fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, wrapping, overflowStrategy, formatter = (params) => this.formatLabel(params.value) } = label; return { placement, avoidCollisions, spacing, text: text2, 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, 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 = scale.fill ?? (bar.enabled && scale.fills.length === 0 ? scale.defaultFill : void 0) ?? this.createLinearGradient(scale.fills, scale.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 /* Node */, 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 /* Node */, 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 /* Node */, 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 /* Node */, 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: text2, shape, size, fill, fillOpacity, stroke: stroke2, 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 /* Target */, index: i }, type: 1 /* Target */, value: targetValue, text: text2, x: targetPoint.x, y: targetPoint.y, shape, size, rotation: targetRotation, fill, fillOpacity, stroke: stroke2, 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 /* Target */) { 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: stroke2, 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 = stroke2; 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, first, last) => { node.pointerEvents = import_ag_charts_community192._ModuleSupport.PointerEvents.None; node.clipBBox ?? (node.clipBBox = new BBox14(NaN, NaN, NaN, NaN)); node.x = first.x; node.y = first.y; node.clipBBox.x = first.clipBBox?.x ?? first.x; node.clipBBox.y = first.clipBBox?.y ?? first.y; if (this.properties.direction === "horizontal") { node.height = node.clipBBox.height = last.height; node.width = last === first ? last.width : last.x + last.width; node.clipBBox.width = node.width - (last.width - (last.clipBBox?.width ?? last.width)); node.topLeftCornerRadius = first.topLeftCornerRadius; node.bottomLeftCornerRadius = first.bottomLeftCornerRadius; node.topRightCornerRadius = last.topRightCornerRadius; node.bottomRightCornerRadius = last.bottomRightCornerRadius; } else { node.width = node.clipBBox.width = last.width; node.height = last === first ? last.height : last.x + last.height; node.clipBBox.height = node.height - (last.height - (last.clipBBox?.height ?? last.height)); node.topLeftCornerRadius = first.topLeftCornerRadius; node.topRightCornerRadius = first.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 } = this.properties; const { fillOpacity, stroke: stroke2, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = scale; scaleSelection.each((rect, datum) => { const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, fill } = datum; rect.fill = fill; rect.fillOpacity = fillOpacity; rect.stroke = stroke2; 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: stroke2, 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 ?? stroke2; 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: text2 } = 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 = text2; 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 width = Math.abs(x1 - x0); const height = 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, height); } else { const yValue = yAxis.scale.convert(value); barBBox = new BBox14(x, yValue, width, height - yValue); } const bboxes = { scale: new BBox14(x, y, width, height), bar: barBBox }; const { margin: padding } = this.properties; formatLinearGaugeLabels(this, labelSelection, { padding, horizontal }, bboxes, datum); } resetAllAnimation() { this.ctx.animationManager.stopByAnimationGroupId(this.id); resetMotion2([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); fromToMotion(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId); fromToMotion(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); fromToMotion(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: text2 = properties.label.text } = parseUnknownGaugeNodeDatum(nodeDatum); return tooltip.formatTooltip( { data: [{ label: text2, 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"; // packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeModule.ts var { ThemeSymbols: { DEFAULT_HIERARCHY_FILLS, DEFAULT_GAUGE_SERIES_COLOR_RANGE }, 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_RANGE); const hierarchyFills = themeTemplateParameters.get(DEFAULT_HIERARCHY_FILLS); const colorRange = userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]]; return { scale: { defaultFill: hierarchyFills?.[1], stroke: hierarchyFills?.[2] }, defaultColorRange: defaultColorStops(colorRange) }; } }; // packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundModule.ts var import_ag_charts_community200 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-util/mapThemeDefaults.ts 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" } }; // packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeries.ts var import_ag_charts_community199 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-util/geoGeometry.ts var import_ag_charts_community195 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-util/lineStringUtil.ts var delta2 = 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) < delta2) { 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 distance = Math.hypot(x1 - x0, y1 - y0); totalDistance += distance; 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 ratio = (targetDistance - totalDistance) / segmentDistance; const point = [x0 + (x1 - x0) * ratio, y0 + (y1 - y0) * ratio]; const angle = Math.atan2(y1 - y0, x1 - x0); return { point, angle }; } totalDistance = nextDistance; x0 = x1; y0 = y1; } } // packages/ag-charts-enterprise/src/series/map-util/bboxUtil.ts var import_ag_charts_community194 = require("ag-charts-community"); var { LonLatBBox } = import_ag_charts_community194._ModuleSupport; function extendBbox(into, lon0, lat0, lon1, lat1) { if (into == null) { into = new LonLatBBox(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; } // packages/ag-charts-enterprise/src/series/map-util/polygonUtil.ts 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); } // packages/ag-charts-enterprise/src/series/map-util/geoGeometry.ts 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 /* All */; // Keep non-filled shapes separate so we don't fill them 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 distance = this.geometryDistance(projectedGeometry, x, y); return distance > 0 ? distance * distance : 0; } geometryDistance(geometry, x, y) { const { renderMode, strokeWidth } = this; const drawPolygons = (renderMode & 1 /* Polygons */) !== 0; const drawLines = (renderMode & 2 /* Lines */) !== 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 /* Polygons */) !== 0; const drawLines = (renderMode & 2 /* Lines */) !== 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 end = isClosed ? coordinates.length - 1 : coordinates.length; for (let i = 0; i < end; 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; } }; __decorateClass([ ScenePathChangeDetection8() ], GeoGeometry.prototype, "projectedGeometry", 2); __decorateClass([ ScenePathChangeDetection8() ], GeoGeometry.prototype, "renderMode", 2); // packages/ag-charts-enterprise/src/series/map-util/geometryUtil.ts 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 area = Math.abs(bbox.lat1 - bbox.lat0) * Math.abs(bbox.lon1 - bbox.lon0); if (maxArea == null || area > maxArea) { maxArea = area; 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 area = Math.abs(bbox.lat1 - bbox.lat0) * Math.abs(bbox.lon1 - bbox.lon0); if (maxArea == null || area > maxArea) { maxArea = area; 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 length = lineStringLength(lineString); if (length == null) return; if (maxLength == null || length > maxLength) { maxLength = length; maxLineString = lineString; } }); return maxLineString; } case "MultiLineString": { let maxLength = 0; let maxLineString; geometry.coordinates.forEach((lineString) => { const length = lineStringLength(lineString); if (length > maxLength) { maxLength = length; 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 /* Polygon */) !== 0; case "MultiLineString": case "LineString": return (type & 2 /* LineString */) !== 0; case "MultiPoint": case "Point": return (type & 4 /* Point */) !== 0; } } function projectGeometry(geometry, scale) { switch (geometry.type) { case "GeometryCollection": return { type: "GeometryCollection", geometries: geometry.geometries.map((g) => projectGeometry(g, scale)) }; case "Polygon": return { type: "Polygon", coordinates: projectPolygon(geometry.coordinates, scale) }; case "MultiPolygon": return { type: "MultiPolygon", coordinates: projectMultiPolygon(geometry.coordinates, scale) }; case "MultiLineString": return { type: "MultiLineString", coordinates: projectPolygon(geometry.coordinates, scale) }; case "LineString": return { type: "LineString", coordinates: projectLineString(geometry.coordinates, scale) }; case "MultiPoint": return { type: "MultiPoint", coordinates: projectLineString(geometry.coordinates, scale) }; case "Point": return { type: "Point", coordinates: scale.convert(geometry.coordinates) }; } } function projectMultiPolygon(multiPolygon, scale) { return multiPolygon.map((polygon) => projectPolygon(polygon, scale)); } function projectPolygon(polygon, scale) { return polygon.map((lineString) => projectLineString(lineString, scale)); } function projectLineString(lineString, scale) { return lineString.map((lonLat) => scale.convert(lonLat)); } // packages/ag-charts-enterprise/src/series/map-util/topologySeries.ts var import_ag_charts_community196 = require("ag-charts-community"); 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]; } }; // packages/ag-charts-enterprise/src/series/map-util/validation.ts var import_ag_charts_community197 = require("ag-charts-community"); function isValidCoordinate(v) { return Array.isArray(v) && v.length >= 2 && v.every(isFiniteNumber); } function isValidCoordinates(v) { return Array.isArray(v) && v.length >= 2 && v.every(isValidCoordinate); } var delta3 = 1e-3; function hasSameStartEndPoint(c) { return Math.abs(c[0][0] - c[c.length - 1][0]) < delta3 && Math.abs(c[0][1] - c[c.length - 1][1]) < delta3; } 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"); // packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeriesProperties.ts var import_ag_charts_community198 = require("ag-charts-community"); 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(); } }; __decorateClass([ Validate65(GEOJSON_OBJECT, { optional: true }) ], MapLineBackgroundSeriesProperties.prototype, "topology", 2); __decorateClass([ Validate65(COLOR_STRING16) ], MapLineBackgroundSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate65(RATIO20) ], MapLineBackgroundSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate65(POSITIVE_NUMBER24) ], MapLineBackgroundSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate65(LINE_DASH12) ], MapLineBackgroundSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate65(POSITIVE_NUMBER24) ], MapLineBackgroundSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate65(OBJECT32) ], MapLineBackgroundSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeries.ts 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 /* ShapeLineBackground */, index, 0]; this.highlightGroup.zIndex = [0 /* ShapeLineBackground */, index, 1]; return true; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 2 /* Lines */; 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_exports.warnOnce(`no topology was provided for [MapShapeBackgroundSeries]; nothing will be rendered.`); } } createNodeData() { const { id: seriesId, topology, scale } = this; if (topology == null) return; const nodeData = []; const labelData = []; topology.features.forEach((feature, index) => { const { geometry } = feature; const projectedGeometry = geometry != null && scale != null ? projectGeometry(geometry, scale) : 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: stroke2, 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 = stroke2; 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"; __decorateClass([ Validate66(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapLineBackgroundSeries.prototype, "_chartTopology", 2); // packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundModule.ts var { DEFAULT_HIERARCHY_STROKES } = 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_STROKES)?.[1] }; } }; // packages/ag-charts-enterprise/src/series/map-line/mapLineModule.ts var import_ag_charts_community203 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-line/mapLineSeries.ts var import_ag_charts_community202 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-util/mapUtil.ts 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; } // packages/ag-charts-enterprise/src/series/map-line/mapLineSeriesProperties.ts var import_ag_charts_community201 = require("ag-charts-community"); var { AND: AND6, ARRAY: ARRAY9, COLOR_STRING: COLOR_STRING17, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY7, FUNCTION: FUNCTION13, LINE_DASH: LINE_DASH13, NUMBER_ARRAY: NUMBER_ARRAY2, 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(); } }; __decorateClass([ Validate67(GEOJSON_OBJECT, { optional: true }) ], MapLineSeriesProperties.prototype, "topology", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "title", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "legendItemName", 2); __decorateClass([ Validate67(STRING31) ], MapLineSeriesProperties.prototype, "idKey", 2); __decorateClass([ Validate67(STRING31) ], MapLineSeriesProperties.prototype, "topologyIdKey", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "idName", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "sizeKey", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate67(STRING31, { optional: true }) ], MapLineSeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate67(NUMBER_ARRAY2, { optional: true }) ], MapLineSeriesProperties.prototype, "sizeDomain", 2); __decorateClass([ Validate67(AND6(COLOR_STRING_ARRAY7, ARRAY9.restrict({ minLength: 1 })), { optional: true }) ], MapLineSeriesProperties.prototype, "colorRange", 2); __decorateClass([ Validate67(POSITIVE_NUMBER25, { optional: true }) ], MapLineSeriesProperties.prototype, "maxStrokeWidth", 2); __decorateClass([ Validate67(COLOR_STRING17) ], MapLineSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate67(RATIO21) ], MapLineSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate67(POSITIVE_NUMBER25) ], MapLineSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate67(LINE_DASH13) ], MapLineSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate67(POSITIVE_NUMBER25) ], MapLineSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate67(FUNCTION13, { optional: true }) ], MapLineSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate67(OBJECT33) ], MapLineSeriesProperties.prototype, "label", 2); __decorateClass([ Validate67(OBJECT33) ], MapLineSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/map-line/mapLineSeries.ts var { getMissCount: getMissCount2, createDatumId: createDatumId10, SeriesNodePickMode: SeriesNodePickMode8, valueProperty: valueProperty9, CachedTextMeasurerPool: CachedTextMeasurerPool7, Validate: Validate68, ColorScale: ColorScale3, LinearScale: LinearScale4, Selection: Selection8, Text: Text3, Transformable: Transformable2 } = 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 /* ShapeLine */, index]; this.highlightGroup.zIndex = [2 /* ShapeLineHighlight */, 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 /* Lines */; 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_exports.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 = getMissCount2(this, processedData.defs.values[colorIdx].missing); const colorDataMissing = dataCount === 0 || dataCount === missCount; return !colorDataMissing; } getLabelDatum(datum, labelValue, projectedGeometry, font2) { 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: font2 }); const labelCenter = lineStringCenter(lineString); if (labelCenter == null) return; const [x, y] = labelCenter.point; const { width, height } = labelSize; return { point: { x, y, size: 0 }, label: { width, height, text: labelText }, anchor: void 0, placement: void 0 }; } createNodeData() { const { id: seriesId, dataModel, processedData, sizeScale, properties, scale } = 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 font2 = 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 && scale != null ? projectGeometry(geometry, scale) : 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, font2); 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_exports.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, (text2) => { text2.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, height, text: text2 }) => { label.visible = true; label.x = x + width / 2; label.y = y + height / 2; label.text = text2; 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 distanceSquared = node.distanceSquared(x, y); if (distanceSquared < minDistanceSquared) { minDistanceSquared = distanceSquared; 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 center = lineString != null ? lineStringCenter(lineString)?.point : void 0; const point = center != null ? { x: center[0], y: center[1] } : void 0; this._previousDatumMidPoint = { datum, point }; return point; } legendItemSymbol(datumIndex) { const { dataModel, processedData, properties } = this; const { strokeWidth, strokeOpacity, lineDash } = properties; let { stroke: stroke2 } = properties; if (datumIndex != null && this.isColorScaleValid()) { const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData); const colorValue = colorValues[datumIndex]; stroke2 = 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: stroke2, 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 ? Transformable2.toCanvas(this.contentGroup, geometry.getBBox()) : void 0; } }; MapLineSeries.className = "MapLineSeries"; MapLineSeries.type = "map-line"; __decorateClass([ Validate68(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapLineSeries.prototype, "_chartTopology", 2); // packages/ag-charts-enterprise/src/series/map-line/mapLineModule.ts var { DEFAULT_DIVERGING_SERIES_COLOR_RANGE: DEFAULT_DIVERGING_SERIES_COLOR_RANGE2 } = 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_RANGE2); const { fills } = takeColors(colorsCount); return { colorRange: userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]], stroke: fill }; } }; // packages/ag-charts-enterprise/src/series/map-marker/mapMarkerModule.ts var import_ag_charts_community206 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeries.ts var import_ag_charts_community205 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-util/linkedList.ts var insertManySorted = (list, items, cmp) => { let head = list; let current = head; for (const value of items) { if (head == null || cmp(head.value, value) > 0) { head = { value, next: head }; current = head; } else { current = current; while (current.next != null && cmp(current.next.value, value) <= 0) { current = current.next; } current.next = { value, next: current.next }; } } return head; }; // packages/ag-charts-enterprise/src/series/map-util/polygonPointSearch.ts 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: distance2, 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(distance2, distanceToCentroid); const maxValue = cellValue(maxDistance, minDistanceToCentroid); return { distance: distance2, 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: distance2, value, maxValue, x: x2, y: y2, stride } = item; queue = queue.next; if (distance2 > 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, x, y } = bestResult; return { x, y, distance }; } var labelPlacementCmp = (a, b) => b.maxValue - a.maxValue; // packages/ag-charts-enterprise/src/series/map-util/markerUtil.ts function polygonMarkerCenter(polygons, precision) { const result = polygonPointSearch(polygons, precision, (p, x2, y2, stride) => { const distance = -polygonDistance(p, x2, y2); const maxDistance = distance + stride * Math.SQRT2; return { distance, maxDistance }; }); if (result == null) return; const { x, y } = result; return [x, y]; } function markerPositions(geometry, precision) { let center; 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); center = polygon != null ? polygonMarkerCenter(polygon, precision) : void 0; break; } case "Polygon": { const polygon = geometry.coordinates; center = polygon != null ? polygonMarkerCenter(polygon, precision) : void 0; break; } case "MultiLineString": { const lineString = largestLineString(geometry); center = lineString != null ? lineStringCenter(lineString)?.point : void 0; break; } case "LineString": { const lineString = geometry.coordinates; center = lineStringCenter(lineString)?.point; break; } } return center != null ? [center] : []; } // packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeriesProperties.ts var import_ag_charts_community204 = require("ag-charts-community"); 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: RATIO22, STRING: STRING32, MARKER_SHAPE: MARKER_SHAPE2, 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"; } }; __decorateClass([ 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_exports.warnOnce( "Either both [topology] and [idKey] or both [latitudeKey] and [longitudeKey] must be set to render a map marker series." ); return false; } return superIsValid; } }; __decorateClass([ Validate69(GEOJSON_OBJECT, { optional: true }) ], MapMarkerSeriesProperties.prototype, "topology", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "title", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "legendItemName", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "idKey", 2); __decorateClass([ Validate69(STRING32) ], MapMarkerSeriesProperties.prototype, "topologyIdKey", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "idName", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "latitudeKey", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "latitudeName", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "longitudeKey", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "longitudeName", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "sizeKey", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate69(STRING32, { optional: true }) ], MapMarkerSeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate69(AND7(COLOR_STRING_ARRAY8, ARRAY10.restrict({ minLength: 1 })), { optional: true }) ], MapMarkerSeriesProperties.prototype, "colorRange", 2); __decorateClass([ Validate69(MARKER_SHAPE2) ], MapMarkerSeriesProperties.prototype, "shape", 2); __decorateClass([ Validate69(POSITIVE_NUMBER26) ], MapMarkerSeriesProperties.prototype, "size", 2); __decorateClass([ Validate69(POSITIVE_NUMBER26, { optional: true }) ], MapMarkerSeriesProperties.prototype, "maxSize", 2); __decorateClass([ Validate69(NUMBER_ARRAY3, { optional: true }) ], MapMarkerSeriesProperties.prototype, "sizeDomain", 2); __decorateClass([ Validate69(COLOR_STRING18) ], MapMarkerSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate69(RATIO22) ], MapMarkerSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate69(COLOR_STRING18) ], MapMarkerSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate69(POSITIVE_NUMBER26) ], MapMarkerSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate69(RATIO22) ], MapMarkerSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate69(LINE_DASH14) ], MapMarkerSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate69(POSITIVE_NUMBER26) ], MapMarkerSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate69(FUNCTION14, { optional: true }) ], MapMarkerSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate69(OBJECT34) ], MapMarkerSeriesProperties.prototype, "label", 2); __decorateClass([ Validate69(OBJECT34) ], MapMarkerSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeries.ts var { CachedTextMeasurerPool: CachedTextMeasurerPool8, Validate: Validate70, fromToMotion: fromToMotion2, StateMachine: StateMachine13, getMissCount: getMissCount3, createDatumId: createDatumId11, SeriesNodePickMode: SeriesNodePickMode9, valueProperty: valueProperty10, computeMarkerFocusBounds, 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 /* Marker */, index]; this.highlightGroup.zIndex = [4 /* MarkerHighlight */, 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, font2) { 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, height } = CachedTextMeasurerPool8.measureText(String(labelText), { font: font2 }); const anchor = Marker3.anchor(shape); return { point: { x, y, size }, label: { width, height, text: labelText }, anchor, placement }; } createNodeData() { const { id: seriesId, dataModel, processedData, sizeScale, properties, scale } = this; const { idKey, latitudeKey, longitudeKey, sizeKey, colorKey, labelKey, label } = properties; if (dataModel == null || processedData == null || scale == 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 font2 = 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 && scale != null ? projectGeometry(geometry, scale) : 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] = scale.convert([lonValue, latValue]); const labelDatum = this.getLabelDatum(datum, labelValue, x, y, size, font2); 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, font2); 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_exports.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, (text2) => { text2.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, height, text: text2 }) => { label.visible = true; label.x = x + width / 2; label.y = y + height / 2; label.text = text2; 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(); fromToMotion2(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 distanceSquared = dx2 * dx2 + dy2 * dy2; if (distanceSquared < minDistanceSquared) { minDistanceSquared = distanceSquared; minDatum = datum; } }); return minDatum != null ? { datum: minDatum, distance: Math.sqrt(minDistanceSquared) } : void 0; } legendItemSymbol(datumIndex) { const { dataModel, processedData, properties } = this; const { shape, fillOpacity, stroke: stroke2, 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: stroke2, 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 computeMarkerFocusBounds(this, opts); } }; MapMarkerSeries.className = "MapMarkerSeries"; MapMarkerSeries.type = "map-marker"; __decorateClass([ Validate70(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapMarkerSeries.prototype, "_chartTopology", 2); // packages/ag-charts-enterprise/src/series/map-marker/mapMarkerModule.ts 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: stroke2 } = import_ag_charts_community206._ModuleSupport.singleSeriesPaletteFactory(opts); const defaultColorRange = themeTemplateParameters.get(DEFAULT_DIVERGING_SERIES_COLOR_RANGE3); const { fills } = takeColors(colorsCount); return { fill, stroke: stroke2, colorRange: userPalette === "inbuilt" ? defaultColorRange : [fills[0], fills[1]] }; } }; // packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundModule.ts var import_ag_charts_community209 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeries.ts var import_ag_charts_community208 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeriesProperties.ts var import_ag_charts_community207 = require("ag-charts-community"); 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(); } }; __decorateClass([ Validate71(GEOJSON_OBJECT, { optional: true }) ], MapShapeBackgroundSeriesProperties.prototype, "topology", 2); __decorateClass([ Validate71(COLOR_STRING19) ], MapShapeBackgroundSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate71(RATIO23) ], MapShapeBackgroundSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate71(COLOR_STRING19) ], MapShapeBackgroundSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate71(RATIO23) ], MapShapeBackgroundSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate71(POSITIVE_NUMBER27) ], MapShapeBackgroundSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate71(LINE_DASH15) ], MapShapeBackgroundSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate71(POSITIVE_NUMBER27) ], MapShapeBackgroundSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate71(OBJECT35) ], MapShapeBackgroundSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeries.ts 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 /* ShapeLineBackground */, index, 0]; this.highlightGroup.zIndex = [0 /* ShapeLineBackground */, index, 1]; return true; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 1 /* Polygons */; 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_exports.warnOnce(`no topology was provided for [MapShapeBackgroundSeries]; nothing will be rendered.`); } } createNodeData() { const { id: seriesId, topology, scale } = this; if (topology == null) return; const nodeData = []; const labelData = []; topology.features.forEach((feature, index) => { const { geometry } = feature; const projectedGeometry = geometry != null && scale != null ? projectGeometry(geometry, scale) : 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: stroke2, 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 = stroke2; 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"; __decorateClass([ Validate72(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapShapeBackgroundSeries.prototype, "_chartTopology", 2); // packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundModule.ts var { DEFAULT_HIERARCHY_FILLS: DEFAULT_HIERARCHY_FILLS2 } = 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_FILLS2)?.[1] }; } }; // packages/ag-charts-enterprise/src/series/map-shape/mapShapeModule.ts var import_ag_charts_community212 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeries.ts var import_ag_charts_community211 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/map-util/polygonLabelUtil.ts function preferredLabelCenter(polygons, { aspectRatio, precision }) { const result = polygonPointSearch(polygons, precision, (p, cx, cy, stride) => { const width = maxWidthOfRectConstrainedByCenterAndAspectRatioToPolygon(p, cx, cy, aspectRatio); const maxWidth2 = width + 2 * stride * aspectRatio; const distance2 = width * Math.SQRT2; const maxDistance = maxWidth2 * Math.SQRT2; return { distance: distance2, maxDistance }; }); if (result == null) return; const { x, y, distance } = result; const maxWidth = distance / 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 width = Math.abs(cx - x) * 2; maxWidth = Math.min(maxWidth, width); } } } 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 height = Math.abs(cy - y) * 2; const width = height * aspectRatio; maxWidth = Math.min(maxWidth, width); } } } 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 height = Math.abs(cy - bottomPointY) * 2; const width = height * aspectRatio; maxWidth = Math.min(maxWidth, width); } else if (topPointY > cy && centerToTopMRecip < positiveMRecip) { const height = Math.abs(cy - topPointY) * 2; const width = height * aspectRatio; maxWidth = Math.min(maxWidth, width); } const centerToLeftM = Math.abs((leftPointY - cy) / (leftPointX - cx)); const centerToRightM = Math.abs((rightPointY - cy) / (rightPointX - cx)); if (rightPointX < cx && centerToRightM < positiveM) { const width = Math.abs(cx - rightPointX) * 2; maxWidth = Math.min(maxWidth, width); } else if (leftPointX > cx && centerToLeftM < positiveM) { const width = Math.abs(cx - leftPointX) * 2; maxWidth = Math.min(maxWidth, width); } 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 width = maxWidthOfRectConstrainedByCenterAndAspectRatioToLineSegment(p0, p1, cx, cy, aspectRatio); minWidth = Math.min(minWidth, width); 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, height) { const ry0 = cy - height / 2; const ry1 = cy + height / 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, height) { 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, height); 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 }; } } // packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeriesProperties.ts var import_ag_charts_community210 = require("ag-charts-community"); 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(); } }; __decorateClass([ Validate73(GEOJSON_OBJECT, { optional: true }) ], MapShapeSeriesProperties.prototype, "topology", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "title", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "legendItemName", 2); __decorateClass([ Validate73(STRING33) ], MapShapeSeriesProperties.prototype, "idKey", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "idName", 2); __decorateClass([ Validate73(STRING33) ], MapShapeSeriesProperties.prototype, "topologyIdKey", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "colorKey", 2); __decorateClass([ Validate73(STRING33, { optional: true }) ], MapShapeSeriesProperties.prototype, "colorName", 2); __decorateClass([ Validate73(AND8(COLOR_STRING_ARRAY9, ARRAY11.restrict({ minLength: 1 })), { optional: true }) ], MapShapeSeriesProperties.prototype, "colorRange", 2); __decorateClass([ Validate73(COLOR_STRING20) ], MapShapeSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate73(RATIO24) ], MapShapeSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate73(COLOR_STRING20) ], MapShapeSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate73(RATIO24) ], MapShapeSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate73(POSITIVE_NUMBER28) ], MapShapeSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate73(LINE_DASH16) ], MapShapeSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate73(POSITIVE_NUMBER28) ], MapShapeSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate73(POSITIVE_NUMBER28) ], MapShapeSeriesProperties.prototype, "padding", 2); __decorateClass([ Validate73(FUNCTION15, { optional: true }) ], MapShapeSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate73(OBJECT36) ], MapShapeSeriesProperties.prototype, "label", 2); __decorateClass([ Validate73(OBJECT36) ], MapShapeSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeries.ts 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 /* ShapeLine */, index]; this.highlightGroup.zIndex = [2 /* ShapeLineHighlight */, index]; return true; } isLabelEnabled() { return this.properties.labelKey != null && this.properties.label.enabled; } nodeFactory() { const geoGeometry = new GeoGeometry(); geoGeometry.renderMode = 1 /* Polygons */; 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_exports.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, font2, 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: font2 }); 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 } = this; if (scale == 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 }, (height, allowTruncation) => { if (!allowTruncation) return maxSizeWithoutTruncation; const result = maxWidthInPolygonForRectOfHeight(fixedPolygon, untruncatedX, y, height / scaling); return { width: result.width * scaling, height, meta: result.x }; }); if (labelFormatting == null) return; const [{ text: text2, fontSize, lineHeight, width }, formattingX] = labelFormatting; if (text2 === TextUtils6.EllipsisChar) return; const x = width < maxSizeWithoutTruncation.width ? untruncatedX : formattingX; const position = this.scale.convert(fixedScale.invert([x, y])); return { x: position[0], y: position[1], text: text2, fontSize, lineHeight }; } createNodeData() { const { id: seriesId, dataModel, processedData, properties, scale, previousLabelLayouts } = this; const { idKey, colorKey, labelKey, label } = properties; if (dataModel == null || processedData == null) return; const scaling = scale != null ? (scale.range[1][0] - scale.range[0][0]) / scale.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 font2 = 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, font2, geometry, previousLabelLayouts?.get(idValue) ); if (labelLayout != null) { labelLayouts.set(idValue, labelLayout); } const labelDatum = labelLayout != null && scale != null ? this.getLabelDatum(labelLayout, scaling) : void 0; if (labelDatum != null) { labelData.push(labelDatum); } const projectedGeometry = geometry != null && scale != null ? projectGeometry(geometry, scale) : 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_exports.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: text2, fontSize, lineHeight }) => { label.visible = true; label.x = x; label.y = y; label.text = text2; 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 distanceSquared = node.distanceSquared(x, y); if (distanceSquared < minDistanceSquared) { minDistanceSquared = distanceSquared; 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 center = polygon != null ? polygonMarkerCenter(polygon, 2) : void 0; const point = center != null ? { x: center[0], y: center[1] } : void 0; this._previousDatumMidPoint = { datum, point }; return point; } legendItemSymbol(datumIndex) { const { dataModel, processedData, properties } = this; const { fillOpacity, stroke: stroke2, 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: stroke2, 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"; __decorateClass([ Validate74(GEOJSON_OBJECT, { optional: true, property: "topology" }) ], MapShapeSeries.prototype, "_chartTopology", 2); // packages/ag-charts-enterprise/src/series/map-shape/mapShapeModule.ts 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]] }; } }; // packages/ag-charts-enterprise/src/series/nightingale/nightingaleModule.ts var import_ag_charts_community219 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/nightingale/nightingaleSeries.ts var import_ag_charts_community217 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesBase.ts var import_ag_charts_community213 = require("ag-charts-community"); var { ChartAxisDirection: ChartAxisDirection25, PolarAxis: PolarAxis2, diff: diff4, fixNumericExtent: fixNumericExtent5, groupAccumulativeValueProperty: groupAccumulativeValueProperty2, keyProperty: keyProperty6, normaliseGroupTo, resetLabelFn: resetLabelFn2, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation2, seriesLabelFadeOutAnimation, 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: resetLabelFn2 } }); 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 (isDefined(normalizedTo)) { extraProps.push(normaliseGroupTo([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 }), ...groupAccumulativeValueProperty2( radiusKey, "normal", "current", { id: `radiusValue-end`, rangeId: `radiusValue-range`, invalidValue: null, groupId: stackGroupId, separateNegative: true, ...visibleProps }, radiusScaleType ), ...groupAccumulativeValueProperty2( 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 PolarAxis2 ? 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 angle = 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(angle) * midRadius; const y = Math.sin(angle) * 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); seriesLabelFadeInAnimation2(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); seriesLabelFadeOutAnimation(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: stroke2, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties; return { marker: { fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke2 ?? "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; } }; // packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesBaseProperties.ts var import_ag_charts_community214 = require("ag-charts-community"); 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(); } }; __decorateClass([ Validate75(STRING34) ], RadialColumnSeriesBaseProperties.prototype, "angleKey", 2); __decorateClass([ Validate75(STRING34, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "angleName", 2); __decorateClass([ Validate75(STRING34) ], RadialColumnSeriesBaseProperties.prototype, "radiusKey", 2); __decorateClass([ Validate75(STRING34, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "radiusName", 2); __decorateClass([ Validate75(COLOR_STRING21) ], RadialColumnSeriesBaseProperties.prototype, "fill", 2); __decorateClass([ Validate75(RATIO25) ], RadialColumnSeriesBaseProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate75(COLOR_STRING21) ], RadialColumnSeriesBaseProperties.prototype, "stroke", 2); __decorateClass([ Validate75(POSITIVE_NUMBER29) ], RadialColumnSeriesBaseProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate75(RATIO25) ], RadialColumnSeriesBaseProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate75(LINE_DASH17) ], RadialColumnSeriesBaseProperties.prototype, "lineDash", 2); __decorateClass([ Validate75(POSITIVE_NUMBER29) ], RadialColumnSeriesBaseProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate75(POSITIVE_NUMBER29) ], RadialColumnSeriesBaseProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate75(FUNCTION16, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "itemStyler", 2); __decorateClass([ Validate75(NUMBER17) ], RadialColumnSeriesBaseProperties.prototype, "rotation", 2); __decorateClass([ Validate75(STRING34, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "stackGroup", 2); __decorateClass([ Validate75(NUMBER17, { optional: true }) ], RadialColumnSeriesBaseProperties.prototype, "normalizedTo", 2); __decorateClass([ Validate75(OBJECT37) ], RadialColumnSeriesBaseProperties.prototype, "label", 2); __decorateClass([ Validate75(OBJECT37) ], RadialColumnSeriesBaseProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/nightingale/nightingaleUtil.ts var import_ag_charts_community216 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-column/radialColumnUtil.ts var import_ag_charts_community215 = require("ag-charts-community"); 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 from2 = (status === "removed" || status === "updated" ? node : datum)[key]; let to2 = (status === "removed" ? node : datum)[key]; if (isNaN(to2)) { to2 = node.previousDatum?.[key] ?? NaN; } const diff8 = from2 - to2; if (Math.abs(diff8) > Math.PI) { from2 -= Math.sign(diff8) * 2 * Math.PI; } map.set(datum, { from: from2, to: to2 }); }); }; const getAngles = (datum, fromToKey) => { return { startAngle: angles.startAngle.get(datum)[fromToKey], endAngle: angles.endAngle.get(datum)[fromToKey] }; }; const from = (datum) => getAngles(datum, "from"); const to = (datum) => getAngles(datum, "to"); return { calculate, from, 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 }; } // packages/ag-charts-enterprise/src/series/nightingale/nightingaleUtil.ts var { SectorBox, 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 SectorBox(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 SectorBox(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 SectorBox(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 SectorBox(startAngle, endAngle, clipInnerRadius, clipOuterRadius); return { innerRadius, outerRadius, startAngle, endAngle, clipSector }; } // packages/ag-charts-enterprise/src/series/nightingale/nightingaleSeries.ts var { Sector: Sector4, SectorBox: SectorBox2, PolarZIndexMap } = 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, PolarZIndexMap.FOREGROUND, index]; this.highlightGroup.zIndex = [0, PolarZIndexMap.HIGHLIGHT, index]; this.labelGroup.zIndex = [0, PolarZIndexMap.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 SectorBox2(startAngle, endAngle, clipInnerRadius, clipOuterRadius); } } getColumnTransitionFunctions() { const axisZeroRadius = this.isRadiusAxisReversed() ? this.radius : this.getAxisInnerRadius(); return prepareNightingaleAnimationFunctions(axisZeroRadius); } }; NightingaleSeries.className = "NightingaleSeries"; NightingaleSeries.type = "nightingale"; // packages/ag-charts-enterprise/src/series/nightingale/nightingaleThemes.ts var import_ag_charts_community218 = require("ag-charts-community"); var { ThemeConstants: { POLAR_AXIS_TYPE, POLAR_AXIS_SHAPE } } = 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_TYPE.ANGLE_CATEGORY]: { shape: POLAR_AXIS_SHAPE.CIRCLE, groupPaddingInner: 0, paddingInner: 0, label: { spacing: 10 } }, [POLAR_AXIS_TYPE.RADIUS_NUMBER]: { shape: POLAR_AXIS_SHAPE.CIRCLE } } }; // packages/ag-charts-enterprise/src/series/nightingale/nightingaleModule.ts var { ThemeSymbols: { DEFAULT_POLAR_SERIES_STROKE }, ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE2 } } = 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_TYPE2.ANGLE_CATEGORY }, { type: POLAR_AXIS_TYPE2.RADIUS_NUMBER }], themeTemplate: NIGHTINGALE_SERIES_THEME, paletteFactory({ takeColors, userPalette }) { const { fills: [fill], strokes: [stroke2] } = takeColors(1); return { fill, stroke: userPalette !== "inbuilt" ? stroke2 : DEFAULT_POLAR_SERIES_STROKE }; }, stackable: true, groupable: true, stackedByDefault: true }; // packages/ag-charts-enterprise/src/series/ohlc/ohlcModule.ts var import_ag_charts_community221 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/ohlc/ohlcSeries.ts var import_ag_charts_community220 = require("ag-charts-community"); 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, y, height, yOpen, yClose, crisp } = datum; let style; if (itemStyler != null) { const { stroke: stroke2, 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: stroke2, strokeWidth, lineDash, lineDashOffset, highlighted: isHighlight }) ); } node.centerX = centerX; node.width = width; node.y = y; node.height = height; 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"; // packages/ag-charts-enterprise/src/series/ohlc/ohlcModule.ts 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 [stroke2] = takeColors(colorsCount).strokes; return { item: { up: { stroke: stroke2 }, down: { stroke: stroke2 } } }; } return { item: { up: { stroke: palette.up.stroke }, down: { stroke: palette.down.stroke } } }; } }; // packages/ag-charts-enterprise/src/series/pyramid/pyramidModule.ts var import_ag_charts_community225 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/pyramid/pyramidSeries.ts var import_ag_charts_community223 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/pyramid/pyramidProperties.ts var import_ag_charts_community222 = require("ag-charts-community"); var { SeriesProperties: SeriesProperties9, SeriesTooltip: SeriesTooltip15, Validate: Validate76, UNION: UNION15, COLOR_STRING_ARRAY: COLOR_STRING_ARRAY10, FUNCTION: FUNCTION17, DIRECTION: DIRECTION2, BOOLEAN: BOOLEAN30, LINE_DASH: LINE_DASH18, OBJECT: OBJECT38, NUMBER: NUMBER18, POSITIVE_NUMBER: POSITIVE_NUMBER30, RATIO: RATIO26, STRING: STRING35, Label: Label10, DropShadow: DropShadow2 } = import_ag_charts_community222._ModuleSupport; var PyramidSeriesLabel = class extends Label10 { }; var PyramidSeriesStageLabel = class extends Label10 { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass([ Validate76(NUMBER18) ], PyramidSeriesStageLabel.prototype, "spacing", 2); __decorateClass([ 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 DropShadow2().set({ enabled: false }); this.label = new PyramidSeriesLabel(); this.stageLabel = new PyramidSeriesStageLabel(); this.tooltip = new SeriesTooltip15(); } }; __decorateClass([ Validate76(STRING35) ], PyramidProperties.prototype, "stageKey", 2); __decorateClass([ Validate76(STRING35) ], PyramidProperties.prototype, "valueKey", 2); __decorateClass([ Validate76(COLOR_STRING_ARRAY10) ], PyramidProperties.prototype, "fills", 2); __decorateClass([ Validate76(RATIO26) ], PyramidProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate76(COLOR_STRING_ARRAY10) ], PyramidProperties.prototype, "strokes", 2); __decorateClass([ Validate76(POSITIVE_NUMBER30) ], PyramidProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate76(RATIO26) ], PyramidProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate76(LINE_DASH18) ], PyramidProperties.prototype, "lineDash", 2); __decorateClass([ Validate76(POSITIVE_NUMBER30) ], PyramidProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate76(DIRECTION2) ], PyramidProperties.prototype, "direction", 2); __decorateClass([ Validate76(BOOLEAN30, { optional: true }) ], PyramidProperties.prototype, "reverse", 2); __decorateClass([ Validate76(POSITIVE_NUMBER30) ], PyramidProperties.prototype, "spacing", 2); __decorateClass([ Validate76(POSITIVE_NUMBER30, { optional: true }) ], PyramidProperties.prototype, "aspectRatio", 2); __decorateClass([ Validate76(FUNCTION17, { optional: true }) ], PyramidProperties.prototype, "itemStyler", 2); __decorateClass([ Validate76(OBJECT38) ], PyramidProperties.prototype, "shadow", 2); __decorateClass([ Validate76(OBJECT38) ], PyramidProperties.prototype, "label", 2); __decorateClass([ Validate76(OBJECT38) ], PyramidProperties.prototype, "stageLabel", 2); __decorateClass([ Validate76(OBJECT38) ], PyramidProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/pyramid/pyramidSeries.ts 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 text2 = this.getLabelText(this.properties.stageLabel, { datum, value: xValue, stageKey, valueKey }); const { width } = textMeasurer.measureText(text2); const height = text2.split("\n").length * TextUtils7.getLineHeight(label.fontSize); maxLabelWidth = Math.max(maxLabelWidth, width); maxLabelHeight = Math.max(maxLabelHeight, height); stageLabelData.push({ x: NaN, y: NaN, text: text2, 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 text2 = this.getLabelText(label, { datum, value: yValue, stageKey, valueKey }); const labelDatum = { x, y, text: text2, 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 stroke2 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId16(datumId, highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, stageKey, valueKey, highlighted, fill, stroke: stroke2, ...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: text2, textAlign, textBaseline }) => { label.visible = visible; label.x = x; label.y = y; label.text = text2; 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 distanceSquared = node.distanceSquared(x, y); if (distanceSquared < minDistanceSquared) { minDistanceSquared = distanceSquared; 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 stroke2 = strokes[datumIndex % strokes.length] ?? "black"; return { marker: { fill, fillOpacity, stroke: stroke2, 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"; // packages/ag-charts-enterprise/src/series/pyramid/pyramidThemes.ts var import_ag_charts_community224 = require("ag-charts-community"); var { ThemeSymbols: { DEFAULT_SHADOW_COLOUR: DEFAULT_SHADOW_COLOUR2 } } = 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_COLOUR2, xOffset: 3, yOffset: 3, blur: 5 } } }; // packages/ag-charts-enterprise/src/series/pyramid/pyramidModule.ts 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 }; } }; // packages/ag-charts-enterprise/src/series/radar-area/radarAreaModule.ts var import_ag_charts_community231 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radar/radarThemes.ts var import_ag_charts_community226 = require("ag-charts-community"); 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 ); // packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeries.ts var import_ag_charts_community230 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radar/radarSeries.ts var import_ag_charts_community228 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radar/radarSeriesProperties.ts var import_ag_charts_community227 = require("ag-charts-community"); var { Label: Label11, SeriesMarker, SeriesProperties: SeriesProperties10, SeriesTooltip: SeriesTooltip16, Validate: Validate77, BOOLEAN: BOOLEAN31, COLOR_STRING: COLOR_STRING22, 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 SeriesMarker(); this.label = new Label11(); this.tooltip = new SeriesTooltip16(); this.connectMissingData = false; } }; __decorateClass([ Validate77(STRING36) ], RadarSeriesProperties.prototype, "angleKey", 2); __decorateClass([ Validate77(STRING36) ], RadarSeriesProperties.prototype, "radiusKey", 2); __decorateClass([ Validate77(STRING36, { optional: true }) ], RadarSeriesProperties.prototype, "angleName", 2); __decorateClass([ Validate77(STRING36, { optional: true }) ], RadarSeriesProperties.prototype, "radiusName", 2); __decorateClass([ Validate77(COLOR_STRING22) ], RadarSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate77(POSITIVE_NUMBER31) ], RadarSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate77(RATIO27) ], RadarSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate77(LINE_DASH19) ], RadarSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate77(POSITIVE_NUMBER31) ], RadarSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate77(NUMBER19) ], RadarSeriesProperties.prototype, "rotation", 2); __decorateClass([ Validate77(OBJECT39) ], RadarSeriesProperties.prototype, "marker", 2); __decorateClass([ Validate77(OBJECT39) ], RadarSeriesProperties.prototype, "label", 2); __decorateClass([ Validate77(OBJECT39) ], RadarSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate77(BOOLEAN31) ], RadarSeriesProperties.prototype, "connectMissingData", 2); // packages/ag-charts-enterprise/src/series/radar/radarSeries.ts var { ChartAxisDirection: ChartAxisDirection26, PolarAxis: PolarAxis3, SeriesNodePickMode: SeriesNodePickMode14, valueProperty: valueProperty14, fixNumericExtent: fixNumericExtent6, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation3, markerFadeInAnimation, resetMarkerFn, animationValidation: animationValidation5, computeMarkerFocusBounds: computeMarkerFocusBounds2, extent, 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: resetMarkerFn } }); 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 = extent(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 angle = angleScale.convert(angleDatum); const radius = this.radius + axisInnerRadius - radiusScale.convert(radiusDatum); const cos = Math.cos(angle); const sin = Math.sin(angle); 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: !isFiniteNumber(angle) || !isFiniteNumber(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: stroke2, strokeWidth, strokeOpacity, lineDash, marker } = this.properties; return { marker: { shape: marker.shape, fill: this.getMarkerFill() ?? marker.stroke ?? stroke2 ?? "rgba(0, 0, 0, 0)", stroke: marker.stroke ?? stroke2 ?? "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: stroke2, 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 distance = Math.sqrt((hitPoint.x - datumX - cx) ** 2 + (hitPoint.y - datumY - cy) ** 2); if (distance < minDistance) { minDistance = distance; closestDatum = datum; } } if (closestDatum) { const distance = Math.max(minDistance - (closestDatum.point?.size ?? 0), 0); return { datum: closestDatum, distance }; } } 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, ratio) { 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 angle = Math.atan2(y1, x1); const x0 = radiusZero * Math.cos(angle); const y0 = radiusZero * Math.sin(angle); const t = ratio; 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(ratio) { const linePoints = this.getLinePoints(); const lineNode = this.getLineNode(); if (!lineNode) return; this.animateSinglePath(lineNode, linePoints, ratio); } 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: (ratio) => this.animatePaths(ratio), onStop: () => this.animatePaths(1) }); markerFadeInAnimation(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 computeMarkerFocusBounds2(this, opts); } }; RadarSeries.className = "RadarSeries"; // packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeriesProperties.ts var import_ag_charts_community229 = require("ag-charts-community"); 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; } }; __decorateClass([ Validate78(COLOR_STRING23) ], RadarAreaSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate78(RATIO28) ], RadarAreaSeriesProperties.prototype, "fillOpacity", 2); // packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeries.ts 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(ratio) { super.animatePaths(ratio); this.animateSinglePath(this.getAreaNode(), this.getAreaPoints(), ratio); } 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"; // packages/ag-charts-enterprise/src/series/radar-area/radarAreaModule.ts var { markerPaletteFactory, 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 } = markerPaletteFactory(params); return { stroke: marker.stroke, fill: marker.fill, marker }; } }; // packages/ag-charts-enterprise/src/series/radar-line/radarLineModule.ts var import_ag_charts_community232 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radar-line/radarLineSeries.ts var RadarLineSeries = class extends RadarSeries { updatePathSelections() { this.lineSelection.update(this.visible ? [true] : []); } }; RadarLineSeries.className = "RadarLineSeries"; RadarLineSeries.type = "radar-line"; // packages/ag-charts-enterprise/src/series/radar-line/radarLineModule.ts 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: [stroke2] } = takeColors(1); return { stroke: fill, marker: { fill, stroke: stroke2 } }; } }; // packages/ag-charts-enterprise/src/series/radial-bar/radialBarModule.ts var import_ag_charts_community237 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeries.ts var import_ag_charts_community235 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeriesProperties.ts var import_ag_charts_community233 = require("ag-charts-community"); 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(); } }; __decorateClass([ Validate79(STRING37) ], RadialBarSeriesProperties.prototype, "angleKey", 2); __decorateClass([ Validate79(STRING37) ], RadialBarSeriesProperties.prototype, "radiusKey", 2); __decorateClass([ Validate79(STRING37, { optional: true }) ], RadialBarSeriesProperties.prototype, "angleName", 2); __decorateClass([ Validate79(STRING37, { optional: true }) ], RadialBarSeriesProperties.prototype, "radiusName", 2); __decorateClass([ Validate79(COLOR_STRING24) ], RadialBarSeriesProperties.prototype, "fill", 2); __decorateClass([ Validate79(RATIO29) ], RadialBarSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate79(COLOR_STRING24) ], RadialBarSeriesProperties.prototype, "stroke", 2); __decorateClass([ Validate79(POSITIVE_NUMBER32) ], RadialBarSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate79(RATIO29) ], RadialBarSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate79(LINE_DASH20) ], RadialBarSeriesProperties.prototype, "lineDash", 2); __decorateClass([ Validate79(POSITIVE_NUMBER32) ], RadialBarSeriesProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate79(POSITIVE_NUMBER32) ], RadialBarSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate79(FUNCTION18, { optional: true }) ], RadialBarSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate79(NUMBER20) ], RadialBarSeriesProperties.prototype, "rotation", 2); __decorateClass([ Validate79(STRING37, { optional: true }) ], RadialBarSeriesProperties.prototype, "stackGroup", 2); __decorateClass([ Validate79(NUMBER20, { optional: true }) ], RadialBarSeriesProperties.prototype, "normalizedTo", 2); __decorateClass([ Validate79(OBJECT40) ], RadialBarSeriesProperties.prototype, "label", 2); __decorateClass([ Validate79(OBJECT40) ], RadialBarSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/radial-bar/radialBarUtil.ts var import_ag_charts_community234 = require("ag-charts-community"); 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 }; } // packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeries.ts var { ChartAxisDirection: ChartAxisDirection28, PolarAxis: PolarAxis4, diff: diff5, groupAccumulativeValueProperty: groupAccumulativeValueProperty3, keyProperty: keyProperty7, normaliseGroupTo: normaliseGroupTo2, valueProperty: valueProperty15, fixNumericExtent: fixNumericExtent7, resetLabelFn: resetLabelFn3, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation4, seriesLabelFadeOutAnimation: seriesLabelFadeOutAnimation2, 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 (isDefined(normalizedTo)) { extraProps.push(normaliseGroupTo2([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); 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[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: stroke2, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties; return { marker: { fill: fill ?? "rgba(0, 0, 0, 0)", stroke: stroke2 ?? "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"; // packages/ag-charts-enterprise/src/series/radial-bar/radialBarThemes.ts var import_ag_charts_community236 = require("ag-charts-community"); 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 } } }; // packages/ag-charts-enterprise/src/series/radial-bar/radialBarModule.ts 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: [stroke2] } = takeColors(1); return { fill, stroke: stroke2 }; }, stackable: true, groupable: true }; // packages/ag-charts-enterprise/src/series/radial-column/radialColumnModule.ts var import_ag_charts_community241 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeries.ts var import_ag_charts_community239 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesProperties.ts var import_ag_charts_community238 = require("ag-charts-community"); var { Validate: Validate80, RATIO: RATIO30 } = import_ag_charts_community238._ModuleSupport; var RadialColumnSeriesProperties = class extends RadialColumnSeriesBaseProperties { }; __decorateClass([ Validate80(RATIO30, { optional: true }) ], RadialColumnSeriesProperties.prototype, "columnWidthRatio", 2); __decorateClass([ Validate80(RATIO30, { optional: true }) ], RadialColumnSeriesProperties.prototype, "maxColumnWidthRatio", 2); // packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeries.ts var { ChartAxisDirection: ChartAxisDirection29, PolarAxis: PolarAxis5, RadialColumnShape, getRadialColumnWidth } = 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 RadialColumnShape(); } 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 getRadialColumnWidth(startAngle, endAngle, this.radius, columnWidthRatio, maxColumnWidthRatio); } }; RadialColumnSeries.className = "RadialColumnSeries"; RadialColumnSeries.type = "radial-column"; // packages/ag-charts-enterprise/src/series/radial-column/radialColumnThemes.ts var import_ag_charts_community240 = require("ag-charts-community"); var { ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE8, POLAR_AXIS_SHAPE: POLAR_AXIS_SHAPE2 } } = 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_SHAPE2.CIRCLE, groupPaddingInner: 0, paddingInner: 0, label: { spacing: 10 } }, [POLAR_AXIS_TYPE8.RADIUS_NUMBER]: { shape: POLAR_AXIS_SHAPE2.CIRCLE, innerRadiusRatio: 0.5 } } }; // packages/ag-charts-enterprise/src/series/radial-column/radialColumnModule.ts 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: [stroke2] } = takeColors(1); return { fill, stroke: stroke2 }; }, stackable: true, groupable: true }; // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeModule.ts var import_ag_charts_community246 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeSeries.ts var import_ag_charts_community245 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeNeedle.ts var import_ag_charts_community242 = require("ag-charts-community"); var { SvgPath, Rotatable, Translatable, Scalable } = import_ag_charts_community242._ModuleSupport; var RadialGaugeNeedle = class extends Rotatable(Scalable(Translatable(SvgPath))) { 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"; // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeSeriesProperties.ts var import_ag_charts_community243 = require("ag-charts-community"); 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_ARRAY2, 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 { }; __decorateClass([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeDefaultTargetLabelProperties.prototype, "spacing", 2); var RadialGaugeTargetProperties = class extends BaseProperties26 { constructor() { super(...arguments); this.label = new RadialGaugeDefaultTargetLabelProperties(); } }; __decorateClass([ Validate81(STRING38, { optional: true }) ], RadialGaugeTargetProperties.prototype, "text", 2); __decorateClass([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "value", 2); __decorateClass([ Validate81(TARGET_MARKER_SHAPE, { optional: true }) ], RadialGaugeTargetProperties.prototype, "shape", 2); __decorateClass([ Validate81(TARGET_PLACEMENT2, { optional: true }) ], RadialGaugeTargetProperties.prototype, "placement", 2); __decorateClass([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "spacing", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeTargetProperties.prototype, "size", 2); __decorateClass([ Validate81(NUMBER21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "rotation", 2); __decorateClass([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeTargetProperties.prototype, "fill", 2); __decorateClass([ Validate81(RATIO31, { optional: true }) ], RadialGaugeTargetProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeTargetProperties.prototype, "stroke", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeTargetProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate81(RATIO31, { optional: true }) ], RadialGaugeTargetProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate81(LINE_DASH21, { optional: true }) ], RadialGaugeTargetProperties.prototype, "lineDash", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeTargetProperties.prototype, "lineDashOffset", 2); __decorateClass([ 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; } }; __decorateClass([ Validate81(BOOLEAN32) ], RadialGaugeBarProperties.prototype, "enabled", 2); __decorateClass([ Validate81(OBJECT_ARRAY2) ], RadialGaugeBarProperties.prototype, "fills", 2); __decorateClass([ Validate81(FILL_MODE) ], RadialGaugeBarProperties.prototype, "fillMode", 2); __decorateClass([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeBarProperties.prototype, "fill", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeBarProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeBarProperties.prototype, "stroke", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeBarProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeBarProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate81(LINE_DASH21) ], RadialGaugeBarProperties.prototype, "lineDash", 2); __decorateClass([ 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"; } }; __decorateClass([ Validate81(OBJECT_ARRAY2) ], RadialGaugeScaleProperties.prototype, "fills", 2); __decorateClass([ Validate81(FILL_MODE) ], RadialGaugeScaleProperties.prototype, "fillMode", 2); __decorateClass([ Validate81(COLOR_STRING25, { optional: true }) ], RadialGaugeScaleProperties.prototype, "fill", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeScaleProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate81(COLOR_STRING25) ], RadialGaugeScaleProperties.prototype, "stroke", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeScaleProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeScaleProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate81(LINE_DASH21) ], RadialGaugeScaleProperties.prototype, "lineDash", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeScaleProperties.prototype, "lineDashOffset", 2); __decorateClass([ 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; } }; __decorateClass([ Validate81(BOOLEAN32) ], RadialGaugeNeedleProperties.prototype, "enabled", 2); __decorateClass([ Validate81(RATIO31, { optional: true }) ], RadialGaugeNeedleProperties.prototype, "radiusRatio", 2); __decorateClass([ Validate81(NUMBER21) ], RadialGaugeNeedleProperties.prototype, "spacing", 2); __decorateClass([ Validate81(COLOR_STRING25) ], RadialGaugeNeedleProperties.prototype, "fill", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeNeedleProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate81(COLOR_STRING25) ], RadialGaugeNeedleProperties.prototype, "stroke", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeNeedleProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeNeedleProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate81(LINE_DASH21) ], RadialGaugeNeedleProperties.prototype, "lineDash", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeNeedleProperties.prototype, "lineDashOffset", 2); var RadialGaugeLabelProperties = class extends AutoSizedLabel { }; __decorateClass([ Validate81(STRING38, { optional: true }) ], RadialGaugeLabelProperties.prototype, "text", 2); var RadialGaugeSecondaryLabelProperties = class extends AutoSizedSecondaryLabel { }; __decorateClass([ 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_exports.warnOnce("Either [innerRadius] and [outerRadius] must both be set, or neither can be set."); return false; } return true; } }; __decorateClass([ Validate81(NUMBER21) ], RadialGaugeSeriesProperties.prototype, "value", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "segmentation", 2); __decorateClass([ Validate81(COLOR_STRING_ARRAY11) ], RadialGaugeSeriesProperties.prototype, "defaultColorRange", 2); __decorateClass([ Validate81(OBJECT_ARRAY2) ], RadialGaugeSeriesProperties.prototype, "targets", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "defaultTarget", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeSeriesProperties.prototype, "outerRadiusRatio", 2); __decorateClass([ Validate81(RATIO31) ], RadialGaugeSeriesProperties.prototype, "innerRadiusRatio", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeSeriesProperties.prototype, "outerRadius", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33, { optional: true }) ], RadialGaugeSeriesProperties.prototype, "innerRadius", 2); __decorateClass([ Validate81(POSITIVE_NUMBER33) ], RadialGaugeSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate81(CORNER_MODE) ], RadialGaugeSeriesProperties.prototype, "cornerMode", 2); __decorateClass([ Validate81(NUMBER21) ], RadialGaugeSeriesProperties.prototype, "spacing", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "scale", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "bar", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "needle", 2); __decorateClass([ Validate81(FUNCTION19, { optional: true }) ], RadialGaugeSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "label", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "secondaryLabel", 2); __decorateClass([ Validate81(OBJECT41) ], RadialGaugeSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeUtil.ts var import_ag_charts_community244 = require("ag-charts-community"); 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 } = datum; return { rotation: angle }; } 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" /* Primary */) { labelDatum = datum; } else if (datum.label === "secondary" /* 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 = (height2) => ({ width: Math.sqrt(Math.max(innerRadius ** 2 - (height2 / verticalFactor) ** 2, 0)) * horizontalFactor, height: Math.min(height2, verticalFactor * innerRadius), meta: null }); let labelLayout; let secondaryLabelLayout; let height; if (secondaryLabelDatum != null && secondaryLabelText != null) { const layout = formatStackedLabels( labelText, labelDatum, secondaryLabelText, secondaryLabelDatum, params, sizeFittingHeight ); labelLayout = layout?.label; secondaryLabelLayout = layout?.secondaryLabel; height = layout?.height ?? 0; } else { const layout = formatSingleLabel(labelText, labelDatum, params, sizeFittingHeight); labelLayout = layout?.[0]; secondaryLabelLayout = void 0; height = layout?.[0].height ?? 0; } const rectYOffset = height * verticalAlignFactors3[verticalAlign]; selection.each((label, datum) => { let layout; if (datum.label === "primary" /* Primary */) { layout = labelLayout; } else if (datum.label === "secondary" /* 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" /* Primary */ ? layout.height / 2 : height - layout.height / 2; label.y = datum.centerY + rectOriginInLabelRect - rectYOffset; label.x = datum.centerX; }); } // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeSeries.ts var { fromToMotion: fromToMotion3, resetMotion: resetMotion3, SeriesNodePickMode: SeriesNodePickMode15, StateMachine: StateMachine14, createDatumId: createDatumId19, ChartAxisDirection: ChartAxisDirection30, normalizeAngle360: normalizeAngle3607, normalizeAngle360Inclusive: normalizeAngle360Inclusive3, toDegrees, toRadians: toRadians6, BBox: BBox18, Group: Group19, PointerEvents: PointerEvents10, Selection: Selection15, Sector: Sector6, SectorBox: SectorBox6, Text: Text8, ConicGradient, Marker: Marker5, getColorStops: getColorStops2 } = 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: range2 } = this.axes[ChartAxisDirection30.X].scale; const [startAngle, endAngle] = range2; const { defaultColorRange } = this.properties; const conicAngle = normalizeAngle3607((startAngle + endAngle) / 2 + Math.PI); const sweepAngle = normalizeAngle360Inclusive3(endAngle - startAngle); const stops = getColorStops2(fills, defaultColorRange, domain, fillMode).map( ({ color, offset }) => { offset = Math.min(Math.max(offset, 0), 1); const angle = startAngle + sweepAngle * offset; offset = (angle - conicAngle) / (2 * Math.PI); offset = (offset % 1 + 1) % 1; return { offset, color }; } ); return new ConicGradient( "oklch", stops, toDegrees(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: text2 = 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: stroke2 = 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: text2, value, shape, placement, spacing, size, rotation, fill, fillOpacity, stroke: stroke2, 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 angle = angleScale.convert(value); const quadrant = normalizeAngle3607(angle) / (Math.PI / 2) | 0; const offset = size / 2 + spacing; let textAlign; let textBaseline; let offsetX; let offsetY; switch (placement) { case "outside": ({ textAlign, textBaseline } = outsideLabelPlacements[quadrant]); offsetX = offset * Math.cos(angle); offsetY = offset * Math.sin(angle); break; case "inside": ({ textAlign, textBaseline } = insideLabelPlacements[quadrant]); offsetX = -offset * Math.cos(angle); offsetY = -offset * Math.sin(angle); break; default: textAlign = "center"; textBaseline = "bottom"; offsetX = 0; offsetY = -offset; 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, 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 = scale.fill ?? (bar.enabled && scale.fills.length === 0 ? scale.defaultFill : void 0) ?? this.createConicGradient(scale.fills, scale.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 /* Node */, 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 /* Node */, 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 /* Node */, 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 /* Node */, 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: text2, color: fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter = (params) => this.formatLabel(params.value) } = label; labelData.push({ label: "primary" /* Primary */, centerX, centerY, text: text2, value, fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter }); } if (!needle.enabled && secondaryLabel.enabled) { const { text: text2, color: fill, fontSize, minimumFontSize, fontStyle, fontWeight, fontFamily, lineHeight, formatter } = secondaryLabel; labelData.push({ label: "secondary" /* Secondary */, centerX, centerY, text: text2, 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: text2, size, shape, fill, fillOpacity, stroke: stroke2, 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 /* Target */, index: i }, type: 1 /* Target */, value: targetValue, text: text2, centerX, centerY, shape, radius: targetRadius, angle: targetAngle, rotation: targetRotation, size, fill, fillOpacity, stroke: stroke2, 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 /* Target */) { 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: stroke2, 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 = stroke2; 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, first, last) => { node.clipSector ?? (node.clipSector = new SectorBox6(NaN, NaN, NaN, NaN)); node.centerX = first.centerX; node.centerY = first.centerY; node.outerRadius = node.clipSector.outerRadius = first.outerRadius; node.innerRadius = node.clipSector.innerRadius = first.innerRadius; node.startAngle = node.clipSector.startAngle = first.startAngle; node.startInnerCornerRadius = first.startInnerCornerRadius; node.startOuterCornerRadius = first.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, segmentation } = this.properties; const sectorSpacing = segmentation.spacing ?? 0; const { fillOpacity, stroke: stroke2, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = scale; 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 = stroke2; 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: stroke2, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.needle; const animationDisabled = this.ctx.animationManager.isSkipped(); needleSelection.each((needle, datum) => { const { centerX, centerY, radius } = datum; const scale = radius * 2; needle.d = RadialGaugeNeedle.defaultPathData; needle.fill = fill; needle.fillOpacity = fillOpacity; needle.stroke = stroke2; needle.strokeOpacity = strokeOpacity; needle.strokeWidth = strokeWidth / scale; needle.lineDash = lineDash.map((d) => d / scale); needle.lineDashOffset = lineDashOffset / scale; needle.translationX = centerX; needle.translationY = centerY; needle.scalingX = scale; needle.scalingY = scale; 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, radius, shape, size, rotation, fill, fillOpacity, stroke: stroke2, 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 ?? stroke2; 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(angle); target.translationY = centerY + radius * Math.sin(angle); target.rotation = angle + 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, text: text2 } = target; const { offsetX, offsetY, fill, fontStyle, fontWeight, fontSize, fontFamily, textAlign, textBaseline } = target.label; if (text2 == null) { label.visible = false; return; } label.visible = true; label.x = centerX + radius * Math.cos(angle) + offsetX; label.y = centerY + radius * Math.sin(angle) + offsetY; label.text = text2; 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" /* Primary */) { labelFrom = label.previousDatum?.value ?? params.from ?? datum.value; labelTo = datum.value; } else if (datum.label === "secondary" /* 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: text2 = properties.label.text } = parseUnknownGaugeNodeDatum(nodeDatum); return tooltip.formatTooltip( { data: [{ label: text2, 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 text2 = getLabelText(this, datum); if (text2 != null) { description.push(text2); } }); return description.join(". "); } }; RadialGaugeSeries.className = "RadialGaugeSeries"; RadialGaugeSeries.type = "radial-gauge"; // packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeModule.ts var { FONT_SIZE_RATIO: FONT_SIZE_RATIO2, ThemeSymbols: { DEFAULT_HIERARCHY_FILLS: DEFAULT_HIERARCHY_FILLS3, DEFAULT_GAUGE_SERIES_COLOR_RANGE: DEFAULT_GAUGE_SERIES_COLOR_RANGE2 }, 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_RATIO2.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_RANGE2); 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) }; } }; // packages/ag-charts-enterprise/src/series/range-area/rangeAreaModule.ts var import_ag_charts_community251 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/range-area/rangeArea.ts var import_ag_charts_community249 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/range-area/rangeAreaAggregation.ts 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_MAX]; } 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_MIN]; } 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; } // packages/ag-charts-enterprise/src/series/range-area/rangeAreaProperties.ts var import_ag_charts_community247 = require("ag-charts-community"); var { CartesianSeriesProperties: CartesianSeriesProperties2, InterpolationProperties, SeriesMarker: SeriesMarker2, SeriesTooltip: SeriesTooltip19, Validate: Validate82, BOOLEAN: BOOLEAN33, COLOR_STRING: COLOR_STRING26, LINE_DASH: LINE_DASH22, OBJECT: OBJECT42, PLACEMENT, 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; } }; __decorateClass([ Validate82(PLACEMENT) ], RangeAreaSeriesLabel.prototype, "placement", 2); __decorateClass([ Validate82(POSITIVE_NUMBER34) ], RangeAreaSeriesLabel.prototype, "padding", 2); var RangeAreaProperties = class extends CartesianSeriesProperties2 { 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 InterpolationProperties(); this.shadow = new DropShadow3().set({ enabled: false }); this.marker = new SeriesMarker2(); this.label = new RangeAreaSeriesLabel(); this.tooltip = new SeriesTooltip19(); this.connectMissingData = false; } }; __decorateClass([ Validate82(STRING39) ], RangeAreaProperties.prototype, "xKey", 2); __decorateClass([ Validate82(STRING39) ], RangeAreaProperties.prototype, "yLowKey", 2); __decorateClass([ Validate82(STRING39) ], RangeAreaProperties.prototype, "yHighKey", 2); __decorateClass([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "xName", 2); __decorateClass([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "yName", 2); __decorateClass([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "yLowName", 2); __decorateClass([ Validate82(STRING39, { optional: true }) ], RangeAreaProperties.prototype, "yHighName", 2); __decorateClass([ Validate82(COLOR_STRING26) ], RangeAreaProperties.prototype, "fill", 2); __decorateClass([ Validate82(RATIO32) ], RangeAreaProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate82(COLOR_STRING26) ], RangeAreaProperties.prototype, "stroke", 2); __decorateClass([ Validate82(POSITIVE_NUMBER34) ], RangeAreaProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate82(RATIO32) ], RangeAreaProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate82(LINE_DASH22) ], RangeAreaProperties.prototype, "lineDash", 2); __decorateClass([ Validate82(POSITIVE_NUMBER34) ], RangeAreaProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "interpolation", 2); __decorateClass([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "shadow", 2); __decorateClass([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "marker", 2); __decorateClass([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "label", 2); __decorateClass([ Validate82(OBJECT42) ], RangeAreaProperties.prototype, "tooltip", 2); __decorateClass([ Validate82(BOOLEAN33) ], RangeAreaProperties.prototype, "connectMissingData", 2); // packages/ag-charts-enterprise/src/series/range-area/rangeAreaUtil.ts var import_ag_charts_community248 = require("ag-charts-community"); var { CollapseMode, isScaleValid, pairUpSpans, prepareAreaFillAnimationFns, plotInterpolatedLinePathStroke, prepareLinePathPropertyAnimation, areScalingEqual } = import_ag_charts_community248._ModuleSupport; function prepareRangeAreaPathStrokeAnimationFns(status, highSpans, lowSpans, visibleToggleMode) { const removePhaseFn = (ratio, path) => { plotInterpolatedLinePathStroke(ratio, path, highSpans.removed); plotInterpolatedLinePathStroke(ratio, path, lowSpans.removed); }; const updatePhaseFn = (ratio, path) => { plotInterpolatedLinePathStroke(ratio, path, highSpans.moved); plotInterpolatedLinePathStroke(ratio, path, lowSpans.moved); }; const addPhaseFn = (ratio, path) => { plotInterpolatedLinePathStroke(ratio, path, highSpans.added); plotInterpolatedLinePathStroke(ratio, path, lowSpans.added); }; const pathProperties = prepareLinePathPropertyAnimation(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 || !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 }, CollapseMode.Split ); if (fillSpans == null) return; const fillPhantomSpans = pairUpSpans( { scales: newData.scales, data: newData.fillData.phantomSpans }, { scales: oldData.scales, data: oldData.fillData.phantomSpans }, CollapseMode.Split ); if (fillPhantomSpans == null) return; const highStrokeSpans = pairUpSpans( { scales: newData.scales, data: newData.highStrokeData.spans }, { scales: oldData.scales, data: oldData.highStrokeData.spans }, CollapseMode.Split ); if (highStrokeSpans == null) return; const lowStrokeSpans = pairUpSpans( { scales: newData.scales, data: newData.lowStrokeData.spans }, { scales: oldData.scales, data: oldData.lowStrokeData.spans }, CollapseMode.Split ); if (lowStrokeSpans == null) return; const fadeMode = "fade"; const fill = prepareAreaFillAnimationFns(status, fillSpans, fillPhantomSpans, fadeMode); const stroke2 = prepareRangeAreaPathStrokeAnimationFns(status, highStrokeSpans, lowStrokeSpans, fadeMode); const hasMotion = (diff8?.changed ?? true) || !areScalingEqual(newData.scales.x, oldData.scales.x) || !areScalingEqual(newData.scales.y, oldData.scales.y) || status !== "updated"; return { status, fill, stroke: stroke2, hasMotion }; } // packages/ag-charts-enterprise/src/series/range-area/rangeArea.ts var { valueProperty: valueProperty16, keyProperty: keyProperty8, ChartAxisDirection: ChartAxisDirection31, mergeDefaults: mergeDefaults5, updateLabelNode: updateLabelNode2, fixNumericExtent: fixNumericExtent8, buildResetPathFn, resetLabelFn: resetLabelFn4, resetMarkerFn: resetMarkerFn2, resetMarkerPositionFn, pathSwipeInAnimation, resetMotion: resetMotion4, markerSwipeScaleInAnimation, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation5, animationValidation: animationValidation7, diff: diff6, updateClipPath, computeMarkerFocusBounds: computeMarkerFocusBounds3, plotAreaPathFill, plotLinePathStroke, interpolatePoints, pathFadeInAnimation, markerFadeInAnimation: markerFadeInAnimation2, fromToMotion: fromToMotion4, pathMotion, extent: extent2, 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: buildResetPathFn({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }), label: resetLabelFn4, marker: (node, datum) => ({ ...resetMarkerFn2(node), ...resetMarkerPositionFn(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(extent2(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 range2 = r1 - r0; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range2); const topIndices = dataAggregationFilter?.topIndices; const bottomIndices = dataAggregationFilter?.bottomIndices; let [start, end] = this.visibleRange("xValue", xAxis.range, topIndices); start = Math.max(start - 1, 0); end = Math.min(end + 1, topIndices?.length ?? xValues.length); if (processedData.input.count < 1e3) { start = 0; end = processedData.input.count; } for (let i = start; i < end; 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 interpolatePoints(highPoints, interpolation); }); const lowSpans = spanPoints.flatMap((p) => { if (!Array.isArray(p)) return []; const lowPoints = p.map((d) => d.low); return interpolatePoints(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, stroke2] = opts.paths; const strokeWidth = this.getStrokeWidth(this.properties.strokeWidth); stroke2.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 }); updateClipPath(this, stroke2); 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 [, stroke2] = paths; stroke2.path.clear(); plotLinePathStroke(stroke2, contextData.highStrokeData.spans); plotLinePathStroke(stroke2, contextData.lowStrokeData.spans); stroke2.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: stroke2, strokeWidth, fillOpacity, strokeOpacity } = this.properties; const baseStyle = mergeDefaults5(highlighted && this.properties.highlightStyle.item, marker.getStyle(), { fill, fillOpacity, stroke: stroke2, 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, (text2) => { text2.pointerEvents = PointerEvents11.None; }); } updateLabelNodes(opts) { opts.labelSelection.each((textNode, datum) => { updateLabelNode2(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: stroke2, strokeWidth, strokeOpacity, lineDash, marker } = this.properties; return { marker: { shape: marker.shape, fill: marker.fill ?? fill, stroke: marker.stroke ?? stroke2, fillOpacity: marker.fillOpacity, strokeOpacity: marker.strokeOpacity, strokeWidth: marker.strokeWidth, lineDash: marker.lineDash, lineDashOffset: marker.lineDashOffset }, line: { stroke: stroke2, 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); pathSwipeInAnimation(this, animationManager, ...paths); resetMotion4([markerSelection], resetMarkerPositionFn); markerSwipeScaleInAnimation(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, stroke2] = paths; if (fill == null && stroke2 == 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(); markerFadeInAnimation2(this, animationManager, "added", markerSelection); pathFadeInAnimation(this, "fill_path_properties", animationManager, "add", fill); pathFadeInAnimation(this, "stroke_path_properties", animationManager, "add", stroke2); 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, [stroke2], fns.stroke.pathProperties); if (fns.status === "added") { this.updateAreaPaths(paths, contextData); } else if (fns.status === "removed") { this.updateAreaPaths(paths, previousContextData); } else { pathMotion(this.id, "fill_path_update", animationManager, [fill], fns.fill.path); pathMotion(this.id, "stroke_path_update", animationManager, [stroke2], fns.stroke.path); } if (fns.hasMotion) { markerFadeInAnimation2(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"; // packages/ag-charts-enterprise/src/series/range-area/rangeAreaThemes.ts var import_ag_charts_community250 = require("ag-charts-community"); 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 } } } }; // packages/ag-charts-enterprise/src/series/range-area/rangeAreaModule.ts var { markerPaletteFactory: markerPaletteFactory2, 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 } = markerPaletteFactory2(params); return { fill: marker.fill, stroke: marker.stroke, marker }; } }; // packages/ag-charts-enterprise/src/series/range-bar/rangeBarModule.ts var import_ag_charts_community255 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/range-bar/rangeBarSeries.ts var import_ag_charts_community253 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/range-bar/rangeBarAggregation.ts 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; } // packages/ag-charts-enterprise/src/series/range-bar/rangeBarProperties.ts var import_ag_charts_community252 = require("ag-charts-community"); var { AbstractBarSeriesProperties: AbstractBarSeriesProperties5, SeriesTooltip: SeriesTooltip20, Validate: Validate83, COLOR_STRING: COLOR_STRING27, FUNCTION: FUNCTION20, LINE_DASH: LINE_DASH23, OBJECT: OBJECT43, PLACEMENT: PLACEMENT2, 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; } }; __decorateClass([ Validate83(PLACEMENT2) ], RangeBarSeriesLabel.prototype, "placement", 2); __decorateClass([ 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; } }; __decorateClass([ Validate83(STRING40) ], RangeBarProperties.prototype, "xKey", 2); __decorateClass([ Validate83(STRING40) ], RangeBarProperties.prototype, "yLowKey", 2); __decorateClass([ Validate83(STRING40) ], RangeBarProperties.prototype, "yHighKey", 2); __decorateClass([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "xName", 2); __decorateClass([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "yName", 2); __decorateClass([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "yLowName", 2); __decorateClass([ Validate83(STRING40, { optional: true }) ], RangeBarProperties.prototype, "yHighName", 2); __decorateClass([ Validate83(COLOR_STRING27) ], RangeBarProperties.prototype, "fill", 2); __decorateClass([ Validate83(RATIO33) ], RangeBarProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate83(COLOR_STRING27) ], RangeBarProperties.prototype, "stroke", 2); __decorateClass([ Validate83(POSITIVE_NUMBER35) ], RangeBarProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate83(RATIO33) ], RangeBarProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate83(LINE_DASH23) ], RangeBarProperties.prototype, "lineDash", 2); __decorateClass([ Validate83(POSITIVE_NUMBER35) ], RangeBarProperties.prototype, "lineDashOffset", 2); __decorateClass([ Validate83(POSITIVE_NUMBER35) ], RangeBarProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate83(FUNCTION20, { optional: true }) ], RangeBarProperties.prototype, "itemStyler", 2); __decorateClass([ Validate83(OBJECT43) ], RangeBarProperties.prototype, "shadow", 2); __decorateClass([ Validate83(OBJECT43) ], RangeBarProperties.prototype, "label", 2); __decorateClass([ Validate83(OBJECT43) ], RangeBarProperties.prototype, "tooltip", 2); __decorateClass([ Validate83(BOOLEAN34) ], RangeBarProperties.prototype, "fastDataProcessing", 2); // packages/ag-charts-enterprise/src/series/range-bar/rangeBarSeries.ts var { SeriesNodePickMode: SeriesNodePickMode16, valueProperty: valueProperty17, keyProperty: keyProperty9, ChartAxisDirection: ChartAxisDirection32, checkCrisp: checkCrisp2, updateLabelNode: updateLabelNode3, SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL4, LARGEST_KEY_INTERVAL: LARGEST_KEY_INTERVAL2, diff: diff7, prepareBarAnimationFunctions: prepareBarAnimationFunctions2, midpointStartingBarPosition: midpointStartingBarPosition2, resetBarSelectionsFn: resetBarSelectionsFn2, fixNumericExtent: fixNumericExtent9, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation6, resetLabelFn: resetLabelFn5, animationValidation: animationValidation8, computeBarFocusBounds: computeBarFocusBounds5, visibleRangeIndices: visibleRangeIndices2, 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: resetBarSelectionsFn2, 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_INTERVAL2] : [], ...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 = checkCrisp2( xAxis?.scale, xAxis?.visibleRange, this.smallestDataInterval, this.largestDataInterval ); const xPosition = (datumIndex) => Math.round(xScale.convert(xValues[datumIndex])) + groupOffset + barOffset; const handleDatum = (datumIndex, groupedDataIndex, x, width, 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 height = 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 ? height : width, height: barAlongX ? width : height }; 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 range2 = r1 - r0; const dataAggregationFilter = dataAggregationFilters?.find((f) => f.maxRange > range2); if (dataAggregationFilter != null) { const { maxRange, indexData } = dataAggregationFilter; const [start, end] = visibleRangeIndices2(maxRange, xAxis.range, (index) => { const aggIndex = index * SPAN; const xMinIndex = indexData[aggIndex + X_MIN]; const xMaxIndex = indexData[aggIndex + X_MAX]; if (xMinIndex === -1) return; const midDatumIndex = (xMinIndex + xMaxIndex) / 2 | 0; return [xPosition(midDatumIndex), xPosition(xMaxIndex) + effectiveBarWidth]; }); for (let i = start; i < end; i += 1) { const aggIndex = i * SPAN; 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 midDatumIndex = (xMinIndex + xMaxIndex) / 2 | 0; const xValue = xValues[midDatumIndex]; if (xValue == null) continue; const x = xPosition(midDatumIndex); const width = Math.abs(xPosition(xMinIndex) - xPosition(xMaxIndex)) + effectiveBarWidth; const yLow = yLowValues[yMinIndex]; const yHigh = yHighValues[yMaxIndex]; handleDatum(midDatumIndex, 0, x, width, yLow, yHigh, false); } } else if (processedData.type === "ungrouped") { let [start, end] = visibleRangeIndices2(rawData.length, xAxis.range, (index) => { const x = xPosition(index); return [x, effectiveBarWidth]; }); if (processedData.input.count < 1e3) { start = 0; end = processedData.input.count; } for (let datumIndex = start; datumIndex < end; datumIndex += 1) { const x = xPosition(datumIndex); const width = effectiveBarWidth; const yLow = yLowValues[datumIndex]; const yHigh = yHighValues[datumIndex]; handleDatum(datumIndex, 0, x, width, yLow, yHigh, defaultCrisp); } } else { for (const { datumIndex, groupIndex: groupDataIndex } of dataModel.forEachGroupDatum(this, processedData)) { const x = xPosition(datumIndex); const width = effectiveBarWidth; const yLow = yLowValues[datumIndex]; const yHigh = yHighValues[datumIndex]; handleDatum(datumIndex, groupDataIndex, x, width, 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, (text2) => { text2.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: stroke2, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.properties; return { marker: { fill, stroke: stroke2, 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 = prepareBarAnimationFunctions2(midpointStartingBarPosition2(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 = prepareBarAnimationFunctions2(midpointStartingBarPosition2(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"; // packages/ag-charts-enterprise/src/series/range-bar/rangeBarThemes.ts var import_ag_charts_community254 = require("ag-charts-community"); 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 } } } }; // packages/ag-charts-enterprise/src/series/range-bar/rangeBarModule.ts 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: [stroke2] } = takeColors(1); return { fill, stroke: stroke2 }; }, groupable: true }; // packages/ag-charts-enterprise/src/series/sankey/sankeyModule.ts var import_ag_charts_community259 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/sankey/sankeySeries.ts var import_ag_charts_community258 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/sankey/sankeyLayout.ts 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 height = seriesRectHeight * node.size * sizeScale; node.y = y; node.height = height; y += height + 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); } } // packages/ag-charts-enterprise/src/series/sankey/sankeyLink.ts var import_ag_charts_community256 = require("ag-charts-community"); var { BBox: BBox20, Path: Path13, ScenePathChangeDetection: ScenePathChangeDetection9, splitBezier } = import_ag_charts_community256._ModuleSupport; function offsetTrivialCubicBezier(path, p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, offset) { 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 + offset) / d0; const d1 = Math.hypot(p3y - ty, p3x - tx); const s1 = (d1 + offset) / 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 width = Math.max(this.x1, this.x2) - x; const y = Math.min(this.y1, this.y2); const height = Math.max(this.y1, this.y2) - y + this.height; return new BBox20(x, y, width, height); } 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 height = this.height - 2 * inset; if (height < 0 || x1 > x2) return; const p0x = x1; const p0y = y1 + height / 2; const p1x = (x1 + x2) / 2; const p1y = y1 + height / 2; const p2x = (x1 + x2) / 2; const p2y = y2 + height / 2; const p3x = x2; const p3y = y2 + height / 2; path.moveTo(p0x, p0y - height / 2); if (Math.abs(this.y2 - this.y1) < 1 || this.x2 - this.x1 < this.height * Math.SQRT2) { path.cubicCurveTo(p1x, p1y - height / 2, p2x, p2y - height / 2, p3x, p3y - height / 2); path.lineTo(p3x, p3y + height / 2); path.cubicCurveTo(p2x, p2y + height / 2, p1x, p1y + height / 2, p0x, p0y + height / 2); } else { const [a, b] = splitBezier(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, 0.5); const offset = (y2 > y1 ? 1 : -1) * height / 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, offset); 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, -offset); path.lineTo(p3x, p3y + height / 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, offset); 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, -offset); } path.closePath(); } }; __decorateClass([ ScenePathChangeDetection9() ], SankeyLink.prototype, "x1", 2); __decorateClass([ ScenePathChangeDetection9() ], SankeyLink.prototype, "x2", 2); __decorateClass([ ScenePathChangeDetection9() ], SankeyLink.prototype, "y1", 2); __decorateClass([ ScenePathChangeDetection9() ], SankeyLink.prototype, "y2", 2); __decorateClass([ ScenePathChangeDetection9() ], SankeyLink.prototype, "height", 2); __decorateClass([ ScenePathChangeDetection9() ], SankeyLink.prototype, "inset", 2); // packages/ag-charts-enterprise/src/series/sankey/sankeySeriesProperties.ts var import_ag_charts_community257 = require("ag-charts-community"); 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; } }; __decorateClass([ 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; } }; __decorateClass([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesLinkProperties.prototype, "fill", 2); __decorateClass([ Validate84(RATIO34) ], SankeySeriesLinkProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesLinkProperties.prototype, "stroke", 2); __decorateClass([ Validate84(RATIO34) ], SankeySeriesLinkProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesLinkProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate84(LINE_DASH24) ], SankeySeriesLinkProperties.prototype, "lineDash", 2); __decorateClass([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesLinkProperties.prototype, "lineDashOffset", 2); __decorateClass([ 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; } }; __decorateClass([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "spacing", 2); __decorateClass([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "width", 2); __decorateClass([ Validate84(ALIGNMENT) ], SankeySeriesNodeProperties.prototype, "alignment", 2); __decorateClass([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesNodeProperties.prototype, "fill", 2); __decorateClass([ Validate84(RATIO34) ], SankeySeriesNodeProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate84(COLOR_STRING28, { optional: true }) ], SankeySeriesNodeProperties.prototype, "stroke", 2); __decorateClass([ Validate84(RATIO34) ], SankeySeriesNodeProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate84(LINE_DASH24) ], SankeySeriesNodeProperties.prototype, "lineDash", 2); __decorateClass([ Validate84(POSITIVE_NUMBER36) ], SankeySeriesNodeProperties.prototype, "lineDashOffset", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate84(ARRAY12, { optional: true }) ], SankeySeriesProperties.prototype, "nodes", 2); __decorateClass([ Validate84(STRING41) ], SankeySeriesProperties.prototype, "fromKey", 2); __decorateClass([ Validate84(STRING41) ], SankeySeriesProperties.prototype, "toKey", 2); __decorateClass([ Validate84(STRING41) ], SankeySeriesProperties.prototype, "idKey", 2); __decorateClass([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "idName", 2); __decorateClass([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "labelName", 2); __decorateClass([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "sizeKey", 2); __decorateClass([ Validate84(STRING41, { optional: true }) ], SankeySeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate84(COLOR_STRING_ARRAY12) ], SankeySeriesProperties.prototype, "fills", 2); __decorateClass([ Validate84(COLOR_STRING_ARRAY12) ], SankeySeriesProperties.prototype, "strokes", 2); __decorateClass([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "label", 2); __decorateClass([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "link", 2); __decorateClass([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "node", 2); __decorateClass([ Validate84(OBJECT44) ], SankeySeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/sankey/sankeySeries.ts var { Transformable: Transformable3, applyShapeStyle: applyShapeStyle11, SeriesNodePickMode: SeriesNodePickMode17, CachedTextMeasurerPool: CachedTextMeasurerPool11, TextWrapper: TextWrapper6, TextUtils: TextUtils8, createDatumId: createDatumId22, 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_exports.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 text2; 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; text2 = TextWrapper6.wrapText(node.label, { maxWidth, maxHeight: node.height, font: this.properties.label, textWrap: "never", overflow: "hide" }); } if (text2 == null || text2 === "") { const labelInset = leading || trailing ? labelSpacing : labelSpacing * 2; text2 = TextWrapper6.wrapText(node.label, { maxWidth: columnWidth - labelInset, maxHeight: node.height, font: this.properties.label, textWrap: "never" }); } if (text2 === "") return; const { height } = CachedTextMeasurerPool11.measureText(text2, { font: canvasFont, textAlign: "left", textBaseline: "middle" }); const y0 = y - height / 2; const y1 = y + height / 2; if (y0 >= bottom) { labelData.push({ x, y, leading, text: text2 }); 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: text2 }) => { label.visible = true; label.x = x; label.y = y; label.text = text2; 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) => createDatumId22([datum.type, datum.id])); } getBaseNodeStyle(highlighted) { const { properties } = this; const { fill, fillOpacity, stroke: stroke2, 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 ?? stroke2, 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 stroke2 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId22(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: stroke2, 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) => createDatumId22([datum.type, datum.index, datum.fromNode.id, datum.toNode.id]) ); } getBaseLinkStyle(highlighted) { const { properties } = this; const { fill, fillOpacity, stroke: stroke2, 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 ?? stroke2, 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 stroke2 = format.stroke ?? strokes[datumIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId22(datumId, highlighted ? "highlight" : "node"), () => { const { fillOpacity = 1, strokeOpacity = 1, strokeWidth = 0, lineDash = [], lineDashOffset = 0 } = format; return itemStyler({ seriesId, datum, highlighted, fill, fillOpacity, stroke: stroke2, 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 /* Link */ ? seriesDatum.fromNode.index : seriesDatum.index; const title = seriesDatum.type === 0 /* Link */ ? `${seriesDatum.fromNode.label} - ${seriesDatum.toNode.label}` : seriesDatum.label; const datum = datumIndex.type === 0 /* Link */ ? linksProcessedData?.dataSources.get(this.id)?.[datumIndex.index] : nodesProcessedData?.dataSources.get(this.id)?.[datumIndex.index]; const size = seriesDatum.size; let format; if (seriesDatum.type === 0 /* Link */) { 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, height } = node; const bbox = new BBox21(x, y, width, height); return Transformable3.toCanvas(this.contentGroup, bbox); } return node; } }; SankeySeries.className = "SankeySeries"; SankeySeries.type = "sankey"; // packages/ag-charts-enterprise/src/series/sankey/sankeyModule.ts 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); } }; // packages/ag-charts-enterprise/src/series/sunburst/sunburstModule.ts var import_ag_charts_community262 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/sunburst/sunburstSeries.ts var import_ag_charts_community261 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/sunburst/sunburstSeriesProperties.ts var import_ag_charts_community260 = require("ag-charts-community"); var { HierarchySeriesProperties, HighlightStyle, SeriesTooltip: SeriesTooltip22, Validate: Validate85, COLOR_STRING: COLOR_STRING29, FUNCTION: FUNCTION22, NUMBER: NUMBER22, OBJECT: OBJECT45, POSITIVE_NUMBER: POSITIVE_NUMBER37, RATIO: RATIO35, STRING: STRING42 } = import_ag_charts_community260._ModuleSupport; var SunburstSeriesTileHighlightStyle = class extends HighlightStyle { constructor() { super(...arguments); this.label = new AutoSizedLabel(); this.secondaryLabel = new AutoSizedLabel(); } }; __decorateClass([ Validate85(STRING42, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "fill", 2); __decorateClass([ Validate85(RATIO35, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "fillOpacity", 2); __decorateClass([ Validate85(COLOR_STRING29, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "stroke", 2); __decorateClass([ Validate85(POSITIVE_NUMBER37, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "strokeWidth", 2); __decorateClass([ Validate85(RATIO35, { optional: true }) ], SunburstSeriesTileHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass([ Validate85(OBJECT45) ], SunburstSeriesTileHighlightStyle.prototype, "label", 2); __decorateClass([ Validate85(OBJECT45) ], SunburstSeriesTileHighlightStyle.prototype, "secondaryLabel", 2); var SunburstSeriesProperties = class extends HierarchySeriesProperties { 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 SeriesTooltip22(); } }; __decorateClass([ Validate85(STRING42, { optional: true }) ], SunburstSeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate85(STRING42, { optional: true }) ], SunburstSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate85(STRING42, { optional: true }) ], SunburstSeriesProperties.prototype, "secondaryLabelKey", 2); __decorateClass([ Validate85(RATIO35) ], SunburstSeriesProperties.prototype, "fillOpacity", 2); __decorateClass([ Validate85(POSITIVE_NUMBER37) ], SunburstSeriesProperties.prototype, "strokeWidth", 2); __decorateClass([ Validate85(RATIO35) ], SunburstSeriesProperties.prototype, "strokeOpacity", 2); __decorateClass([ Validate85(POSITIVE_NUMBER37) ], SunburstSeriesProperties.prototype, "cornerRadius", 2); __decorateClass([ Validate85(NUMBER22, { optional: true }) ], SunburstSeriesProperties.prototype, "sectorSpacing", 2); __decorateClass([ Validate85(NUMBER22, { optional: true }) ], SunburstSeriesProperties.prototype, "padding", 2); __decorateClass([ Validate85(FUNCTION22, { optional: true }) ], SunburstSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "highlightStyle", 2); __decorateClass([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "label", 2); __decorateClass([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "secondaryLabel", 2); __decorateClass([ Validate85(OBJECT45) ], SunburstSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/sunburst/sunburstSeries.ts var { fromToMotion: fromToMotion5, normalizeAngle360: normalizeAngle3608, createDatumId: createDatumId23, Sector: Sector7, Group: Group21, ScalableGroup: ScalableGroup2, Selection: Selection16, TransformableText: TransformableText2, 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 ScalableGroup2()); 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 TransformableText2({ tag: 0 /* Primary */ }), new TransformableText2({ 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 stroke2 = format.stroke ?? strokes[rootIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = colorValue != null ? colorScale.convert(colorValue) : fill; overrides.stroke = stroke2; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId23(datumId.join(":"), highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, depth, highlighted, fill, stroke: stroke2, ...format }); } ); Object.assign(overrides, itemStyle); } return overrides; } updateNodes() { const { chart, data, maxDepth } = this; if (chart == null || data == null) { return; } const { width, height } = chart.seriesRect; const { sectorSpacing = 0, padding = 0, cornerRadius, childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName } = this.properties; this.contentGroup.translationX = width / 2; this.contentGroup.translationY = height / 2; const baseInset = sectorSpacing * 0.5; const radius = Math.min(width, height) / 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 /* Top */ : 12 /* Bottom */) & (right ? 6 /* Right */ : 9 /* Left */); let labelRadius; switch (labelPlacement) { case 0 /* CenterCircle */: labelRadius = 0; break; case 1 /* Parallel */: { 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 /* Perpendicular */: 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, text2, tag, highlighted) => { const { depth, contentHeight } = node; const primary = tag === 0 /* Primary */; const label = primary ? node.label : node.secondaryLabel; if (depth == null || label == null) { text2.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; } text2.text = label.text; text2.fontSize = label.fontSize; text2.lineHeight = label.lineHeight; text2.fontStyle = label.fontStyle; text2.fontFamily = label.fontFamily; text2.fontWeight = label.fontWeight; text2.fill = highlightedColor ?? label.color; switch (labelPlacement) { case 0 /* CenterCircle */: text2.textAlign = "center"; text2.textBaseline = "top"; text2.translationX = 0; text2.translationY = (primary ? 0 : contentHeight - label.height) - contentHeight * 0.5; text2.rotation = 0; break; case 1 /* Parallel */: { const topHalf = (circleQuarter & 3 /* Top */) !== 0; const translationRadius = primary === !topHalf ? textRadius : textRadius - (contentHeight - label.height); text2.textAlign = "center"; text2.textBaseline = topHalf ? "bottom" : "top"; text2.translationX = Math.cos(theta) * translationRadius; text2.translationY = Math.sin(theta) * translationRadius; text2.rotation = topHalf ? theta - Math.PI * 0.5 : theta + Math.PI * 0.5; break; } case 2 /* Perpendicular */: { const rightHalf = (circleQuarter & 6 /* Right */) !== 0; const translation = primary === !rightHalf ? (contentHeight - label.height) * 0.5 : (label.height - contentHeight) * 0.5; text2.textAlign = "center"; text2.textBaseline = "middle"; text2.translationX = Math.cos(theta) * textRadius + Math.cos(theta + Math.PI / 2) * translation; text2.translationY = Math.sin(theta) * textRadius + Math.sin(theta + Math.PI / 2) * translation; text2.rotation = rightHalf ? theta : theta + Math.PI; break; } } text2.visible = true; }; const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); this.labelSelection.selectByClass(TransformableText2).forEach((text2) => { updateText(text2.datum, text2, text2.tag, text2.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"; // packages/ag-charts-enterprise/src/series/sunburst/sunburstModule.ts 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 }; } }; // packages/ag-charts-enterprise/src/series/treemap/treemapModule.ts var import_ag_charts_community265 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/treemap/treemapSeries.ts var import_ag_charts_community264 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/treemap/treemapSeriesProperties.ts var import_ag_charts_community263 = require("ag-charts-community"); var { BaseProperties: BaseProperties28, HierarchySeriesProperties: HierarchySeriesProperties2, HighlightStyle: HighlightStyle2, 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, TEXT_ALIGN: TEXT_ALIGN3, VERTICAL_ALIGN: VERTICAL_ALIGN2, Label: Label17 } = import_ag_charts_community263._ModuleSupport; var TreemapGroupLabel = class extends Label17 { constructor() { super(...arguments); this.spacing = 0; } }; __decorateClass([ 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(); } }; __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesGroup.prototype, "fill", 2); __decorateClass([ Validate86(RATIO36) ], TreemapSeriesGroup.prototype, "fillOpacity", 2); __decorateClass([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesGroup.prototype, "stroke", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "strokeWidth", 2); __decorateClass([ Validate86(RATIO36) ], TreemapSeriesGroup.prototype, "strokeOpacity", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "cornerRadius", 2); __decorateClass([ Validate86(TEXT_ALIGN3) ], TreemapSeriesGroup.prototype, "textAlign", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "gap", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesGroup.prototype, "padding", 2); __decorateClass([ Validate86(BOOLEAN35) ], TreemapSeriesGroup.prototype, "interactive", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesTile.prototype, "fill", 2); __decorateClass([ Validate86(RATIO36) ], TreemapSeriesTile.prototype, "fillOpacity", 2); __decorateClass([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesTile.prototype, "stroke", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38, { optional: true }) ], TreemapSeriesTile.prototype, "strokeWidth", 2); __decorateClass([ Validate86(RATIO36) ], TreemapSeriesTile.prototype, "strokeOpacity", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesTile.prototype, "cornerRadius", 2); __decorateClass([ Validate86(TEXT_ALIGN3) ], TreemapSeriesTile.prototype, "textAlign", 2); __decorateClass([ Validate86(VERTICAL_ALIGN2) ], TreemapSeriesTile.prototype, "verticalAlign", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesTile.prototype, "gap", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38) ], TreemapSeriesTile.prototype, "padding", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesTile.prototype, "label", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesTile.prototype, "secondaryLabel", 2); var TreemapSeriesGroupHighlightStyle = class extends BaseProperties28 { constructor() { super(...arguments); this.label = new AutoSizedLabel(); } }; __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "fill", 2); __decorateClass([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "fillOpacity", 2); __decorateClass([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "stroke", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "strokeWidth", 2); __decorateClass([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesGroupHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesGroupHighlightStyle.prototype, "label", 2); var TreemapSeriesTileHighlightStyle = class extends BaseProperties28 { constructor() { super(...arguments); this.label = new AutoSizedLabel(); this.secondaryLabel = new AutoSizedSecondaryLabel(); } }; __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "fill", 2); __decorateClass([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "fillOpacity", 2); __decorateClass([ Validate86(COLOR_STRING30, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "stroke", 2); __decorateClass([ Validate86(POSITIVE_NUMBER38, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "strokeWidth", 2); __decorateClass([ Validate86(RATIO36, { optional: true }) ], TreemapSeriesTileHighlightStyle.prototype, "strokeOpacity", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesTileHighlightStyle.prototype, "label", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesTileHighlightStyle.prototype, "secondaryLabel", 2); var TreemapSeriesHighlightStyle = class extends HighlightStyle2 { constructor() { super(...arguments); this.group = new TreemapSeriesGroupHighlightStyle(); this.tile = new TreemapSeriesTileHighlightStyle(); } }; __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesHighlightStyle.prototype, "group", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesHighlightStyle.prototype, "tile", 2); var TreemapSeriesProperties = class extends HierarchySeriesProperties2 { constructor() { super(...arguments); this.highlightStyle = new TreemapSeriesHighlightStyle(); this.tooltip = new SeriesTooltip23(); this.group = new TreemapSeriesGroup(); this.tile = new TreemapSeriesTile(); this.undocumentedGroupFills = []; this.undocumentedGroupStrokes = []; } }; __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesProperties.prototype, "sizeName", 2); __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesProperties.prototype, "labelKey", 2); __decorateClass([ Validate86(STRING43, { optional: true }) ], TreemapSeriesProperties.prototype, "secondaryLabelKey", 2); __decorateClass([ Validate86(FUNCTION23, { optional: true }) ], TreemapSeriesProperties.prototype, "itemStyler", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "highlightStyle", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "tooltip", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "group", 2); __decorateClass([ Validate86(OBJECT46) ], TreemapSeriesProperties.prototype, "tile", 2); __decorateClass([ Validate86(STRING_ARRAY) ], TreemapSeriesProperties.prototype, "undocumentedGroupFills", 2); __decorateClass([ Validate86(STRING_ARRAY) ], TreemapSeriesProperties.prototype, "undocumentedGroupStrokes", 2); // packages/ag-charts-enterprise/src/series/treemap/treemapSeries.ts var { TextUtils: TextUtils9, TextWrapper: TextWrapper7, isNumberEqual: isNumberEqual10, createDatumId: createDatumId24, Rect: Rect9, Group: Group22, BBox: BBox22, 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(text2, style) { const { fontStyle, fontWeight, fontSize, fontFamily } = style; tempText.setProperties({ text: text2, fontStyle, fontWeight, fontSize, fontFamily, textAlign: "left", textBaseline: "top" }); const { width, height } = tempText.getBBox(); return { width, height }; } 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 Group22()); this.datumSelection = Selection17.select(this.rectGroup, Rect9); this.labelSelection = Selection17.select(this.labelGroup, Group22); this.highlightSelection = Selection17.select( this.rectGroup, Rect9 ); } groupTitleHeight(node, bbox) { const { labelValue } = node; const { label: font2 } = this.properties.group; const heightRatioThreshold = 3; if (labelValue == null) { return; } else if (font2.fontSize > bbox.width / heightRatioThreshold || font2.fontSize > bbox.height / heightRatioThreshold) { return; } else { const { height: fontHeight } = getTextSize(labelValue, font2); return Math.max(fontHeight, font2.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 width = bbox.width - padding.left - padding.right; const height = bbox.height - padding.top - padding.bottom; if (width <= 0 || height <= 0) return; const numChildren = sortedChildrenIndices.length; let stackSum = 0; let startIndex = 0; let minRatioDiff = Infinity; let partitionSum = sortedChildrenIndices.reduce((sum, sortedIndex) => sum + nodeSize(children[sortedIndex]), 0); const innerBox = new BBox22(bbox.x + padding.left, bbox.y + padding.top, width, height); 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 ratio = Math.max(firstTileLength, stackThickness) / Math.min(firstTileLength, stackThickness); const diff8 = Math.abs(targetTileAspectRatio - ratio); if (diff8 < minRatioDiff) { minRatioDiff = diff8; i++; continue; } stackSum -= value; stackThickness = partThickness * stackSum / partitionSum; let start2 = isVertical2 ? partition.x : partition.y; for (let j = startIndex; j < i; j++) { const child = childAt(j); const childSize = nodeSize(child); const x = isVertical2 ? start2 : partition.x; const y = isVertical2 ? partition.y : start2; const length = partLength * childSize / stackSum; const stackWidth = isVertical2 ? length : stackThickness; const stackHeight = isVertical2 ? stackThickness : length; const childBbox = new BBox22(x, y, stackWidth, stackHeight); this.applyGap(innerBox, childBbox, allLeafNodes); this.squarify(child, childBbox); partitionSum -= childSize; start2 += length; } 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 start = isVertical ? partition.x : partition.y; for (let childIdx = startIndex; childIdx < numChildren; childIdx++) { const child = childAt(childIdx); const x = isVertical ? start : partition.x; const y = isVertical ? partition.y : start; const part = nodeSize(child) / partitionSum; const childWidth = partition.width * (isVertical ? part : 1); const childHeight = partition.height * (isVertical ? 1 : part); const childBox = new BBox22(x, y, childWidth, childHeight); this.applyGap(innerBox, childBox, allLeafNodes); this.squarify(child, childBox); start += 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 stroke2 = format.stroke ?? undocumentedGroupStrokes[Math.min(depth ?? 0, undocumentedGroupStrokes.length)]; const overrides = {}; if (!highlighted) { overrides.fill = fill; overrides.stroke = stroke2; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId24(datumId.join(":"), highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, depth, highlighted, fill, stroke: stroke2, ...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 stroke2 = format.stroke ?? strokes[rootIndex % strokes.length]; const overrides = {}; if (!highlighted) { overrides.fill = colorValue != null ? colorScale.convert(colorValue) : fill; overrides.stroke = stroke2; } if (itemStyler != null) { const itemStyle = this.cachedDatumCallback( createDatumId24(datumId.join(":"), highlighted ? "highlight" : "node"), () => { return itemStyler({ seriesId, datum, depth, highlighted, fill, stroke: stroke2, ...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, height } = seriesRect; this.squarify(rootNode, new BBox22(0, 0, width, height)); 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 text2 = 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: text2, 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, text2, tag, highlighted) => { const isLeaf = node.children.length === 0; const label = tag === 0 /* Primary */ ? node.label : node.secondaryLabel; if (label == null) { text2.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 /* Primary */) { highlightedColor = hTitle.label.color; } } text2.text = label.text; text2.fontSize = label.fontSize; text2.lineHeight = label.lineHeight; text2.fontStyle = label.fontStyle; text2.fontFamily = label.fontFamily; text2.fontWeight = label.fontWeight; text2.fill = highlightedColor ?? label.color; text2.textAlign = label.textAlign; text2.textBaseline = label.verticalAlign; text2.x = label.x; text2.y = label.y; text2.visible = true; text2.zIndex = 1; }; const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight(); this.labelSelection.selectByClass(Text9).forEach((text2) => { updateLabelFn(text2.datum, text2, text2.tag, text2.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"; // packages/ag-charts-enterprise/src/series/treemap/treemapModule.ts 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_STROKES2 } } = 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_STROKES2); return { fills, strokes, colorRange: defaultColorRange, undocumentedGroupFills: groupFills, undocumentedGroupStrokes: groupStrokes }; } }; // packages/ag-charts-enterprise/src/series/waterfall/waterfallModule.ts var import_ag_charts_community269 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/waterfall/waterfallSeries.ts var import_ag_charts_community267 = require("ag-charts-community"); // packages/ag-charts-enterprise/src/series/waterfall/waterfallSeriesProperties.ts var import_ag_charts_community266 = require("ag-charts-community"); 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 { }; __decorateClass([ Validate87(UNION18(["subtotal", "total"], "a total type")) ], WaterfallSeriesTotal.prototype, "totalType", 2); __decorateClass([ Validate87(NUMBER24) ], WaterfallSeriesTotal.prototype, "index", 2); __decorateClass([ Validate87(STRING44) ], WaterfallSeriesTotal.prototype, "axisLabel", 2); var WaterfallSeriesItemTooltip = class extends BaseProperties29 { }; __decorateClass([ Validate87(FUNCTION24, { optional: true }) ], WaterfallSeriesItemTooltip.prototype, "renderer", 2); var WaterfallSeriesLabel = class extends Label18 { constructor() { super(...arguments); this.placement = "outside-end"; this.padding = 6; } }; __decorateClass([ Validate87(UNION18(["inside-center", "inside-start", "inside-end", "outside-start", "outside-end"], "a placement")) ], WaterfallSeriesLabel.prototype, "placement", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate87(STRING44, { optional: true }) ], WaterfallSeriesItem.prototype, "name", 2); __decorateClass([ Validate87(COLOR_STRING31) ], WaterfallSeriesItem.prototype, "fill", 2); __decorateClass([ Validate87(COLOR_STRING31) ], WaterfallSeriesItem.prototype, "stroke", 2); __decorateClass([ Validate87(RATIO37) ], WaterfallSeriesItem.prototype, "fillOpacity", 2); __decorateClass([ Validate87(RATIO37) ], WaterfallSeriesItem.prototype, "strokeOpacity", 2); __decorateClass([ Validate87(LINE_DASH25) ], WaterfallSeriesItem.prototype, "lineDash", 2); __decorateClass([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesItem.prototype, "lineDashOffset", 2); __decorateClass([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesItem.prototype, "strokeWidth", 2); __decorateClass([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesItem.prototype, "cornerRadius", 2); __decorateClass([ Validate87(FUNCTION24, { optional: true }) ], WaterfallSeriesItem.prototype, "itemStyler", 2); __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesItem.prototype, "shadow", 2); __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesItem.prototype, "label", 2); __decorateClass([ 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; } }; __decorateClass([ Validate87(BOOLEAN36) ], WaterfallSeriesConnectorLine.prototype, "enabled", 2); __decorateClass([ Validate87(COLOR_STRING31) ], WaterfallSeriesConnectorLine.prototype, "stroke", 2); __decorateClass([ Validate87(RATIO37) ], WaterfallSeriesConnectorLine.prototype, "strokeOpacity", 2); __decorateClass([ Validate87(LINE_DASH25) ], WaterfallSeriesConnectorLine.prototype, "lineDash", 2); __decorateClass([ Validate87(POSITIVE_NUMBER39) ], WaterfallSeriesConnectorLine.prototype, "lineDashOffset", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesItems.prototype, "positive", 2); __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesItems.prototype, "negative", 2); __decorateClass([ 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(); } }; __decorateClass([ Validate87(STRING44) ], WaterfallSeriesProperties.prototype, "xKey", 2); __decorateClass([ Validate87(STRING44) ], WaterfallSeriesProperties.prototype, "yKey", 2); __decorateClass([ Validate87(STRING44, { optional: true }) ], WaterfallSeriesProperties.prototype, "xName", 2); __decorateClass([ Validate87(STRING44, { optional: true }) ], WaterfallSeriesProperties.prototype, "yName", 2); __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesProperties.prototype, "item", 2); __decorateClass([ Validate87(OBJECT_ARRAY3) ], WaterfallSeriesProperties.prototype, "totals", 2); __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesProperties.prototype, "line", 2); __decorateClass([ Validate87(OBJECT47) ], WaterfallSeriesProperties.prototype, "tooltip", 2); // packages/ag-charts-enterprise/src/series/waterfall/waterfallSeries.ts var { adjustLabelPlacement, SeriesNodePickMode: SeriesNodePickMode18, fixNumericExtent: fixNumericExtent10, valueProperty: valueProperty18, keyProperty: keyProperty10, accumulativeValueProperty, trailingAccumulatedValueProperty, ChartAxisDirection: ChartAxisDirection33, createDatumId: createDatumId25, checkCrisp: checkCrisp3, updateLabelNode: updateLabelNode4, prepareBarAnimationFunctions: prepareBarAnimationFunctions3, collapsedStartingBarPosition, resetBarSelectionsFn: resetBarSelectionsFn3, seriesLabelFadeInAnimation: seriesLabelFadeInAnimation7, resetLabelFn: resetLabelFn6, animationValidation: animationValidation9, DEFAULT_CARTESIAN_DIRECTION_KEYS: DEFAULT_CARTESIAN_DIRECTION_KEYS2, DEFAULT_CARTESIAN_DIRECTION_NAMES: DEFAULT_CARTESIAN_DIRECTION_NAMES2, computeBarFocusBounds: computeBarFocusBounds6, isContinuous, 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_KEYS2, directionNames: DEFAULT_CARTESIAN_DIRECTION_NAMES2, 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 positiveNumber = (v) => isContinuous(v) && Number(v) >= 0; const negativeNumber = (v) => isContinuous(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` }), accumulativeValueProperty(yKey, yScaleType, { ...propertyDefinition, id: `yCurrent` }), accumulativeValueProperty(yKey, yScaleType, { ...propertyDefinition, missingValue: 0, id: `yCurrentTotal` }), accumulativeValueProperty(yKey, yScaleType, { ...propertyDefinition, id: `yCurrentPositive`, validation: positiveNumber }), accumulativeValueProperty(yKey, yScaleType, { ...propertyDefinition, id: `yCurrentNegative`, validation: negativeNumber }), trailingAccumulatedValueProperty(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, ...adjustLabelPlacement({ 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: stroke2, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.getItemConfig(item); return { marker: { fill, stroke: stroke2, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } }; } getLegendData(legendType) { if (legendType !== "category") { return []; } const { id, seriesItemTypes } = this; const legendData = []; const capitalise = (text2) => text2.charAt(0).toUpperCase() + text2.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(collapsedStartingBarPosition(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( (end, point) => { if (compare(point.x, end)) { end = point.x; } return end; }, valueAxisReversed ? Infinity : 0 ); const scale = (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 = scale(pointX, startX, endX, startX, point.x); const x2 = scale(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( (end, point) => { if (compare(point.y, end)) { end = point.y; } return end; }, valueAxisReversed ? 0 : Infinity ); const scale = (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 = scale(pointY, startY, endY, startY, point.y); const y2 = scale(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: stroke2, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties.line; lineNode.setProperties({ fill: void 0, stroke: stroke2, 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"; // packages/ag-charts-enterprise/src/series/waterfall/waterfallThemes.ts var import_ag_charts_community268 = require("ag-charts-community"); 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 } }; // packages/ag-charts-enterprise/src/series/waterfall/waterfallModule.ts 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" } } } } }; } }; // packages/ag-charts-enterprise/src/styles.css var styles_default = `.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}} `; // packages/ag-charts-enterprise/src/setup.ts 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, BackgroundModule, 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_default; 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; } // packages/ag-charts-enterprise/src/main.ts __reExport(main_exports, require("ag-charts-community"), 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 };