hyperprop-charting-library 0.1.121 → 0.1.122

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -221,6 +221,7 @@ var DEFAULT_OPTIONS = {
221
221
  autoScaleSmoothing: 0,
222
222
  autoScaleIgnoreLatestCandle: true,
223
223
  kineticScroll: { touch: true, mouse: false },
224
+ timeStepMs: 0,
224
225
  pinOutOfRangeLines: false,
225
226
  doubleClickEnabled: true,
226
227
  doubleClickAction: "reset",
@@ -1720,11 +1721,16 @@ function createChart(element, options = {}) {
1720
1721
  return Array.from(dedupedByTime.values()).sort((a, b) => a.time.getTime() - b.time.getTime());
1721
1722
  };
1722
1723
  const getTimeStepMs = () => {
1724
+ const configured = Number(mergedOptions.timeStepMs);
1725
+ if (Number.isFinite(configured) && configured > 0) {
1726
+ return configured;
1727
+ }
1723
1728
  if (data.length < 2) {
1724
1729
  return 24 * 60 * 60 * 1e3;
1725
1730
  }
1726
1731
  const deltas = [];
1727
- for (let index = 1; index < Math.min(data.length, 40); index += 1) {
1732
+ const first = Math.max(1, data.length - 40);
1733
+ for (let index = first; index < data.length; index += 1) {
1728
1734
  const previous = data[index - 1];
1729
1735
  const current = data[index];
1730
1736
  if (!previous || !current) {
@@ -3633,8 +3639,8 @@ function createChart(element, options = {}) {
3633
3639
  return null;
3634
3640
  }
3635
3641
  const stepMs = getTimeStepMs();
3636
- const rawRemainingMs = last.time.getTime() + stepMs - Date.now();
3637
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3642
+ const elapsedMs = Date.now() - last.time.getTime();
3643
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3638
3644
  return formatDuration(countdownMs);
3639
3645
  };
3640
3646
  const ticker = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
@@ -3887,8 +3893,8 @@ function createChart(element, options = {}) {
3887
3893
  }
3888
3894
  if (labels.visible && labels.showCountdownToBarClose && lastPoint) {
3889
3895
  const stepMs = getTimeStepMs();
3890
- const rawRemainingMs = lastPoint.time.getTime() + stepMs - Date.now();
3891
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3896
+ const elapsedMs = Date.now() - lastPoint.time.getTime();
3897
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3892
3898
  const countdownText = formatDuration(countdownMs);
3893
3899
  const prevFont = ctx.font;
3894
3900
  ctx.font = `${xAxisFontSize}px ${mergedOptions.fontFamily}`;
@@ -37,6 +37,14 @@ interface ChartOptions {
37
37
  touch?: boolean;
38
38
  mouse?: boolean;
39
39
  };
40
+ /**
41
+ * Authoritative bar interval in milliseconds. When set, the bar-close
42
+ * countdown, time extrapolation beyond the last bar, and axis density use
43
+ * this exact step instead of inferring it from bar spacing (inference can
44
+ * mis-read series whose deep history has gaps, e.g. session-aligned 4h
45
+ * futures data with sparse back-month eras). 0/undefined = infer.
46
+ */
47
+ timeStepMs?: number;
40
48
  pinOutOfRangeLines?: boolean;
41
49
  doubleClickEnabled?: boolean;
42
50
  doubleClickAction?: "reset" | "placeLimitOrder";
@@ -195,6 +195,7 @@ var DEFAULT_OPTIONS = {
195
195
  autoScaleSmoothing: 0,
196
196
  autoScaleIgnoreLatestCandle: true,
197
197
  kineticScroll: { touch: true, mouse: false },
198
+ timeStepMs: 0,
198
199
  pinOutOfRangeLines: false,
199
200
  doubleClickEnabled: true,
200
201
  doubleClickAction: "reset",
@@ -1694,11 +1695,16 @@ function createChart(element, options = {}) {
1694
1695
  return Array.from(dedupedByTime.values()).sort((a, b) => a.time.getTime() - b.time.getTime());
1695
1696
  };
1696
1697
  const getTimeStepMs = () => {
1698
+ const configured = Number(mergedOptions.timeStepMs);
1699
+ if (Number.isFinite(configured) && configured > 0) {
1700
+ return configured;
1701
+ }
1697
1702
  if (data.length < 2) {
1698
1703
  return 24 * 60 * 60 * 1e3;
1699
1704
  }
1700
1705
  const deltas = [];
1701
- for (let index = 1; index < Math.min(data.length, 40); index += 1) {
1706
+ const first = Math.max(1, data.length - 40);
1707
+ for (let index = first; index < data.length; index += 1) {
1702
1708
  const previous = data[index - 1];
1703
1709
  const current = data[index];
1704
1710
  if (!previous || !current) {
@@ -3607,8 +3613,8 @@ function createChart(element, options = {}) {
3607
3613
  return null;
3608
3614
  }
3609
3615
  const stepMs = getTimeStepMs();
3610
- const rawRemainingMs = last.time.getTime() + stepMs - Date.now();
3611
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3616
+ const elapsedMs = Date.now() - last.time.getTime();
3617
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3612
3618
  return formatDuration(countdownMs);
3613
3619
  };
3614
3620
  const ticker = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
@@ -3861,8 +3867,8 @@ function createChart(element, options = {}) {
3861
3867
  }
3862
3868
  if (labels.visible && labels.showCountdownToBarClose && lastPoint) {
3863
3869
  const stepMs = getTimeStepMs();
3864
- const rawRemainingMs = lastPoint.time.getTime() + stepMs - Date.now();
3865
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3870
+ const elapsedMs = Date.now() - lastPoint.time.getTime();
3871
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3866
3872
  const countdownText = formatDuration(countdownMs);
3867
3873
  const prevFont = ctx.font;
3868
3874
  ctx.font = `${xAxisFontSize}px ${mergedOptions.fontFamily}`;
package/dist/index.cjs CHANGED
@@ -221,6 +221,7 @@ var DEFAULT_OPTIONS = {
221
221
  autoScaleSmoothing: 0,
222
222
  autoScaleIgnoreLatestCandle: true,
223
223
  kineticScroll: { touch: true, mouse: false },
224
+ timeStepMs: 0,
224
225
  pinOutOfRangeLines: false,
225
226
  doubleClickEnabled: true,
226
227
  doubleClickAction: "reset",
@@ -1720,11 +1721,16 @@ function createChart(element, options = {}) {
1720
1721
  return Array.from(dedupedByTime.values()).sort((a, b) => a.time.getTime() - b.time.getTime());
1721
1722
  };
1722
1723
  const getTimeStepMs = () => {
1724
+ const configured = Number(mergedOptions.timeStepMs);
1725
+ if (Number.isFinite(configured) && configured > 0) {
1726
+ return configured;
1727
+ }
1723
1728
  if (data.length < 2) {
1724
1729
  return 24 * 60 * 60 * 1e3;
1725
1730
  }
1726
1731
  const deltas = [];
1727
- for (let index = 1; index < Math.min(data.length, 40); index += 1) {
1732
+ const first = Math.max(1, data.length - 40);
1733
+ for (let index = first; index < data.length; index += 1) {
1728
1734
  const previous = data[index - 1];
1729
1735
  const current = data[index];
1730
1736
  if (!previous || !current) {
@@ -3633,8 +3639,8 @@ function createChart(element, options = {}) {
3633
3639
  return null;
3634
3640
  }
3635
3641
  const stepMs = getTimeStepMs();
3636
- const rawRemainingMs = last.time.getTime() + stepMs - Date.now();
3637
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3642
+ const elapsedMs = Date.now() - last.time.getTime();
3643
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3638
3644
  return formatDuration(countdownMs);
3639
3645
  };
3640
3646
  const ticker = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
@@ -3887,8 +3893,8 @@ function createChart(element, options = {}) {
3887
3893
  }
3888
3894
  if (labels.visible && labels.showCountdownToBarClose && lastPoint) {
3889
3895
  const stepMs = getTimeStepMs();
3890
- const rawRemainingMs = lastPoint.time.getTime() + stepMs - Date.now();
3891
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3896
+ const elapsedMs = Date.now() - lastPoint.time.getTime();
3897
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3892
3898
  const countdownText = formatDuration(countdownMs);
3893
3899
  const prevFont = ctx.font;
3894
3900
  ctx.font = `${xAxisFontSize}px ${mergedOptions.fontFamily}`;
package/dist/index.d.cts CHANGED
@@ -37,6 +37,14 @@ interface ChartOptions {
37
37
  touch?: boolean;
38
38
  mouse?: boolean;
39
39
  };
40
+ /**
41
+ * Authoritative bar interval in milliseconds. When set, the bar-close
42
+ * countdown, time extrapolation beyond the last bar, and axis density use
43
+ * this exact step instead of inferring it from bar spacing (inference can
44
+ * mis-read series whose deep history has gaps, e.g. session-aligned 4h
45
+ * futures data with sparse back-month eras). 0/undefined = infer.
46
+ */
47
+ timeStepMs?: number;
40
48
  pinOutOfRangeLines?: boolean;
41
49
  doubleClickEnabled?: boolean;
42
50
  doubleClickAction?: "reset" | "placeLimitOrder";
package/dist/index.d.ts CHANGED
@@ -37,6 +37,14 @@ interface ChartOptions {
37
37
  touch?: boolean;
38
38
  mouse?: boolean;
39
39
  };
40
+ /**
41
+ * Authoritative bar interval in milliseconds. When set, the bar-close
42
+ * countdown, time extrapolation beyond the last bar, and axis density use
43
+ * this exact step instead of inferring it from bar spacing (inference can
44
+ * mis-read series whose deep history has gaps, e.g. session-aligned 4h
45
+ * futures data with sparse back-month eras). 0/undefined = infer.
46
+ */
47
+ timeStepMs?: number;
40
48
  pinOutOfRangeLines?: boolean;
41
49
  doubleClickEnabled?: boolean;
42
50
  doubleClickAction?: "reset" | "placeLimitOrder";
package/dist/index.js CHANGED
@@ -195,6 +195,7 @@ var DEFAULT_OPTIONS = {
195
195
  autoScaleSmoothing: 0,
196
196
  autoScaleIgnoreLatestCandle: true,
197
197
  kineticScroll: { touch: true, mouse: false },
198
+ timeStepMs: 0,
198
199
  pinOutOfRangeLines: false,
199
200
  doubleClickEnabled: true,
200
201
  doubleClickAction: "reset",
@@ -1694,11 +1695,16 @@ function createChart(element, options = {}) {
1694
1695
  return Array.from(dedupedByTime.values()).sort((a, b) => a.time.getTime() - b.time.getTime());
1695
1696
  };
1696
1697
  const getTimeStepMs = () => {
1698
+ const configured = Number(mergedOptions.timeStepMs);
1699
+ if (Number.isFinite(configured) && configured > 0) {
1700
+ return configured;
1701
+ }
1697
1702
  if (data.length < 2) {
1698
1703
  return 24 * 60 * 60 * 1e3;
1699
1704
  }
1700
1705
  const deltas = [];
1701
- for (let index = 1; index < Math.min(data.length, 40); index += 1) {
1706
+ const first = Math.max(1, data.length - 40);
1707
+ for (let index = first; index < data.length; index += 1) {
1702
1708
  const previous = data[index - 1];
1703
1709
  const current = data[index];
1704
1710
  if (!previous || !current) {
@@ -3607,8 +3613,8 @@ function createChart(element, options = {}) {
3607
3613
  return null;
3608
3614
  }
3609
3615
  const stepMs = getTimeStepMs();
3610
- const rawRemainingMs = last.time.getTime() + stepMs - Date.now();
3611
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3616
+ const elapsedMs = Date.now() - last.time.getTime();
3617
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3612
3618
  return formatDuration(countdownMs);
3613
3619
  };
3614
3620
  const ticker = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
@@ -3861,8 +3867,8 @@ function createChart(element, options = {}) {
3861
3867
  }
3862
3868
  if (labels.visible && labels.showCountdownToBarClose && lastPoint) {
3863
3869
  const stepMs = getTimeStepMs();
3864
- const rawRemainingMs = lastPoint.time.getTime() + stepMs - Date.now();
3865
- const countdownMs = rawRemainingMs >= 0 && rawRemainingMs <= stepMs * 2 ? rawRemainingMs : stepMs - Date.now() % stepMs;
3870
+ const elapsedMs = Date.now() - lastPoint.time.getTime();
3871
+ const countdownMs = elapsedMs >= 0 ? stepMs - elapsedMs % stepMs : Math.min(stepMs, stepMs - elapsedMs);
3866
3872
  const countdownText = formatDuration(countdownMs);
3867
3873
  const prevFont = ctx.font;
3868
3874
  ctx.font = `${xAxisFontSize}px ${mergedOptions.fontFamily}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.121",
3
+ "version": "0.1.122",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",