var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result)
__defProp(target, key, result);
return result;
};
// packages/ag-charts-enterprise/src/main.ts
import { AgCharts, VERSION, _Scene, _Theme, _Util, setupCommunityModules } from "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
import { _ModuleSupport as _ModuleSupport265 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/axes/angle-category/angleCategoryAxis.ts
import { _ModuleSupport as _ModuleSupport5 } from "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
import { _ModuleSupport } from "ag-charts-community";
var { OR, POSITIVE_NUMBER, NAN, AxisInterval, Validate } = _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
import { _ModuleSupport as _ModuleSupport4 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/axes/polar-crosslines/angleCrossLine.ts
import { _ModuleSupport as _ModuleSupport3 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/axes/polar-crosslines/polarCrossLine.ts
import { _ModuleSupport as _ModuleSupport2 } from "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
} = _ModuleSupport2;
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
} = _ModuleSupport3;
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 _ModuleSupport3.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
} = _ModuleSupport4;
var AngleAxisLabel = class extends _ModuleSupport4.AxisLabel {
constructor() {
super(...arguments);
this.orientation = "fixed";
}
};
__decorateClass([
Validate3(UNION2(["fixed", "parallel", "perpendicular"], "a label orientation"))
], AngleAxisLabel.prototype, "orientation", 2);
var AngleAxis = class extends _ModuleSupport4.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 } = _ModuleSupport5;
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
import { _ModuleSupport as _ModuleSupport7 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/axes/angle-number/linearAngleScale.ts
import { _ModuleSupport as _ModuleSupport6 } from "ag-charts-community";
var { range, isDenseInterval, isNumberEqual: isNumberEqual4, LinearScale } = _ModuleSupport6;
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
} = _ModuleSupport7;
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
import { _ModuleSupport as _ModuleSupport8 } from "ag-charts-community";
var { OrdinalTimeScale } = _ModuleSupport8;
var OrdinalTimeAxis = class extends _ModuleSupport8.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
import { _ModuleSupport as _ModuleSupport11 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/axes/radius/radiusAxis.ts
import { _ModuleSupport as _ModuleSupport10 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/axes/polar-crosslines/radiusCrossLine.ts
import { _ModuleSupport as _ModuleSupport9 } from "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
} = _ModuleSupport9;
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 _ModuleSupport9.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 _ModuleSupport9.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
} = _ModuleSupport10;
var RadiusAxisLabel = class extends _ModuleSupport10.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 _ModuleSupport10.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 = _ModuleSupport10.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 } = _ModuleSupport11;
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
import { _ModuleSupport as _ModuleSupport12 } from "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 } = _ModuleSupport12;
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
import { _ModuleSupport as _ModuleSupport14 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/charts/flowProportionChart.ts
import { _ModuleSupport as _ModuleSupport13 } from "ag-charts-community";
var { Chart } = _ModuleSupport13;
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 } = _ModuleSupport14;
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
import { _ModuleSupport as _ModuleSupport16 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/charts/gaugeChart.ts
import { _ModuleSupport as _ModuleSupport15 } from "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
} = _ModuleSupport15;
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 } = _ModuleSupport16;
var GaugeChartModule = {
type: "chart",
name: "gauge",
detect: isAgGaugeChartOptions,
create(options, resources) {
return new GaugeChart(options, resources);
}
};
// packages/ag-charts-enterprise/src/charts/hierarchyChartModule.ts
import { _ModuleSupport as _ModuleSupport18 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/charts/hierarchyChart.ts
import { _ModuleSupport as _ModuleSupport17 } from "ag-charts-community";
var { Chart: Chart3 } = _ModuleSupport17;
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 } = _ModuleSupport18;
var HierarchyChartModule = {
type: "chart",
name: "hierarchy",
detect: isAgHierarchyChartOptions,
create(options, resources) {
return new HierarchyChart(options, resources);
}
};
// packages/ag-charts-enterprise/src/charts/standaloneChartModule.ts
import { _ModuleSupport as _ModuleSupport20 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/charts/standaloneChart.ts
import { _ModuleSupport as _ModuleSupport19 } from "ag-charts-community";
var { Chart: Chart4 } = _ModuleSupport19;
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 } = _ModuleSupport20;
var StandaloneChartModule = {
type: "chart",
name: "standalone",
detect: isAgStandaloneChartOptions,
create(options, resources) {
return new StandaloneChart(options, resources);
}
};
// packages/ag-charts-enterprise/src/charts/topologyChartModule.ts
import { _ModuleSupport as _ModuleSupport22 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/charts/topologyChart.ts
import { _ModuleSupport as _ModuleSupport21 } from "ag-charts-community";
var { Chart: Chart5, MercatorScale, NumberAxis } = _ModuleSupport21;
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 } = _ModuleSupport22;
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
import { _ModuleSupport as _ModuleSupport23 } from "ag-charts-community";
var { BOOLEAN: BOOLEAN3, POSITIVE_NUMBER: POSITIVE_NUMBER3, ObserveChanges, Validate: Validate10 } = _ModuleSupport23;
var Animation = class extends _ModuleSupport23.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
import {
_ModuleSupport as _ModuleSupport98
} from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/text-input/textInput.ts
import { _ModuleSupport as _ModuleSupport24 } from "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 } = _ModuleSupport24;
var moduleId = "text-input";
var canvasOverlay = "canvas-overlay";
var TextInput = class extends _ModuleSupport24.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;
_ModuleSupport24.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 _ModuleSupport24.BBox(left, top, width, height);
}
};
// packages/ag-charts-enterprise/src/features/annotations/annotationAxesButtons.ts
import { _ModuleSupport as _ModuleSupport25 } from "ag-charts-community";
var { BOOLEAN: BOOLEAN4, BaseProperties: BaseProperties2, Validate: Validate11, UNION: UNION3 } = _ModuleSupport25;
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
import { _ModuleSupport as _ModuleSupport47 } from "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
import { _ModuleSupport as _ModuleSupport30 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/annotationProperties.ts
import { _ModuleSupport as _ModuleSupport26 } from "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
} = _ModuleSupport26;
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
import { _ModuleSupport as _ModuleSupport29 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/utils/values.ts
import { _ModuleSupport as _ModuleSupport27 } from "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 } = _ModuleSupport27;
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
import { _ModuleSupport as _ModuleSupport28 } from "ag-charts-community";
var { BaseProperties: BaseProperties4 } = _ModuleSupport28;
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 } = _ModuleSupport29;
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 } = _ModuleSupport30;
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
import { _ModuleSupport as _ModuleSupport32 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/properties/textualPointProperties.ts
import { _ModuleSupport as _ModuleSupport31 } from "ag-charts-community";
var { STRING: STRING5, BaseProperties: BaseProperties5, Validate: Validate15 } = _ModuleSupport31;
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 } = _ModuleSupport32;
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
import { _ModuleSupport as _ModuleSupport34 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/utils/line.ts
import { _ModuleSupport as _ModuleSupport33 } from "ag-charts-community";
var { Vec2 } = _ModuleSupport33;
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 } = _ModuleSupport34;
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
import { _ModuleSupport as _ModuleSupport36 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/text/util.ts
import { _ModuleSupport as _ModuleSupport35 } from "ag-charts-community";
var { TextWrapper: TextWrapper2, CachedTextMeasurerPool, BBox: BBox2 } = _ModuleSupport35;
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 } = _ModuleSupport36;
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
import { _ModuleSupport as _ModuleSupport37 } from "ag-charts-community";
var { BaseProperties: BaseProperties8 } = _ModuleSupport37;
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
import { _ModuleSupport as _ModuleSupport39 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/utils/validation.ts
import "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 } = _ModuleSupport39;
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
import { _ModuleSupport as _ModuleSupport40 } from "ag-charts-community";
var { NUMBER: NUMBER6, OBJECT: OBJECT8, STRING: STRING10, BaseProperties: BaseProperties10, Validate: Validate20 } = _ModuleSupport40;
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
import { _ModuleSupport as _ModuleSupport43 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/properties/fibonacciProperties.ts
import { _ModuleSupport as _ModuleSupport42 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/line/lineProperties.ts
import { _ModuleSupport as _ModuleSupport41 } from "ag-charts-community";
var { OBJECT: OBJECT9, STRING: STRING11, Validate: Validate21 } = _ModuleSupport41;
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 } = _ModuleSupport42;
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 } = _ModuleSupport43;
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
import { _ModuleSupport as _ModuleSupport44 } from "ag-charts-community";
var { STRING: STRING13, Validate: Validate24 } = _ModuleSupport44;
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
import { _ModuleSupport as _ModuleSupport45 } from "ag-charts-community";
var { NUMBER: NUMBER7, STRING: STRING14, OBJECT: OBJECT12, BaseProperties: BaseProperties11, Validate: Validate25 } = _ModuleSupport45;
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
import { _ModuleSupport as _ModuleSupport46 } from "ag-charts-community";
var { STRING: STRING15, Validate: Validate26 } = _ModuleSupport46;
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 } = _ModuleSupport47;
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
import { _ModuleSupport as _ModuleSupport50 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/components/color-picker/colorPicker.ts
import { _ModuleSupport as _ModuleSupport48 } from "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 } = _ModuleSupport48;
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 _ModuleSupport48.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
import { _ModuleSupport as _ModuleSupport49 } from "ag-charts-community";
function channelMenuItemVisible(scale) {
return !(scale instanceof _ModuleSupport49.LogScale) && !(scale instanceof _ModuleSupport49.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
} = _ModuleSupport50;
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 _ModuleSupport50.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
import { _ModuleSupport as _ModuleSupport51 } from "ag-charts-community";
var { StateMachine, StateMachineProperty, Vec2: Vec22, Debug } = _ModuleSupport51;
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
import { _ModuleSupport as _ModuleSupport52 } from "ag-charts-community";
var { STRING: STRING17, Validate: Validate28 } = _ModuleSupport52;
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
import { _ModuleSupport as _ModuleSupport58 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpScene.ts
import { _ModuleSupport as _ModuleSupport57 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/annotationScene.ts
import { _ModuleSupport as _ModuleSupport54 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/handle.ts
import { _ModuleSupport as _ModuleSupport53 } from "ag-charts-community";
var _Handle = class _Handle extends _ModuleSupport53.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 _ModuleSupport53.Marker({ shape: "circle" });
this.glow = new _ModuleSupport53.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 _ModuleSupport53.Rect();
this.glow = new _ModuleSupport53.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 _ModuleSupport53.Marker({ shape: "circle" });
this.glow = new _ModuleSupport53.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 } = _ModuleSupport54;
var AnnotationScene = class extends _ModuleSupport54.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 _ModuleSupport54.Transformable.toCanvas(
this,
_ModuleSupport54.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
import { _ModuleSupport as _ModuleSupport56 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/utils/coords.ts
import { _ModuleSupport as _ModuleSupport55 } from "ag-charts-community";
var { Vec2: Vec23, toRadians: toRadians4 } = _ModuleSupport55;
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 } = _ModuleSupport56;
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) {
_ModuleSupport57.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 _ModuleSupport57.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) {
_ModuleSupport58.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 _ModuleSupport58.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
import { _ModuleSupport as _ModuleSupport59 } from "ag-charts-community";
var { StateMachine: StateMachine2, StateMachineProperty: StateMachineProperty2, Debug: Debug2 } = _ModuleSupport59;
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
import { _ModuleSupport as _ModuleSupport60 } from "ag-charts-community";
var { STRING: STRING18, Validate: Validate29 } = _ModuleSupport60;
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
import { _ModuleSupport as _ModuleSupport64 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/textualStartEndScene.ts
import { _ModuleSupport as _ModuleSupport63 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/startEndScene.ts
import { _ModuleSupport as _ModuleSupport62 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/linearScene.ts
import { _ModuleSupport as _ModuleSupport61 } from "ag-charts-community";
var { Vec2: Vec25, Vec4 } = _ModuleSupport61;
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 } = _ModuleSupport62;
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 } = _ModuleSupport63;
var TextualStartEndScene = class extends StartEndScene {
constructor() {
super(...arguments);
this.label = new _ModuleSupport63.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 } = _ModuleSupport64;
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
import { _ModuleSupport as _ModuleSupport65 } from "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 } = _ModuleSupport65;
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
import { _ModuleSupport as _ModuleSupport67 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/textualPointScene.ts
import { _ModuleSupport as _ModuleSupport66 } from "ag-charts-community";
var TextualPointScene = class extends PointScene {
constructor() {
super(...arguments);
this.label = new _ModuleSupport66.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 } = _ModuleSupport67;
var CommentScene = class extends TextualPointScene {
constructor() {
super();
this.type = "comment" /* Comment */;
this.shape = new _ModuleSupport67.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
import { _ModuleSupport as _ModuleSupport68 } from "ag-charts-community";
var { StateMachine: StateMachine4, StateMachineProperty: StateMachineProperty4, Debug: Debug4 } = _ModuleSupport68;
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
import { _ModuleSupport as _ModuleSupport73 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/axisLabelScene.ts
import { _ModuleSupport as _ModuleSupport69 } from "ag-charts-community";
var { calculateLabelTranslation, ChartAxisDirection: ChartAxisDirection7 } = _ModuleSupport69;
var AxisLabelScene = class extends _ModuleSupport69.Group {
constructor() {
super({ name: "AnnotationAxisLabelGroup" });
this.label = new _ModuleSupport69.Text({ zIndex: 1 });
this.rect = new _ModuleSupport69.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
import { _ModuleSupport as _ModuleSupport70 } from "ag-charts-community";
var { Vec2: Vec27 } = _ModuleSupport70;
var CollidableLine = class extends _ModuleSupport70.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 _ModuleSupport70.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 (_ModuleSupport70.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
import { _ModuleSupport as _ModuleSupport71 } from "ag-charts-community";
var CollidableText = class extends _ModuleSupport71.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
import { _ModuleSupport as _ModuleSupport72 } from "ag-charts-community";
var { Vec2: Vec28 } = _ModuleSupport72;
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 } = _ModuleSupport73;
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
import { _ModuleSupport as _ModuleSupport74 } from "ag-charts-community";
var { StateMachine: StateMachine5, StateMachineProperty: StateMachineProperty5, Debug: Debug5 } = _ModuleSupport74;
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
import { _ModuleSupport as _ModuleSupport77 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/channelScene.ts
import { _ModuleSupport as _ModuleSupport76 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/withBackgroundScene.ts
import { _ModuleSupport as _ModuleSupport75 } from "ag-charts-community";
var { Vec4: Vec45 } = _ModuleSupport75;
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 _ModuleSupport76.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 } = _ModuleSupport76.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 } = _ModuleSupport77;
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
import { _ModuleSupport as _ModuleSupport78 } from "ag-charts-community";
var { StateMachine: StateMachine6, StateMachineProperty: StateMachineProperty6, Debug: Debug6 } = _ModuleSupport78;
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
import { _ModuleSupport as _ModuleSupport80 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/fibonacciScene.ts
import { _ModuleSupport as _ModuleSupport79 } from "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 } = _ModuleSupport79;
var FibonacciScene = class extends AnnotationScene {
constructor() {
super();
this.trendLine = new CollidableLine();
this.rangeFillsGroup = new _ModuleSupport79.Group({
name: `${this.id}-range-fills`
});
this.rangeFillsGroupSelection = _ModuleSupport79.Selection.select(this.rangeFillsGroup, _ModuleSupport79.Range);
this.rangeStrokesGroup = new _ModuleSupport79.Group({
name: `${this.id}-range-strokes`
});
this.rangeStrokesGroupSelection = _ModuleSupport79.Selection.select(this.rangeStrokesGroup, CollidableLine);
this.labelsGroup = new _ModuleSupport79.Group({
name: `${this.id}-ranges-labels`
});
this.labelsGroupSelection = _ModuleSupport79.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, _ModuleSupport79.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 } = _ModuleSupport80;
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
import { _ModuleSupport as _ModuleSupport81 } from "ag-charts-community";
var { StateMachine: StateMachine7, StateMachineProperty: StateMachineProperty7, Debug: Debug7 } = _ModuleSupport81;
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
import { _ModuleSupport as _ModuleSupport82 } from "ag-charts-community";
var { Vec2: Vec213, Vec4: Vec49 } = _ModuleSupport82;
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
import { _ModuleSupport as _ModuleSupport83 } from "ag-charts-community";
var { StateMachine: StateMachine8, StateMachineProperty: StateMachineProperty8, Debug: Debug8 } = _ModuleSupport83;
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
import { _ModuleSupport as _ModuleSupport85 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/scenes/capScene.ts
import { _ModuleSupport as _ModuleSupport84 } from "ag-charts-community";
var { Vec2: Vec214 } = _ModuleSupport84;
var CapScene = class extends _ModuleSupport84.Group {
};
var ArrowCapScene = class extends CapScene {
constructor() {
super();
this.type = "arrow";
this.path = new _ModuleSupport84.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 } = _ModuleSupport85;
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, _ModuleSupport85.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
import { _ModuleSupport as _ModuleSupport88 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/measurer/measurerStatisticsScene.ts
import { _ModuleSupport as _ModuleSupport87 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/annotations/utils/layout.ts
import { _ModuleSupport as _ModuleSupport86 } from "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 += _ModuleSupport86.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 += _ModuleSupport86.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 } = _ModuleSupport87;
var MeasurerStatisticsScene = class extends _ModuleSupport87.Group {
constructor() {
super();
this.name = "MeasurerStatisticsScene";
this.background = new _ModuleSupport87.Rect();
this.dateRangeBarsText = new _ModuleSupport87.Text();
this.dateRangeDivider = new _ModuleSupport87.Line();
this.dateRangeValueText = new _ModuleSupport87.Text();
this.priceRangeValueText = new _ModuleSupport87.Text();
this.priceRangeDivider = new _ModuleSupport87.Line();
this.priceRangePercentageText = new _ModuleSupport87.Text();
this.volumeText = new _ModuleSupport87.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 = _ModuleSupport87.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 _ModuleSupport87.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 = _ModuleSupport87.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 } = _ModuleSupport88;
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 _ModuleSupport88.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, _ModuleSupport88.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
import { _ModuleSupport as _ModuleSupport89 } from "ag-charts-community";
var { StateMachine: StateMachine9, StateMachineProperty: StateMachineProperty9, Debug: Debug9 } = _ModuleSupport89;
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
import { _ModuleSupport as _ModuleSupport90 } from "ag-charts-community";
var { ZIndexMap: ZIndexMap3, TextWrapper: TextWrapper3, clamp: clamp4 } = _ModuleSupport90;
var NoteScene = class extends TextualPointScene {
constructor() {
super();
this.type = "note" /* Note */;
this.shape = new _ModuleSupport90.Rect();
this.iconBackground = new _ModuleSupport90.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 _ModuleSupport90.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 _ModuleSupport90.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
import { _ModuleSupport as _ModuleSupport91 } from "ag-charts-community";
var { Vec2: Vec217, Vec4: Vec413 } = _ModuleSupport91;
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
import { _ModuleSupport as _ModuleSupport92 } from "ag-charts-community";
var { StateMachine: StateMachine10, StateMachineProperty: StateMachineProperty10, Debug: Debug10 } = _ModuleSupport92;
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
import { _ModuleSupport as _ModuleSupport93 } from "ag-charts-community";
var { ActionOnSet, ParallelStateMachine, StateMachine: StateMachine11, StateMachineProperty: StateMachineProperty11, Debug: Debug11 } = _ModuleSupport93;
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
import { _ModuleSupport as _ModuleSupport94 } from "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
} = _ModuleSupport94;
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 _ModuleSupport94.BaseProperties {
constructor(ctx) {
super();
this.ctx = ctx;
this.enabled = true;
this.padding = 20;
this.buttons = new PropertiesArray2(AnnotationsToolbarButtonProperties);
this.events = new _ModuleSupport94.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
import { _ModuleSupport as _ModuleSupport95, _Widget } from "ag-charts-community";
var { BaseModuleInstance, InteractionState, Validate: Validate31, BOOLEAN: BOOLEAN10, ChartAxisDirection: ChartAxisDirection10, getIconClassNames } = _ModuleSupport95;
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 _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
import { _ModuleSupport as _ModuleSupport97 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/components/dialog/dialog.ts
import { _ModuleSupport as _ModuleSupport96 } from "ag-charts-community";
var {
Color: Color5,
DraggablePopover,
NativeWidget,
Vec2: Vec218,
createButton,
createCheckbox,
createElementId,
createSelect,
createTextArea,
initRovingTabIndex,
getIconClassNames: getIconClassNames2,
mapValues,
setAttribute,
setAttributes,
createElement: createElement2,
getWindow
} = _ModuleSupport96;
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 } = _ModuleSupport97;
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
} = _ModuleSupport98;
var _Annotations = class _Annotations extends _ModuleSupport98.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 _ModuleSupport98.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 === _ModuleSupport98.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
import {
_ModuleSupport as _ModuleSupport99
} from "ag-charts-community";
var { FONT_SIZE_RATIO, ThemeSymbols } = _ModuleSupport99;
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
import { _ModuleSupport as _ModuleSupport101 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/image/image.ts
import { _ModuleSupport as _ModuleSupport100 } from "ag-charts-community";
var {
BaseProperties: BaseProperties12,
ObserveChanges: ObserveChanges3,
ProxyProperty,
Validate: Validate33,
NUMBER: NUMBER9,
POSITIVE_NUMBER: POSITIVE_NUMBER6,
RATIO: RATIO5,
calculatePlacement,
createElement: createElement3
} = _ModuleSupport100;
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 _ModuleSupport100.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 } = _ModuleSupport101;
var Background2 = class extends _ModuleSupport101.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(_ModuleSupport101.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
import "ag-charts-community";
// packages/ag-charts-enterprise/src/features/chart-toolbar/chartToolbar.ts
import { _ModuleSupport as _ModuleSupport102 } from "ag-charts-community";
var { BOOLEAN: BOOLEAN12, ActionOnSet: ActionOnSet4, LayoutElement: LayoutElement2, Menu: Menu3, Validate: Validate35 } = _ModuleSupport102;
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 _ModuleSupport102.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
import { _ModuleSupport as _ModuleSupport104 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/context-menu/contextMenu.ts
import { _ModuleSupport as _ModuleSupport103 } from "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 } = _ModuleSupport103;
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 _ModuleSupport103.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(_ModuleSupport103.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(_ModuleSupport103.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 = _ModuleSupport103.clamp(0, x, canvasRect.width - width);
y = _ModuleSupport103.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: _ModuleSupport104.ThemeSymbols.IS_DARK_THEME
}
}
};
// packages/ag-charts-enterprise/src/features/crosshair/crosshairModule.ts
import "ag-charts-community";
// packages/ag-charts-enterprise/src/features/crosshair/crosshair.ts
import { _ModuleSupport as _ModuleSupport106 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/crosshair/crosshairLabel.ts
import { _ModuleSupport as _ModuleSupport105 } from "ag-charts-community";
var { BaseProperties: BaseProperties13, BOOLEAN: BOOLEAN14, FUNCTION: FUNCTION2, NUMBER: NUMBER10, STRING: STRING19, Validate: Validate37, createId: createId2, setAttribute: setAttribute2 } = _ModuleSupport105;
var DEFAULT_LABEL_CLASS = "ag-charts-crosshair-label";
var CrosshairLabelProperties = class extends _ModuleSupport105.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 _ModuleSupport105.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
} = _ModuleSupport106;
var Crosshair = class extends _ModuleSupport106.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 = _ModuleSupport106.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(_ModuleSupport106.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(_ModuleSupport106.ChartUpdateType.SCENE_RENDER);
}
onMouseOut() {
if (!this.ctx.interactionManager.isState(InteractionState3.Clickable))
return;
this.hideCrosshairs();
this.ctx.updateService.update(_ModuleSupport106.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
import { _ModuleSupport as _ModuleSupport108 } from "ag-charts-community";
var { BOOLEAN: BOOLEAN16, FUNCTION: FUNCTION3, ActionOnSet: ActionOnSet5, Validate: Validate39 } = _ModuleSupport108;
var DataSource = class extends _ModuleSupport108.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
import { AgErrorBarSupportedSeriesTypes as AgErrorBarSupportedSeriesTypes2 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/error-bar/errorBar.ts
import { AgErrorBarSupportedSeriesTypes, _ModuleSupport as _ModuleSupport111 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/error-bar/errorBarNode.ts
import { _ModuleSupport as _ModuleSupport109 } from "ag-charts-community";
var { nearestSquaredInContainer, partialAssign, mergeDefaults, BBox: BBox5 } = _ModuleSupport109;
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 _ModuleSupport109.Group {
constructor() {
super();
this.capLength = NaN;
this._datum = void 0;
this.whiskerPath = new _ModuleSupport109.Path();
this.capsPath = new _ModuleSupport109.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 _ModuleSupport109.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
import {
_ModuleSupport as _ModuleSupport110
} from "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
} = _ModuleSupport110;
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 } = _ModuleSupport111;
function toErrorBoundCartesianSeries(ctx) {
for (const supportedType of 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: ${AgErrorBarSupportedSeriesTypes.join(", ")}`
);
}
var ErrorBars = class _ErrorBars extends _ModuleSupport111.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 = _ModuleSupport111.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
import "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: AgErrorBarSupportedSeriesTypes2,
moduleFactory: (ctx) => new ErrorBars(ctx),
themeTemplate: ERROR_BARS_THEME
};
// packages/ag-charts-enterprise/src/features/foreground/foreground.ts
import { _ModuleSupport as _ModuleSupport113 } from "ag-charts-community";
var { ZIndexMap: ZIndexMap5, ActionOnSet: ActionOnSet6, Validate: Validate41, ProxyPropertyOnWrite: ProxyPropertyOnWrite2, OBJECT: OBJECT18, RATIO: RATIO8, COLOR_STRING: COLOR_STRING6 } = _ModuleSupport113;
var Foreground = class extends _ModuleSupport113.Background {
constructor() {
super(...arguments);
this.image = new Image();
this.fill = "transparent";
this.fillOpacity = void 0;
}
createNode() {
return new _ModuleSupport113.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(_ModuleSupport113.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
import { _ModuleSupport as _ModuleSupport121 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/navigator/navigator.ts
import { _ModuleSupport as _ModuleSupport120 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/navigator/miniChart.ts
import { _ModuleSupport as _ModuleSupport115 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/navigator/shapes/miniChartGroup.ts
import { _ModuleSupport as _ModuleSupport114 } from "ag-charts-community";
var { TranslatableGroup: TranslatableGroup2, ScenePathChangeDetection } = _ModuleSupport114;
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
} = _ModuleSupport115;
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 _ModuleSupport115.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
import { _ModuleSupport as _ModuleSupport116 } from "ag-charts-community";
var { clamp: clamp5, SliderWidget } = _ModuleSupport116;
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
import { _ModuleSupport as _ModuleSupport117 } from "ag-charts-community";
var { Validate: Validate43, ScenePathChangeDetection: ScenePathChangeDetection2, POSITIVE_NUMBER: POSITIVE_NUMBER10, BOOLEAN: BOOLEAN19, BBox: BBox7, ExtendedPath2D } = _ModuleSupport117;
var RangeHandle = class extends _ModuleSupport117.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
import { _ModuleSupport as _ModuleSupport118 } from "ag-charts-community";
var { Path: Path6, BBox: BBox8, ExtendedPath2D: ExtendedPath2D2, clippedRoundRect, POSITIVE_NUMBER: POSITIVE_NUMBER11, Validate: Validate44, ScenePathChangeDetection: ScenePathChangeDetection3 } = _ModuleSupport118;
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
import { _ModuleSupport as _ModuleSupport119 } from "ag-charts-community";
var RangeSelector = class extends _ModuleSupport119.Group {
constructor(children) {
super({ name: "rangeSelectorGroup", zIndex: _ModuleSupport119.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 _ModuleSupport119.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 _ModuleSupport119.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 } = _ModuleSupport120;
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(
_ModuleSupport120.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(_ModuleSupport120.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: [_ModuleSupport121.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
import { _ModuleSupport as _ModuleSupport123 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/ranges/rangesButtonProperties.ts
import { _ModuleSupport as _ModuleSupport122 } from "ag-charts-community";
var { AND: AND4, ARRAY: ARRAY4, FUNCTION: FUNCTION5, NUMBER: NUMBER12, OR: OR3, ToolbarButtonProperties: ToolbarButtonProperties3, Validate: Validate46 } = _ModuleSupport122;
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 } = _ModuleSupport123;
var Ranges = class extends _ModuleSupport123.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
import "ag-charts-community";
// packages/ag-charts-enterprise/src/features/shared-toolbar/sharedToolbar.ts
import { _ModuleSupport as _ModuleSupport124 } from "ag-charts-community";
var _SharedToolbar = class _SharedToolbar extends _ModuleSupport124.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 _ModuleSupport124.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
import { _ModuleSupport as _ModuleSupport126 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/status-bar/statusBar.ts
import { _ModuleSupport as _ModuleSupport125 } from "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
} = _ModuleSupport125;
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 _ModuleSupport125.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 _ModuleSupport125.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: _ModuleSupport126.ThemeSymbols.DEFAULT_CAPTION_LAYOUT_STYLE,
title: {
color: { $ref: "textColor" },
fontFamily: { $ref: "fontFamily" },
fontSize: { $ref: "fontSize" },
fontWeight: { $ref: "fontWeight" }
},
positive: {
color: _ModuleSupport126.ThemeSymbols.PALETTE_UP_STROKE,
fontFamily: { $ref: "fontFamily" },
fontSize: { $ref: "fontSize" },
fontWeight: { $ref: "fontWeight" }
},
negative: {
color: _ModuleSupport126.ThemeSymbols.PALETTE_DOWN_STROKE,
fontFamily: { $ref: "fontFamily" },
fontSize: { $ref: "fontSize" },
fontWeight: { $ref: "fontWeight" }
},
neutral: {
color: _ModuleSupport126.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
import { _ModuleSupport as _ModuleSupport127 } from "ag-charts-community";
var {
BOOLEAN: BOOLEAN23,
STRING: STRING22,
UNION: UNION7,
BaseProperties: BaseProperties16,
CartesianAxis: CartesianAxis2,
ChartUpdateType: ChartUpdateType2,
ObserveChanges: ObserveChanges5,
TooltipManager,
Validate: Validate49
} = _ModuleSupport127;
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
import { _ModuleSupport as _ModuleSupport137 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/zoom/scenes/zoomRect.ts
import { _ModuleSupport as _ModuleSupport128 } from "ag-charts-community";
var { COLOR_STRING: COLOR_STRING8, RATIO: RATIO10, Validate: Validate50 } = _ModuleSupport128;
var VALID_COLOR = "#2196f3";
var INVALID_COLOR = "#8a8a8a";
var ZoomRect = class extends _ModuleSupport128.Rect {
constructor() {
super(...arguments);
this.fill = VALID_COLOR;
this.fillOpacity = 0.2;
this.zIndex = _ModuleSupport128.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
import { _ModuleSupport as _ModuleSupport130 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/features/zoom/zoomUtils.ts
import { _ModuleSupport as _ModuleSupport129 } from "ag-charts-community";
var { UNION: UNION8, clamp: clamp7, isNumberEqual: isNumberEqual8, round } = _ModuleSupport129;
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 === _ModuleSupport130.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 === _ModuleSupport130.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 === _ModuleSupport130.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
import { _ModuleSupport as _ModuleSupport131 } from "ag-charts-community";
var { BBoxValues } = _ModuleSupport131;
var ZoomDOMProxy = class {
constructor(axesHandlers) {
this.axesHandlers = axesHandlers;
this.axes = [];
}
initAxis(ctx, axisId, handlers, direction) {
const { X, Y } = _ModuleSupport131.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 } = _ModuleSupport131.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
import { _ModuleSupport as _ModuleSupport132 } from "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 = _ModuleSupport132.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
import { _ModuleSupport as _ModuleSupport133 } from "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 !== _ModuleSupport133.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
import { _ModuleSupport as _ModuleSupport134 } from "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 === _ModuleSupport134.ChartAxisDirection.X && isScalingX) {
newZoom.max += delta4;
newZoom = scaleZoomAxisWithAnchor(newZoom, zoom, anchorPointX, origin.x);
} else if (direction === _ModuleSupport134.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
import { _ModuleSupport as _ModuleSupport135 } from "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
} = _ModuleSupport135;
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
import "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
} = _ModuleSupport137;
var round2 = (value) => sharedRound(value, 10);
var CURSOR_ID = "zoom-cursor";
var TOOLTIP_ID = "zoom-tooltip";
var ZoomAutoScaling = class extends _ModuleSupport137.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 _ModuleSupport137.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(_ModuleSupport137.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(_ModuleSupport137.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(_ModuleSupport137.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 === _ModuleSupport137.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
import "ag-charts-community";
// packages/ag-charts-enterprise/src/gradient-legend/gradientLegend.ts
import { _ModuleSupport as _ModuleSupport138 } from "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
} = _ModuleSupport138;
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
import { _ModuleSupport as _ModuleSupport140 } from "ag-charts-community";
function injectWatermark(domManager, text2) {
const element = domManager.addChild("canvas-overlay", "watermark");
const textElement = _ModuleSupport140.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
import { _ModuleSupport as _ModuleSupport144 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/bar/barSeries.ts
import { _ModuleSupport as _ModuleSupport143 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/bar/barAggregation.ts
import "ag-charts-community";
// packages/ag-charts-enterprise/src/utils/aggregation.ts
import { _ModuleSupport as _ModuleSupport141 } from "ag-charts-community";
var { findMinMax: findMinMax2 } = _ModuleSupport141;
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 } = _ModuleSupport143;
var BarSeries = class extends _ModuleSupport143.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 } = _ModuleSupport144;
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
import { _ModuleSupport as _ModuleSupport149 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeries.ts
import { _ModuleSupport as _ModuleSupport147 } from "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
import { _ModuleSupport as _ModuleSupport145 } from "ag-charts-community";
var { ScalableGroup, Rect: Rect3, Line: Line4, BBox: BBox9, Selection: Selection3 } = _ModuleSupport145;
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 _ModuleSupport145.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
import { _ModuleSupport as _ModuleSupport146 } from "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
} = _ModuleSupport146;
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
} = _ModuleSupport147;
var BoxPlotSeriesNodeEvent = class extends _ModuleSupport147.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 _ModuleSupport147.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
import { _ModuleSupport as _ModuleSupport148 } from "ag-charts-community";
var { CARTESIAN_AXIS_TYPE } = _ModuleSupport148.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 }
} = _ModuleSupport149;
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
import { _ModuleSupport as _ModuleSupport157 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/candlestick/candlestickSeries.ts
import { _ModuleSupport as _ModuleSupport155 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesBase.ts
import {
_ModuleSupport as _ModuleSupport150
} from "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
} = _ModuleSupport150;
var OhlcSeriesNodeEvent = class extends _ModuleSupport150.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 _ModuleSupport150.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
import { _ModuleSupport as _ModuleSupport152 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/ohlc/ohlcNode.ts
import { _ModuleSupport as _ModuleSupport151 } from "ag-charts-community";
var { Path: Path7, ScenePathChangeDetection: ScenePathChangeDetection4, BBox: BBox10 } = _ModuleSupport151;
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 } = _ModuleSupport152;
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
import { _ModuleSupport as _ModuleSupport154 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport153 } from "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
} = _ModuleSupport153;
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 } = _ModuleSupport154;
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 } = _ModuleSupport155;
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 _ModuleSupport155.LinearGradient(
"rgb",
[
{ color: up.fill, offset: 0 },
{ color: up.fill, offset: 0.5 },
{ color: down.fill, offset: 0.5 }
],
90
);
const stroke2 = new _ModuleSupport155.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
import { _ModuleSupport as _ModuleSupport156 } from "ag-charts-community";
var { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE3 } = _ModuleSupport156.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 } = _ModuleSupport157.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
import "ag-charts-community";
// packages/ag-charts-enterprise/src/series/chord/chordSeries.ts
import { _ModuleSupport as _ModuleSupport161 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/flow-proportion/flowProportionSeries.ts
import { _ModuleSupport as _ModuleSupport158 } from "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 } = _ModuleSupport158;
var FlowProportionSeriesNodeEvent = class extends _ModuleSupport158.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
import { _ModuleSupport as _ModuleSupport159 } from "ag-charts-community";
var { BBox: BBox11, Path: Path8, ScenePathChangeDetection: ScenePathChangeDetection6 } = _ModuleSupport159;
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
import {
_ModuleSupport as _ModuleSupport160
} from "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
} = _ModuleSupport160;
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
} = _ModuleSupport161;
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
import { _ModuleSupport as _ModuleSupport170 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/funnel/funnelThemes.ts
import { _ModuleSupport as _ModuleSupport163 } from "ag-charts-community";
var {
ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE5, CARTESIAN_POSITION: CARTESIAN_POSITION3 },
ThemeSymbols: { DEFAULT_SHADOW_COLOUR }
} = _ModuleSupport163;
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
import { _ModuleSupport as _ModuleSupport168 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/funnel/baseFunnelSeries.ts
import { _ModuleSupport as _ModuleSupport166 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/funnel/funnelConnector.ts
import { _ModuleSupport as _ModuleSupport164 } from "ag-charts-community";
var { lineDistanceSquared, BBox: BBox12, Path: Path9, ScenePathChangeDetection: ScenePathChangeDetection7 } = _ModuleSupport164;
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
import { _ModuleSupport as _ModuleSupport165 } from "ag-charts-community";
var { NODE_UPDATE_STATE_TO_PHASE_MAPPING } = _ModuleSupport165;
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
} = _ModuleSupport166;
var FunnelSeriesNodeEvent = class extends _ModuleSupport166.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 _ModuleSupport166.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
import { _ModuleSupport as _ModuleSupport167 } from "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
} = _ModuleSupport167;
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 } = _ModuleSupport168;
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
import { _ModuleSupport as _ModuleSupport169 } from "ag-charts-community";
var {
ThemeConstants: { CARTESIAN_AXIS_TYPE: CARTESIAN_AXIS_TYPE6 }
} = _ModuleSupport169;
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(
_ModuleSupport170.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
import { _ModuleSupport as _ModuleSupport172 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/funnel/funnelProperties.ts
import { _ModuleSupport as _ModuleSupport171 } from "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
} = _ModuleSupport171;
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
} = _ModuleSupport172;
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
import { _ModuleSupport as _ModuleSupport178 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/heatmap/heatmapSeries.ts
import { _ModuleSupport as _ModuleSupport176 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/util/labelFormatter.ts
import { _ModuleSupport as _ModuleSupport173 } from "ag-charts-community";
var { CachedTextMeasurerPool: CachedTextMeasurerPool4, TextUtils: TextUtils5, TextWrapper: TextWrapper5 } = _ModuleSupport173;
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
import { _ModuleSupport as _ModuleSupport175 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/util/autoSizedLabel.ts
import { _ModuleSupport as _ModuleSupport174 } from "ag-charts-community";
var { Validate: Validate61, NUMBER: NUMBER14, POSITIVE_NUMBER: POSITIVE_NUMBER21, TEXT_WRAP, OVERFLOW_STRATEGY } = _ModuleSupport174;
var BaseAutoSizedLabel = class extends _ModuleSupport174.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
} = _ModuleSupport175;
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
} = _ModuleSupport176;
var HeatmapSeriesNodeEvent = class extends _ModuleSupport176.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 _ModuleSupport176.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
import "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 }
} = _ModuleSupport178;
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
import { _ModuleSupport as _ModuleSupport181 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/line/lineSeries.ts
import { _ModuleSupport as _ModuleSupport180 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/line/lineAggregation.ts
import "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 } = _ModuleSupport180;
var LineSeries = class extends _ModuleSupport180.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 } = _ModuleSupport181;
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
import { _ModuleSupport as _ModuleSupport189 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/gauge-util/defaultColorStops.ts
import { _ModuleSupport as _ModuleSupport182 } from "ag-charts-community";
var { ColorScale: ColorScale2 } = _ModuleSupport182;
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
import {
_ModuleSupport as _ModuleSupport188
} from "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
import "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
import { _ModuleSupport as _ModuleSupport183 } from "ag-charts-community";
var { clamp: clamp8 } = _ModuleSupport183;
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
import { _ModuleSupport as _ModuleSupport184 } from "ag-charts-community";
var { MARKER_SHAPE, UNION: UNION13, OR: OR5 } = _ModuleSupport184;
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
import { _ModuleSupport as _ModuleSupport186 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/gauge-util/segmentation.ts
import { _ModuleSupport as _ModuleSupport185 } from "ag-charts-community";
var { BaseProperties: BaseProperties24, Validate: Validate63, OBJECT: OBJECT30, BOOLEAN: BOOLEAN28, NUMBER: NUMBER15, NUMBER_ARRAY } = _ModuleSupport185;
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
} = _ModuleSupport186;
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(_ModuleSupport186.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(_ModuleSupport186.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
import {
_ModuleSupport as _ModuleSupport187
} from "ag-charts-community";
var { CachedTextMeasurerPool: CachedTextMeasurerPool5, BBox: BBox13 } = _ModuleSupport187;
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
} = _ModuleSupport188;
var horizontalTargetPlacementRotation = {
before: 180,
middle: 0,
after: 0
};
var verticalTargetPlacementRotation = {
before: 90,
middle: 0,
after: -90
};
var LinearGaugeSeries = class extends _ModuleSupport188.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 ? _ModuleSupport188.PointerEvents.All : _ModuleSupport188.PointerEvents.None;
if (animationDisabled || rect.previousDatum == null) {
rect.setProperties(resetLinearGaugeSeriesResetRectFunction(rect, datum));
}
});
this.datumUnion.update(datumSelection, this.itemGroup, _ModuleSupport188.Rect, (node, first, last) => {
node.pointerEvents = _ModuleSupport188.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 }
} = _ModuleSupport189;
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
import { _ModuleSupport as _ModuleSupport196 } from "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
import { _ModuleSupport as _ModuleSupport195 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/map-util/geoGeometry.ts
import { _ModuleSupport as _ModuleSupport191 } from "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
import { _ModuleSupport as _ModuleSupport190 } from "ag-charts-community";
var { LonLatBBox } = _ModuleSupport190;
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 } = _ModuleSupport191;
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
import { _ModuleSupport as _ModuleSupport192 } from "ag-charts-community";
var TopologySeriesProperties = class extends _ModuleSupport192.SeriesProperties {
};
var TopologySeries = class extends _ModuleSupport192.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
import { _ModuleSupport as _ModuleSupport193 } from "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 = _ModuleSupport193.predicateWithMessage(isValidFeatureCollection, "a GeoJSON object");
// packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport194 } from "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 } = _ModuleSupport194;
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 } = _ModuleSupport195;
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 } = _ModuleSupport196.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
import { _ModuleSupport as _ModuleSupport199 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/map-line/mapLineSeries.ts
import { _ModuleSupport as _ModuleSupport198 } from "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
import { _ModuleSupport as _ModuleSupport197 } from "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
} = _ModuleSupport197;
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
} = _ModuleSupport198;
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 = _ModuleSupport198.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 } = _ModuleSupport199.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 } = _ModuleSupport199.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
import { _ModuleSupport as _ModuleSupport202 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeries.ts
import { _ModuleSupport as _ModuleSupport201 } from "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
import { _ModuleSupport as _ModuleSupport200 } from "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
} = _ModuleSupport200;
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
} = _ModuleSupport201;
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 = _ModuleSupport201.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 } = _ModuleSupport202.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 } = _ModuleSupport202.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
import { _ModuleSupport as _ModuleSupport205 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeries.ts
import { _ModuleSupport as _ModuleSupport204 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport203 } from "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 } = _ModuleSupport203;
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 } = _ModuleSupport204;
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 } = _ModuleSupport205.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
import { _ModuleSupport as _ModuleSupport208 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeries.ts
import { _ModuleSupport as _ModuleSupport207 } from "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
import { _ModuleSupport as _ModuleSupport206 } from "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
} = _ModuleSupport206;
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
} = _ModuleSupport207;
var fixedScale = _ModuleSupport207.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 } = _ModuleSupport208.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 } = _ModuleSupport208.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
import { _ModuleSupport as _ModuleSupport215 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/nightingale/nightingaleSeries.ts
import { _ModuleSupport as _ModuleSupport213 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesBase.ts
import { _ModuleSupport as _ModuleSupport209 } from "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
} = _ModuleSupport209;
var RadialColumnSeriesNodeEvent = class extends _ModuleSupport209.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 _ModuleSupport209.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
import { _ModuleSupport as _ModuleSupport210 } from "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
} = _ModuleSupport210;
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
import { _ModuleSupport as _ModuleSupport212 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-column/radialColumnUtil.ts
import { _ModuleSupport as _ModuleSupport211 } from "ag-charts-community";
var { motion: motion5 } = _ModuleSupport211;
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 } = _ModuleSupport212;
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 } = _ModuleSupport213;
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
import { _ModuleSupport as _ModuleSupport214 } from "ag-charts-community";
var {
ThemeConstants: { POLAR_AXIS_TYPE, POLAR_AXIS_SHAPE }
} = _ModuleSupport214;
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 }
} = _ModuleSupport215;
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
import { _ModuleSupport as _ModuleSupport217 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeries.ts
import { _ModuleSupport as _ModuleSupport216 } from "ag-charts-community";
var { createDatumId: createDatumId15 } = _ModuleSupport216;
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 _ModuleSupport216.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 } = _ModuleSupport217.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
import "ag-charts-community";
// packages/ag-charts-enterprise/src/series/pyramid/pyramidSeries.ts
import {
_ModuleSupport as _ModuleSupport219
} from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/pyramid/pyramidProperties.ts
import { _ModuleSupport as _ModuleSupport218 } from "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
} = _ModuleSupport218;
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
} = _ModuleSupport219;
var PyramidSeries = class extends _ModuleSupport219.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
import { _ModuleSupport as _ModuleSupport220 } from "ag-charts-community";
var {
ThemeSymbols: { DEFAULT_SHADOW_COLOUR: DEFAULT_SHADOW_COLOUR2 }
} = _ModuleSupport220;
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
import { _ModuleSupport as _ModuleSupport226 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radar/radarThemes.ts
import { _ModuleSupport as _ModuleSupport221 } from "ag-charts-community";
var {
ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE3 }
} = _ModuleSupport221;
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 = _ModuleSupport221.mergeDefaults({ series: { strokeWidth: 2 } }, BASE_RADAR_SERIES_THEME);
var RADAR_AREA_SERIES_THEME = _ModuleSupport221.mergeDefaults(
{
series: {
fillOpacity: 0.8,
strokeWidth: 2,
marker: { enabled: false }
}
},
BASE_RADAR_SERIES_THEME
);
// packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeries.ts
import { _ModuleSupport as _ModuleSupport225 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radar/radarSeries.ts
import {
_ModuleSupport as _ModuleSupport223
} from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radar/radarSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport222 } from "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
} = _ModuleSupport222;
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
} = _ModuleSupport223;
var RadarSeriesNodeEvent = class extends _ModuleSupport223.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 _ModuleSupport223.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: _ModuleSupport223.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 = [
_ModuleSupport223.SeriesZIndexMap.ANY_CONTENT,
index,
_ModuleSupport223.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
import { _ModuleSupport as _ModuleSupport224 } from "ag-charts-community";
var { RATIO: RATIO28, COLOR_STRING: COLOR_STRING23, Validate: Validate78 } = _ModuleSupport224;
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 } = _ModuleSupport225;
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 _ModuleSupport225.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 }
} = _ModuleSupport226;
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
import { _ModuleSupport as _ModuleSupport227 } from "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 } = _ModuleSupport227.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
import { _ModuleSupport as _ModuleSupport232 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeries.ts
import { _ModuleSupport as _ModuleSupport230 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport228 } from "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
} = _ModuleSupport228;
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
import { _ModuleSupport as _ModuleSupport229 } from "ag-charts-community";
var { SectorBox: SectorBox3, motion: motion7 } = _ModuleSupport229;
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
} = _ModuleSupport230;
var RadialBarSeriesNodeEvent = class extends _ModuleSupport230.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 _ModuleSupport230.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
import { _ModuleSupport as _ModuleSupport231 } from "ag-charts-community";
var {
ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE6 }
} = _ModuleSupport231;
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 } = _ModuleSupport232.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
import { _ModuleSupport as _ModuleSupport236 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeries.ts
import { _ModuleSupport as _ModuleSupport234 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport233 } from "ag-charts-community";
var { Validate: Validate80, RATIO: RATIO30 } = _ModuleSupport233;
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 } = _ModuleSupport234;
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
import { _ModuleSupport as _ModuleSupport235 } from "ag-charts-community";
var {
ThemeConstants: { POLAR_AXIS_TYPE: POLAR_AXIS_TYPE8, POLAR_AXIS_SHAPE: POLAR_AXIS_SHAPE2 }
} = _ModuleSupport235;
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 } = _ModuleSupport236.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
import { _ModuleSupport as _ModuleSupport241 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeSeries.ts
import {
_ModuleSupport as _ModuleSupport240
} from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeNeedle.ts
import { _ModuleSupport as _ModuleSupport237 } from "ag-charts-community";
var { SvgPath, Rotatable, Translatable, Scalable } = _ModuleSupport237;
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
import { _ModuleSupport as _ModuleSupport238 } from "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
} = _ModuleSupport238;
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(_ModuleSupport238.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(_ModuleSupport238.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
import { _ModuleSupport as _ModuleSupport239 } from "ag-charts-community";
var { SectorBox: SectorBox5 } = _ModuleSupport239;
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
} = _ModuleSupport240;
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 _ModuleSupport240.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 ? _ModuleSupport240.PointerEvents.All : _ModuleSupport240.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, _ModuleSupport240.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 = _ModuleSupport240.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 }
} = _ModuleSupport241;
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
import { _ModuleSupport as _ModuleSupport246 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/range-area/rangeArea.ts
import {
_ModuleSupport as _ModuleSupport244
} from "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
import { _ModuleSupport as _ModuleSupport242 } from "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
} = _ModuleSupport242;
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
import { _ModuleSupport as _ModuleSupport243 } from "ag-charts-community";
var {
CollapseMode,
isScaleValid,
pairUpSpans,
prepareAreaFillAnimationFns,
plotInterpolatedLinePathStroke,
prepareLinePathPropertyAnimation,
areScalingEqual
} = _ModuleSupport243;
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
} = _ModuleSupport244;
var RangeAreaSeriesNodeEvent = class extends _ModuleSupport244.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 _ModuleSupport244.CartesianSeries {
constructor(moduleCtx) {
super({
moduleCtx,
hasMarkers: true,
pathsPerSeries: ["fill", "stroke"],
pickModes: [_ModuleSupport244.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
import { _ModuleSupport as _ModuleSupport245 } from "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: {
[_ModuleSupport245.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 }
} = _ModuleSupport246;
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
import { _ModuleSupport as _ModuleSupport250 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/range-bar/rangeBarSeries.ts
import { _ModuleSupport as _ModuleSupport248 } from "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
import { _ModuleSupport as _ModuleSupport247 } from "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
} = _ModuleSupport247;
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
} = _ModuleSupport248;
var RangeBarSeriesNodeEvent = class extends _ModuleSupport248.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 _ModuleSupport248.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
import { _ModuleSupport as _ModuleSupport249 } from "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: {
[_ModuleSupport249.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 } = _ModuleSupport250.ThemeConstants;
var RangeBarModule = {
type: "series",
optionsKey: "series[]",
packageType: "enterprise",
chartTypes: ["cartesian"],
identifier: "range-bar",
moduleFactory: (ctx) => new RangeBarSeries(ctx),
tooltipDefaults: { range: "exact" },
defaultAxes: _ModuleSupport250.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
import "ag-charts-community";
// packages/ag-charts-enterprise/src/series/sankey/sankeySeries.ts
import { _ModuleSupport as _ModuleSupport253 } from "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
import { _ModuleSupport as _ModuleSupport251 } from "ag-charts-community";
var { BBox: BBox20, Path: Path13, ScenePathChangeDetection: ScenePathChangeDetection9, splitBezier } = _ModuleSupport251;
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
import {
_ModuleSupport as _ModuleSupport252
} from "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
} = _ModuleSupport252;
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
} = _ModuleSupport253;
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
import { _ModuleSupport as _ModuleSupport257 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/sunburst/sunburstSeries.ts
import { _ModuleSupport as _ModuleSupport256 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/sunburst/sunburstSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport255 } from "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
} = _ModuleSupport255;
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
} = _ModuleSupport256;
var SunburstNode = class extends _ModuleSupport256.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 _ModuleSupport256.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 }
} = _ModuleSupport257;
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
import { _ModuleSupport as _ModuleSupport260 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/treemap/treemapSeries.ts
import {
_ModuleSupport as _ModuleSupport259
} from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/treemap/treemapSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport258 } from "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
} = _ModuleSupport258;
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
} = _ModuleSupport259;
var TreemapNode = class extends _ModuleSupport259.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 _ModuleSupport259.Group {
distanceSquared(x, y) {
return this.getBBox().distanceSquared(x, y);
}
};
var TreemapSeries = class extends _ModuleSupport259.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 }
} = _ModuleSupport260;
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
import { _ModuleSupport as _ModuleSupport264 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/waterfall/waterfallSeries.ts
import { _ModuleSupport as _ModuleSupport262 } from "ag-charts-community";
// packages/ag-charts-enterprise/src/series/waterfall/waterfallSeriesProperties.ts
import { _ModuleSupport as _ModuleSupport261 } from "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
} = _ModuleSupport261;
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
} = _ModuleSupport262;
var WaterfallSeries = class extends _ModuleSupport262.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 ? [_ModuleSupport262.SMALLEST_KEY_INTERVAL, _ModuleSupport262.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: _ModuleSupport262.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: _ModuleSupport262.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: _ModuleSupport262.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
import { _ModuleSupport as _ModuleSupport263 } from "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: _ModuleSupport263.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 } = _ModuleSupport264;
var WaterfallModule = {
type: "series",
optionsKey: "series[]",
packageType: "enterprise",
chartTypes: ["cartesian"],
identifier: "waterfall",
solo: true,
moduleFactory: (ctx) => new WaterfallSeries(ctx),
tooltipDefaults: { range: "exact" },
defaultAxes: _ModuleSupport264.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
_ModuleSupport265.ModuleRegistry.registerMany([
FlowProportionChartModule,
GaugeChartModule,
HierarchyChartModule,
StandaloneChartModule,
TopologyChartModule
]);
function setupEnterpriseModules() {
_ModuleSupport265.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
);
_ModuleSupport265.enterpriseModule.isEnterprise = true;
_ModuleSupport265.enterpriseModule.styles = styles_default;
_ModuleSupport265.enterpriseModule.licenseManager = (options) => new LicenseManager(
options.container?.ownerDocument ?? (typeof document === "undefined" ? void 0 : document)
);
_ModuleSupport265.enterpriseModule.injectWatermark = injectWatermark;
}
// packages/ag-charts-enterprise/src/main.ts
export * from "ag-charts-community";
setupEnterpriseModules();
var LicenseManager2 = {
setLicenseKey(key) {
LicenseManager.setLicenseKey(key);
}
};
function setupEnterpriseModules2() {
setupEnterpriseModules();
setupCommunityModules();
}
var AgChartsEnterpriseModule = {
VERSION,
_Scene,
_Theme,
_Util,
create: AgCharts.create.bind(AgCharts),
createSparkline: AgCharts.__createSparkline.bind(AgCharts),
setup: setupEnterpriseModules2,
setGridContext: LicenseManager.setGridContext.bind(LicenseManager),
setLicenseKey: LicenseManager.setLicenseKey.bind(LicenseManager),
isEnterprise: true
};
export {
AgChartsEnterpriseModule,
LicenseManager2 as LicenseManager,
setupEnterpriseModules2 as setupEnterpriseModules
};