acttrader-charts 1.3.0-beta.23 → 1.3.0-beta.25

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.
package/README.md CHANGED
@@ -1171,9 +1171,11 @@ Sub-pane heights are user-resizable by dragging the separator between panes.
1171
1171
 
1172
1172
  ### SL/TP bracket labels — price or amount
1173
1173
 
1174
- By default an SL/TP pill reads `SL 4159.00`. With `bracketLabelMode: 'amount'`
1175
- it reads `SL -$290.80` — the money the position gains or loses if that bracket
1176
- is hit, currency symbol in front.
1174
+ By default an SL/TP pill reads `SL @4159.00` — the currency sign is never shown on
1175
+ a price. With `bracketLabelMode: 'amount'` it reads `SL -$290.80` — the money the
1176
+ position gains or loses if that bracket is hit, currency symbol in front and a
1177
+ minus only on a loss. `'priceAndAmount'` shows `SL @4159.00` at rest and
1178
+ `SL @4159.00 -$290.80` while the bracket is dragged.
1177
1179
 
1178
1180
  The chart has no access to contract specs or the account currency, so each level
1179
1181
  supplies what the maths needs:
@@ -1188,7 +1190,7 @@ chart.setLevels([{
1188
1190
  valuePerPoint: 1, // account-currency value of one price unit
1189
1191
  currencySymbol: '$', // optional per-level override
1190
1192
  }], 'label', 'price', 'position');
1191
- // pills render: SL -$290.80 TP +$189.20
1193
+ // pills render: SL -$290.80 TP $189.20
1192
1194
  ```
1193
1195
 
1194
1196
  ```
@@ -1177,14 +1177,15 @@ interface ChartConfig {
1177
1177
  /**
1178
1178
  * What the SL/TP bracket pills show.
1179
1179
  *
1180
- * `'price'` (default) renders the bracket price — `SL 4159.00`.
1180
+ * `'price'` (default) renders the bracket price — `SL @4159.00`. The currency
1181
+ * sign is never shown on a price, only on money values.
1181
1182
  * `'amount'` renders the money the position gains or loses if that bracket
1182
- * is hit — `SL -$290.80` — computed from the level's `lots`, `contractSize`
1183
- * and `valuePerPoint`. Falls back to the price for any level lacking the
1184
- * data needed to compute it, so a partial rollout degrades gracefully.
1185
- * `'priceAndAmount'` keeps the price but puts the currency symbol in front
1186
- * of it — `SL $1.27859` — and appends the P/L while the bracket is being
1187
- * dragged: `SL $1.27859 -$29.08`.
1183
+ * is hit — `SL -$290.80` (a minus only on a loss, no plus on a gain) —
1184
+ * computed from the level's `lots`, `contractSize` and `valuePerPoint`.
1185
+ * Falls back to the price for any level lacking the data needed to compute
1186
+ * it, so a partial rollout degrades gracefully.
1187
+ * `'priceAndAmount'` shows the price at rest — `SL @1.27859` — and appends
1188
+ * the P/L while the bracket is being dragged: `SL @1.27859 -$29.08`.
1188
1189
  */
1189
1190
  bracketLabelMode?: 'price' | 'amount' | 'priceAndAmount';
1190
1191
  /**
@@ -1177,14 +1177,15 @@ interface ChartConfig {
1177
1177
  /**
1178
1178
  * What the SL/TP bracket pills show.
1179
1179
  *
1180
- * `'price'` (default) renders the bracket price — `SL 4159.00`.
1180
+ * `'price'` (default) renders the bracket price — `SL @4159.00`. The currency
1181
+ * sign is never shown on a price, only on money values.
1181
1182
  * `'amount'` renders the money the position gains or loses if that bracket
1182
- * is hit — `SL -$290.80` — computed from the level's `lots`, `contractSize`
1183
- * and `valuePerPoint`. Falls back to the price for any level lacking the
1184
- * data needed to compute it, so a partial rollout degrades gracefully.
1185
- * `'priceAndAmount'` keeps the price but puts the currency symbol in front
1186
- * of it — `SL $1.27859` — and appends the P/L while the bracket is being
1187
- * dragged: `SL $1.27859 -$29.08`.
1183
+ * is hit — `SL -$290.80` (a minus only on a loss, no plus on a gain) —
1184
+ * computed from the level's `lots`, `contractSize` and `valuePerPoint`.
1185
+ * Falls back to the price for any level lacking the data needed to compute
1186
+ * it, so a partial rollout degrades gracefully.
1187
+ * `'priceAndAmount'` shows the price at rest — `SL @1.27859` — and appends
1188
+ * the P/L while the bracket is being dragged: `SL @1.27859 -$29.08`.
1188
1189
  */
1189
1190
  bracketLabelMode?: 'price' | 'amount' | 'priceAndAmount';
1190
1191
  /**
package/dist/index.cjs CHANGED
@@ -1935,8 +1935,7 @@ function bracketPnl(input) {
1935
1935
  function formatMoney(amount, symbol = "$", decimals = 2) {
1936
1936
  const rounded = Number(amount.toFixed(decimals));
1937
1937
  const magnitude = Math.abs(rounded).toFixed(decimals);
1938
- if (rounded === 0) return `${symbol}${magnitude}`;
1939
- return `${rounded > 0 ? "+" : "-"}${symbol}${magnitude}`;
1938
+ return `${rounded < 0 ? "-" : ""}${symbol}${magnitude}`;
1940
1939
  }
1941
1940
  function positionQty(input) {
1942
1941
  const { entryPrice, stopPrice, accountSize, riskPercent } = input;
@@ -2080,13 +2079,12 @@ function bracketBoxLabel(bracketType, price, precision, level, opts = DEFAULT_BR
2080
2079
  const pnl = amount();
2081
2080
  if (pnl !== null) return `${typeLabel} ${formatMoney(pnl, symbol)}`;
2082
2081
  }
2083
- if (opts.mode === "priceAndAmount") {
2084
- const priced = `${typeLabel} ${symbol}${price.toFixed(precision)}`;
2085
- if (!active) return priced;
2082
+ const priced = `${typeLabel} @${price.toFixed(precision)}`;
2083
+ if (opts.mode === "priceAndAmount" && active) {
2086
2084
  const pnl = amount();
2087
- return pnl === null ? priced : `${priced} ${formatMoney(pnl, symbol)}`;
2085
+ if (pnl !== null) return `${priced} ${formatMoney(pnl, symbol)}`;
2088
2086
  }
2089
- return `${typeLabel} ${price.toFixed(precision)}`;
2087
+ return priced;
2090
2088
  }
2091
2089
  var BRACKET_BASE_RATIO = 0.68;
2092
2090
  var BRACKET_COL_OFFSETS = [0, -0.08, 0.08];
@@ -25316,6 +25314,10 @@ var _ChartEngine = class _ChartEngine {
25316
25314
  this.logoImage = null;
25317
25315
  // ── State persistence ─────────────────────────────────────────────────────
25318
25316
  this.isRestoringState = false;
25317
+ this.onPointerEnter = () => {
25318
+ this._cachedWrapRect = null;
25319
+ this._cachedDrawRect = null;
25320
+ };
25319
25321
  this.onMouseMove = (e) => {
25320
25322
  if (this._mobileCrosshairActive) return;
25321
25323
  if (Date.now() - this._lastTouchTime < 500) return;
@@ -26464,19 +26466,29 @@ var _ChartEngine = class _ChartEngine {
26464
26466
  throw new Error("acttrader-charts requires a browser environment");
26465
26467
  }
26466
26468
  enableKeyboardOverlayMode();
26467
- if (window.visualViewport) {
26468
- const vv = window.visualViewport;
26469
- const invalidate = () => {
26470
- this._cachedWrapRect = null;
26471
- this._cachedDrawRect = null;
26472
- };
26469
+ const invalidate = () => {
26470
+ this._cachedWrapRect = null;
26471
+ this._cachedDrawRect = null;
26472
+ };
26473
+ const vv = window.visualViewport;
26474
+ if (vv) {
26473
26475
  vv.addEventListener("resize", invalidate);
26474
26476
  vv.addEventListener("scroll", invalidate);
26475
- this.disposeVvListener = () => {
26477
+ }
26478
+ document.addEventListener("scroll", invalidate, { capture: true, passive: true });
26479
+ window.addEventListener("resize", invalidate);
26480
+ const layoutObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(invalidate) : null;
26481
+ layoutObserver?.observe(document.documentElement);
26482
+ if (document.body) layoutObserver?.observe(document.body);
26483
+ this.disposeVvListener = () => {
26484
+ if (vv) {
26476
26485
  vv.removeEventListener("resize", invalidate);
26477
26486
  vv.removeEventListener("scroll", invalidate);
26478
- };
26479
- }
26487
+ }
26488
+ document.removeEventListener("scroll", invalidate, { capture: true });
26489
+ window.removeEventListener("resize", invalidate);
26490
+ layoutObserver?.disconnect();
26491
+ };
26480
26492
  const {
26481
26493
  container,
26482
26494
  theme = "dark",
@@ -27394,6 +27406,7 @@ var _ChartEngine = class _ChartEngine {
27394
27406
  this.scheduleViewportPersist();
27395
27407
  }
27396
27408
  );
27409
+ this.drawCanvas.addEventListener("mouseenter", this.onPointerEnter);
27397
27410
  this.drawCanvas.addEventListener("mousemove", this.onMouseMove);
27398
27411
  this.drawCanvas.addEventListener("mouseleave", this.onMouseLeave);
27399
27412
  this.drawCanvas.addEventListener("mousedown", this.onCanvasClick);
@@ -29846,6 +29859,7 @@ var _ChartEngine = class _ChartEngine {
29846
29859
  this.advancedToolbar?.destroy();
29847
29860
  this.mobileHeader?.destroy();
29848
29861
  this.leftBar?.destroy();
29862
+ this.drawCanvas.removeEventListener("mouseenter", this.onPointerEnter);
29849
29863
  this.drawCanvas.removeEventListener("mousemove", this.onMouseMove);
29850
29864
  this.drawCanvas.removeEventListener("mouseleave", this.onMouseLeave);
29851
29865
  this.drawCanvas.removeEventListener("mousedown", this.onCanvasClick);