scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
628 lines (627 loc) • 31.7 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmartDateLabelProvider = exports.DEFAULT_LABEL_THRESHOLDS = exports.EHighPrecisionLabelMode = exports.EDatePrecision = exports.ETradeChartLabelFormat = void 0;
var LabelProviderType_1 = require("../../../../types/LabelProviderType");
var NumericFormat_1 = require("../../../../types/NumericFormat");
var date_1 = require("../../../../utils/date");
var number_1 = require("../../../../utils/number");
var LabelProviderBase2D_1 = require("./LabelProviderBase2D");
var ETradeChartLabelFormat;
(function (ETradeChartLabelFormat) {
ETradeChartLabelFormat["Nanoseconds"] = "Nanoseconds";
ETradeChartLabelFormat["Microseconds"] = "Microseconds";
/** @example `04:01`, `45.1234`, `46.3456` */
ETradeChartLabelFormat["MilliSeconds"] = "MilliSeconds";
/** @example `Apr 25`, `04:01:45`, `02:02:30` */
ETradeChartLabelFormat["Seconds"] = "Seconds";
/** @example `Apr 25`, `01:34`, `02:24` */
ETradeChartLabelFormat["Minutes"] = "Minutes";
/** @example `Apr`, `08`, `13` */
ETradeChartLabelFormat["Days"] = "Days";
/** @example `2020`, `Jan`, `Feb` */
ETradeChartLabelFormat["Months"] = "Months";
})(ETradeChartLabelFormat = exports.ETradeChartLabelFormat || (exports.ETradeChartLabelFormat = {}));
var EDatePrecision;
(function (EDatePrecision) {
/** "Second" or "Unix", where 1 second = 1.0 value */
EDatePrecision[EDatePrecision["Seconds"] = 1] = "Seconds";
/** 1 second = 1,000 value */
EDatePrecision[EDatePrecision["Milliseconds"] = 1000] = "Milliseconds";
/** 1 second = 1,000,000 value */
EDatePrecision[EDatePrecision["Microseconds"] = 1000000] = "Microseconds";
/** 1 second = 1,000,000,000 value */
EDatePrecision[EDatePrecision["Nanoseconds"] = 1000000000] = "Nanoseconds";
})(EDatePrecision = exports.EDatePrecision || (exports.EDatePrecision = {}));
var EHighPrecisionLabelMode;
(function (EHighPrecisionLabelMode) {
/**
* Formats the precise values with their respective suffix (`ms`, `µs`, `ns`).
*
* @note It can also show seconds, depending on {@link SmartDateLabelProvider.showSecondsOnPreciseDate}
*
* @example
* "345ms"
* "59s345ms"
*/
EHighPrecisionLabelMode["Suffix"] = "Suffix";
/**
* Formats the precise values as fractional seconds.
*
* @note It can also show seconds, depending on {@link SmartDateLabelProvider.showSecondsOnPreciseDate}
*
* @example
* ".00345"
* "59.00345"
*/
EHighPrecisionLabelMode["Fractional"] = "Fractional";
/**
* Formats the precise values in scientific notation.
*
* @example
* "4.00e-1s"
*/
EHighPrecisionLabelMode["Scientific"] = "Scientific";
})(EHighPrecisionLabelMode = exports.EHighPrecisionLabelMode || (exports.EHighPrecisionLabelMode = {}));
var TEN_MICROSECONDS = 0.00001;
var TEN_MILLISECONDS = 0.01;
var TEN_SECONDS = 10;
var ONE_HOUR = 60 * 60;
var FIVE_DAYS = 60 * 60 * 24 * 5;
var FIFTY_DAYS = 60 * 60 * 24 * 50;
/**
* Default label thresholds used by SmartDateLabelProvider.
* Maps each label format to its maximum time range in seconds.
*/
exports.DEFAULT_LABEL_THRESHOLDS = (_a = {},
_a[ETradeChartLabelFormat.Nanoseconds] = TEN_MICROSECONDS,
_a[ETradeChartLabelFormat.Microseconds] = TEN_MILLISECONDS,
_a[ETradeChartLabelFormat.MilliSeconds] = TEN_SECONDS,
_a[ETradeChartLabelFormat.Seconds] = ONE_HOUR,
_a[ETradeChartLabelFormat.Minutes] = FIVE_DAYS,
_a[ETradeChartLabelFormat.Days] = FIFTY_DAYS,
_a[ETradeChartLabelFormat.Months] = Infinity,
_a);
/**
* The order in which label formats should be evaluated (from smallest to largest time ranges).
* Used to determine which format to use based on the visible time range.
*/
var LABEL_FORMAT_ORDER = [
ETradeChartLabelFormat.Nanoseconds,
ETradeChartLabelFormat.Microseconds,
ETradeChartLabelFormat.MilliSeconds,
ETradeChartLabelFormat.Seconds,
ETradeChartLabelFormat.Minutes,
ETradeChartLabelFormat.Days,
ETradeChartLabelFormat.Months
];
/**
* The {@link SmartDateLabelProvider} formats Axis Labels and Cursor / Tooltips for {@link NumericAxis} types
*/
var SmartDateLabelProvider = /** @class */ (function (_super) {
__extends(SmartDateLabelProvider, _super);
/**
* Creates an instance of {@link SmartDateLabelProvider}
*/
function SmartDateLabelProvider(options) {
var _this = this;
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
_this = _super.call(this, __assign(__assign({}, options), { labelFormat: (_a = options === null || options === void 0 ? void 0 : options.labelFormat) !== null && _a !== void 0 ? _a : NumericFormat_1.ENumericFormat.Date_DDMMYYYY, cursorLabelFormat: (_b = options === null || options === void 0 ? void 0 : options.cursorLabelFormat) !== null && _b !== void 0 ? _b : NumericFormat_1.ENumericFormat.Date_DDMMYYYY, alwaysShowFirstLabel: (_c = options === null || options === void 0 ? void 0 : options.alwaysShowFirstLabel) !== null && _c !== void 0 ? _c : true })) || this;
_this.type = LabelProviderType_1.ELabelProviderType.SmartDate;
_this.textVariesForSameTick = true;
_this.showWiderDateOnFirstLabelProperty = true;
_this.showYearOnWiderDateProperty = false;
_this.dateOffsetProperty = 0;
_this.datePrecisionProperty = EDatePrecision.Seconds;
_this.highPrecisionLabelModeProperty = EHighPrecisionLabelMode.Suffix;
_this.labelThresholdsProperty = exports.DEFAULT_LABEL_THRESHOLDS;
_this.labelThresholdsUpdated = false;
_this.splitWideDateWithCommaProperty = true;
_this.showSecondsOnWideDateProperty = true;
_this.showSecondsOnPreciseDateProperty = false;
_this.firstLabel = true;
_this.showWiderDateOnFirstLabelProperty = (_d = options === null || options === void 0 ? void 0 : options.showWiderDateOnFirstLabel) !== null && _d !== void 0 ? _d : _this.showWiderDateOnFirstLabelProperty;
_this.showYearOnWiderDateProperty = (_e = options === null || options === void 0 ? void 0 : options.showYearOnWiderDate) !== null && _e !== void 0 ? _e : _this.showYearOnWiderDateProperty;
_this.dateOffsetProperty = (_f = options === null || options === void 0 ? void 0 : options.dateOffset) !== null && _f !== void 0 ? _f : _this.dateOffsetProperty;
_this.datePrecisionProperty = (_g = options === null || options === void 0 ? void 0 : options.datePrecision) !== null && _g !== void 0 ? _g : _this.datePrecisionProperty;
_this.highPrecisionLabelModeProperty = (_h = options === null || options === void 0 ? void 0 : options.highPrecisionLabelMode) !== null && _h !== void 0 ? _h : _this.highPrecisionLabelModeProperty;
_this.splitWideDateWithCommaProperty = (_j = options === null || options === void 0 ? void 0 : options.splitWideDateWithComma) !== null && _j !== void 0 ? _j : _this.splitWideDateWithCommaProperty;
_this.showSecondsOnWideDateProperty = (_k = options === null || options === void 0 ? void 0 : options.showSecondsOnWideDate) !== null && _k !== void 0 ? _k : _this.showSecondsOnWideDateProperty;
_this.showSecondsOnPreciseDateProperty = (_l = options === null || options === void 0 ? void 0 : options.showSecondsOnPreciseDate) !== null && _l !== void 0 ? _l : _this.showSecondsOnPreciseDateProperty;
if (options === null || options === void 0 ? void 0 : options.labelThresholds) {
_this.labelThresholdsProperty = __assign(__assign({}, exports.DEFAULT_LABEL_THRESHOLDS), options.labelThresholds);
_this.labelThresholdsUpdated = true;
}
_this.formatCursorLabelProperty = function (dataValue) {
var _a, _b;
var seconds = _this.convertToUnixSeconds(dataValue) + _this.dateOffset;
return _this.applyFormat((0, number_1.formatNumber)(seconds, (_a = _this.cursorNumericFormat) !== null && _a !== void 0 ? _a : _this.numericFormat, (_b = _this.cursorPrecision) !== null && _b !== void 0 ? _b : _this.precision));
};
_this.doFormat = _this.doFormat.bind(_this);
_this.formatLabelProperty = _this.doFormat;
return _this;
}
/**
* Convert value from current precision (ticks) to standard Unix Seconds.
* @note High precision values (nano) will lose precision here.
* Use only for coarse-grained logic (year / month / day checks).
*/
SmartDateLabelProvider.prototype.convertToUnixSeconds = function (value) {
return value / this.datePrecisionProperty;
};
/**
* Convert raw ticks to Unix seconds, preserving integer seconds.
* Returns only the whole seconds part, discarding sub-second precision.
*/
SmartDateLabelProvider.prototype.getWholeSeconds = function (rawTicks) {
var tps = this.datePrecisionProperty;
return Math.floor(rawTicks / tps);
};
Object.defineProperty(SmartDateLabelProvider.prototype, "showWiderDateOnFirstLabel", {
get: function () {
return this.showWiderDateOnFirstLabelProperty;
},
set: function (value) {
if (this.showWiderDateOnFirstLabelProperty !== value) {
this.showWiderDateOnFirstLabelProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "dateOffset", {
/**
* A timestamp in seconds to add to the value being formatted.
*/
get: function () {
var _a;
return (_a = this.dateOffsetProperty) !== null && _a !== void 0 ? _a : 0;
},
set: function (value) {
if (this.dateOffsetProperty !== value) {
this.dateOffsetProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "datePrecision", {
/**
* Gets or sets the precision of the input data values.
* Defaults to `EDatePrecision.Seconds` (Unix).
*/
get: function () {
return this.datePrecisionProperty;
},
set: function (value) {
if (this.datePrecisionProperty !== value) {
this.datePrecisionProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "highPrecisionLabelMode", {
/**
* Gets or Sets the high precision label mode.
* Default `EHighPrecisionLabelMode.Fractional`
*/
get: function () {
return this.highPrecisionLabelModeProperty;
},
set: function (value) {
if (this.highPrecisionLabelModeProperty !== value) {
this.highPrecisionLabelModeProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "showYearOnWiderDate", {
/**
* Gets or Sets whether the year should be shown in the wider format used on first label. Default false.
*/
get: function () {
return this.showYearOnWiderDateProperty;
},
set: function (value) {
if (this.showYearOnWiderDateProperty !== value) {
this.showYearOnWiderDateProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "labelThresholds", {
/**
* Gets or sets the custom label thresholds that map label formats to maximum time ranges.
* Allows you to customize when different label formats are used based on the visible time range.
* You can update individual thresholds by providing a partial object.
* Default {@link DEFAULT_LABEL_THRESHOLDS}.
*
* @example
* ```typescript
* // Override only the Minutes threshold
* labelProvider.labelThresholds = {
* [ETradeChartLabelFormat.Minutes]: 60 * 60 * 24 * 7 // 7 days
* };
* ```
*/
get: function () {
return this.labelThresholdsProperty;
},
set: function (value) {
if (this.labelThresholdsProperty !== value) {
this.labelThresholdsProperty = __assign(__assign({}, this.labelThresholdsProperty), value);
this.labelThresholdsUpdated = true;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "splitWideDateWithComma", {
/**
* Gets or Sets whether your wide formatted dates have a comma in between date + month, and everything else
*/
get: function () { return this.splitWideDateWithCommaProperty; },
set: function (value) {
if (this.splitWideDateWithCommaProperty !== value) {
this.splitWideDateWithCommaProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "showSecondsOnWideDate", {
/**
* Gets or Sets whether to show the seconds component on wide date formats.
*/
get: function () { return this.showSecondsOnWideDateProperty; },
set: function (value) {
if (this.showSecondsOnWideDateProperty !== value) {
this.showSecondsOnWideDateProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "showSecondsOnPreciseDate", {
/**
* Gets or Sets whether to show the seconds component on precise date formats.
*/
get: function () { return this.showSecondsOnPreciseDateProperty; },
set: function (value) {
if (this.showSecondsOnPreciseDateProperty !== value) {
this.showSecondsOnPreciseDateProperty = value;
this.invalidateParent();
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(SmartDateLabelProvider.prototype, "numericFormat", {
/** @inheritDoc */
get: function () {
// SmartDate uses its own formatting; numericFormat is not applicable for axis labels.
return undefined;
},
/** @inheritDoc */
set: function (value) {
// Intentionally no-op to avoid breaking serialization.
},
enumerable: false,
configurable: true
});
SmartDateLabelProvider.prototype.onBeginAxisDraw = function () {
// Could be extended by subclasses or user if needed
};
/**
* @inheritDoc
*/
SmartDateLabelProvider.prototype.getLabels = function (majorTicks) {
var first = majorTicks[0];
var ticksNumber = majorTicks.length;
var last = majorTicks[ticksNumber - 1];
// Only convert the values we need
if (this.parentAxis.isCategoryAxis) {
var categoryCoordCalc = this.parentAxis.getCurrentCoordinateCalculator();
first = categoryCoordCalc.transformIndexToData(first);
last = categoryCoordCalc.transformIndexToData(last);
}
this.prevPrevValue = undefined;
this.prevValue = undefined;
this.firstLabel = true;
var timeRangeRaw = last - first;
var timeRangeSeconds = timeRangeRaw / this.datePrecisionProperty;
this.format = this.getLabelRange(timeRangeSeconds, ticksNumber);
var labels = _super.prototype.getLabels.call(this, majorTicks);
this.format = undefined;
return labels;
};
/**
* Formats the value in a wider format, used for the first label and when the formatted value changes
* (e.g., when crossing day/hour boundaries). This method can be overridden to customize wide label formatting.
*
* @param labelRange - The label format range determined by the visible time span (e.g., Nanoseconds, Seconds, Days)
* @param valueInSeconds - The data value converted to Unix seconds with dateOffset already applied
* @returns The formatted wide label string
*
* @example
* // For high precision: "Jan 2, 2026 12:59:59"
* // For months: "Jan 2026"
* // For years: "2026"
*/
SmartDateLabelProvider.prototype.formatDateWide = function (labelRange, valueInSeconds) {
var yearStr = (0, date_1.formatUnixDateToHumanStringYYYY)(valueInSeconds);
var optionalYearLeftPadded = this.showYearOnWiderDate ? " " + yearStr : "";
var optionalDateSeparator = this.splitWideDateWithComma ? "," : "";
switch (labelRange) {
case ETradeChartLabelFormat.Nanoseconds:
case ETradeChartLabelFormat.Microseconds:
case ETradeChartLabelFormat.MilliSeconds: {
var time = this.showSecondsOnWideDate
? (0, date_1.formatUnixDateToHumanStringHHMMSS)(valueInSeconds)
: (0, date_1.formatUnixDateToHumanStringHHMM)(valueInSeconds);
// "Jan 1 2026 12:59:59"
// "Jan 1, 12:59"
return (0, date_1.formatUnixDateToHumanStringMMMDD)(valueInSeconds)
+ optionalDateSeparator
+ optionalYearLeftPadded
+ " " + time;
}
case ETradeChartLabelFormat.Seconds:
case ETradeChartLabelFormat.Minutes: {
// "Jan 1, 2026"
// "Jan 1"
return (0, date_1.formatUnixDateToHumanStringMMMDD)(valueInSeconds)
+ (this.showYearOnWiderDateProperty ? (optionalDateSeparator + optionalYearLeftPadded) : "");
}
case ETradeChartLabelFormat.Days: {
// "Apr 2026"
// "Apr"
return (0, date_1.formatUnixDateToHumanStringMMM)(valueInSeconds)
+ optionalYearLeftPadded;
}
default:
return yearStr;
}
};
/**
* Formats the value using the precise format for non-wide labels. The format depends on the
* `highPrecisionLabelMode` setting. This method can be overridden to customize precise label formatting.
*
* @param labelRange - The label format range determined by the visible time span (e.g., Nanoseconds, Seconds, Days)
* @param valueInSeconds - The data value converted to Unix seconds with dateOffset already applied
* @param rawValue - The original raw tick value, used to extract sub-second precision without floating point loss
* @returns The formatted precise label string
*
* @remarks
* For high precision formats (ns/µs/ms), the raw value is essential for maintaining precision. See {@link EHighPrecisionLabelMode} for more formatting details.
*
* @remarks
* For coarser formats, only `valueInSeconds` is used.
*/
SmartDateLabelProvider.prototype.formatDatePrecise = function (labelRange, valueInSeconds, rawValue) {
var raw = rawValue !== null && rawValue !== void 0 ? rawValue : 0;
switch (labelRange) {
case ETradeChartLabelFormat.Nanoseconds:
case ETradeChartLabelFormat.Microseconds:
case ETradeChartLabelFormat.MilliSeconds: {
var tps = this.getTicksPerSecond();
var ticksWithinSecond = this.getTicksWithinSecond(raw);
var subSecondOffset = ticksWithinSecond / tps;
var optionalSecondsStr = this.showSecondsOnPreciseDate ? "".concat(this.getWholeSeconds(raw) % 60) : "";
switch (this.highPrecisionLabelModeProperty) {
case EHighPrecisionLabelMode.Scientific:
return "".concat(subSecondOffset.toExponential(2), "s");
case EHighPrecisionLabelMode.Fractional: {
if (labelRange === ETradeChartLabelFormat.Nanoseconds) {
return "".concat(optionalSecondsStr, ".").concat(this.getNanosecondsWithinSecond(raw));
}
else if (labelRange === ETradeChartLabelFormat.Microseconds) {
return "".concat(optionalSecondsStr, ".").concat(this.getMicrosecondsWithinSecond(raw));
}
return "".concat(optionalSecondsStr, ".").concat(this.getMillisecondsWithinSecond(raw));
}
case EHighPrecisionLabelMode.Suffix:
default: {
var prefix = optionalSecondsStr ? optionalSecondsStr + "s" : "";
if (labelRange === ETradeChartLabelFormat.Nanoseconds) {
return "".concat(prefix).concat(Math.round(subSecondOffset * 1000000000), "ns");
}
else if (labelRange === ETradeChartLabelFormat.Microseconds) {
return "".concat(prefix).concat(Math.round(subSecondOffset * 1000000), "\u00B5s");
}
return "".concat(prefix).concat(Math.round(subSecondOffset * 1000), "ms");
}
}
}
case ETradeChartLabelFormat.Seconds:
return (0, date_1.formatUnixDateToHumanStringHHMMSS)(valueInSeconds);
case ETradeChartLabelFormat.Minutes:
return (0, date_1.formatUnixDateToHumanStringHHMM)(valueInSeconds);
case ETradeChartLabelFormat.Days:
case ETradeChartLabelFormat.Months:
return (0, date_1.formatUnixDateToHumanStringDD)(valueInSeconds);
default:
return (0, number_1.formatNumber)(valueInSeconds, NumericFormat_1.ENumericFormat.Date_DDMMYY, 0);
}
};
SmartDateLabelProvider.prototype.toJSON = function () {
var json = _super.prototype.toJSON.call(this);
var options = {
dateOffset: this.dateOffset,
highPrecisionLabelMode: this.highPrecisionLabelMode,
showWiderDateOnFirstLabel: this.showWiderDateOnFirstLabel,
showYearOnWiderDate: this.showYearOnWiderDate,
datePrecision: this.datePrecision,
splitWideDateWithComma: this.splitWideDateWithComma,
showSecondsOnWideDate: this.showSecondsOnWideDate,
showSecondsOnPreciseDate: this.showSecondsOnPreciseDate,
labelThresholds: this.labelThresholdsUpdated ? this.labelThresholds : undefined
};
Object.assign(json.options, options);
return json;
};
/** This method is bound to the formatLabel method of the base labelProvider. */
SmartDateLabelProvider.prototype.doFormat = function (dataValue) {
var _a, _b;
// Convert raw ticks to seconds + offset
var fullValueInSeconds = this.convertToUnixSeconds(dataValue) + this.dateOffset;
if (this.format) {
var text = this.formatSmartLabel(this.format, fullValueInSeconds, this.prevValue, this.prevPrevValue, dataValue);
this.prevPrevValue = this.prevValue;
this.prevValue = fullValueInSeconds;
return text;
}
else {
// Cursor / tooltip fallback
return this.applyFormat((0, number_1.formatNumber)(fullValueInSeconds, (_a = this.cursorNumericFormat) !== null && _a !== void 0 ? _a : this.numericFormat, (_b = this.cursorPrecision) !== null && _b !== void 0 ? _b : this.precision));
}
};
/**
* Return a range string, based on the numeric range of the axis.
* This will be used to choose which formatting to use.
* Uses the {@link labelThresholds} property to determine the appropriate format.
*/
SmartDateLabelProvider.prototype.getLabelRange = function (timeRangeSeconds, ticksNumber) {
// Iterate through formats in order to find the first one whose threshold exceeds the time range
for (var _i = 0, LABEL_FORMAT_ORDER_1 = LABEL_FORMAT_ORDER; _i < LABEL_FORMAT_ORDER_1.length; _i++) {
var format = LABEL_FORMAT_ORDER_1[_i];
var threshold = this.labelThresholdsProperty[format];
if (threshold !== undefined && timeRangeSeconds <= threshold) {
return format;
}
}
// Fallback to Months if no threshold matches
return ETradeChartLabelFormat.Months;
};
/**
* Main smart label formatting logic that determines when to display wide vs precise labels.
* This method can be overridden to customize the overall label selection strategy.
*
* @param format - The label format range (Nanoseconds, Microseconds, MilliSeconds, Seconds, Minutes, Days, Months)
* @param valueInSeconds - The current data value converted to Unix seconds with dateOffset applied
* @param prevValueInSeconds - The previous label's value in Unix seconds (undefined for first label)
* @param prevPrevValueInSeconds - The label before the previous one in Unix seconds (used for month formatting)
* @param originalRawValue - The current raw tick value, preserving sub-second precision
* @returns The formatted label string (either wide or precise format)
*
* @remarks
* The method decides between wide and precise formats based on:
* 1. Whether this is the first label (controlled by `showWiderDateOnFirstLabel`)
* 2. Whether the wide-formatted value has changed from the previous label
* 3. Special logic for month boundaries
*
* Wide labels provide date/time context (e.g., "1/1/2026 12:59:59"), while precise labels
* show incremental values (e.g., "00.000004000" or "4000ns").
*/
SmartDateLabelProvider.prototype.formatSmartLabel = function (
/** The label format range determined by the visible time span (e.g., Nanoseconds, Seconds, Days) */
format,
/** The data value converted to Unix seconds with dateOffset already applied */
valueInSeconds,
/** The previous label's value in Unix seconds (undefined for first label) */
prevValueInSeconds,
/** The label before the previous one in Unix seconds (used for month formatting) */
prevPrevValueInSeconds,
/** The original raw tick value, used to extract sub-second precision without floating point loss */
originalRawValue) {
var showWider = !this.firstLabel || this.showWiderDateOnFirstLabel;
this.firstLabel = false;
var wideDate = this.formatDateWide(format, valueInSeconds);
var prevWideDate = prevValueInSeconds !== undefined
? this.formatDateWide(format, prevValueInSeconds)
: undefined;
var isNewDate = prevWideDate === undefined || wideDate !== prevWideDate;
if (format !== ETradeChartLabelFormat.Months) {
if (isNewDate && showWider) {
return wideDate;
}
return this.formatDatePrecise(format, valueInSeconds, originalRawValue);
}
else {
if (isNewDate && showWider) {
return wideDate;
}
var prevPrevWideDate = prevPrevValueInSeconds !== undefined && prevValueInSeconds !== undefined
? this.formatDateWide(format, prevPrevValueInSeconds)
: undefined;
var prevPrevNewYear = prevPrevWideDate === undefined || prevWideDate !== prevPrevWideDate;
var newMonth = prevPrevNewYear ||
(0, date_1.formatUnixDateToHumanStringMMM)(valueInSeconds) !==
(0, date_1.formatUnixDateToHumanStringMMM)(prevValueInSeconds);
if (newMonth) {
return (0, date_1.formatUnixDateToHumanStringMMM)(valueInSeconds);
}
return this.formatDatePrecise(format, valueInSeconds, originalRawValue);
}
};
SmartDateLabelProvider.prototype.getTicksPerSecond = function () {
return this.datePrecisionProperty;
};
SmartDateLabelProvider.prototype.getTicksWithinSecond = function (rawTicks) {
var tps = this.getTicksPerSecond();
if (!tps)
return 0;
var wholeSeconds = Math.floor(rawTicks / tps);
return rawTicks - wholeSeconds * tps;
};
SmartDateLabelProvider.prototype.getMillisecondsWithinSecond = function (rawTicks) {
var tps = this.getTicksPerSecond();
if (!tps)
return 0;
var ticksWithinSecond = this.getTicksWithinSecond(rawTicks);
return Math.floor((ticksWithinSecond * 1000) / tps);
};
SmartDateLabelProvider.prototype.getMicrosecondsWithinSecond = function (rawTicks) {
var tps = this.getTicksPerSecond();
if (!tps)
return 0;
var ticksWithinSecond = this.getTicksWithinSecond(rawTicks);
return Math.floor((ticksWithinSecond * 1000000) / tps);
};
SmartDateLabelProvider.prototype.getNanosecondsWithinSecond = function (rawTicks) {
var tps = this.getTicksPerSecond();
if (!tps)
return 0;
var ticksWithinSecond = this.getTicksWithinSecond(rawTicks);
return Math.floor((ticksWithinSecond * 1000000000) / tps);
};
return SmartDateLabelProvider;
}(LabelProviderBase2D_1.LabelProviderBase2D));
exports.SmartDateLabelProvider = SmartDateLabelProvider;