acttrader-charts 1.0.2 → 1.0.4

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
@@ -164,18 +164,26 @@ chart.setLevels([], 'label', 'price', 'pending'); // clear all of one type
164
164
 
165
165
  ```ts
166
166
  // Confirmed drag of a pending order entry
167
- chart.on('tradeLevelEdit', ({ label, type, changes }) => {
167
+ chart.on('tradeLevelEdit', ({ label, type, changes, isFullscreen }) => {
168
168
  for (const c of changes) {
169
169
  if (c.field === 'MAIN') myApi.modifyOrder(label, { price: c.newPrice });
170
170
  if (c.field === 'SL') myApi.modifyOrder(label, { stopLoss: c.newPrice });
171
171
  if (c.field === 'TP') myApi.modifyOrder(label, { takeProfit: c.newPrice });
172
172
  }
173
+ // isFullscreen — show a toast only when the chart is covering the full screen
174
+ if (isFullscreen) showToast(`Order ${label} updated`);
173
175
  });
174
176
 
175
177
  // User clicked × on a level
176
- chart.on('tradeLevelClose', ({ label, type, action }) => {
178
+ chart.on('tradeLevelClose', ({ label, type, action, isFullscreen }) => {
177
179
  if (type === 'pending') myApi.cancelOrder(label);
178
180
  if (type === 'position') myApi.closePosition(label);
181
+ if (isFullscreen) showToast(`${action}: ${label}`);
182
+ });
183
+
184
+ // Live price during drag (fires on every mouse-move — throttle if needed)
185
+ chart.on('tradeLevelDrag', ({ label, newPrice, bracketType, isFullscreen }) => {
186
+ updatePricePreview(label, newPrice);
179
187
  });
180
188
  ```
181
189
 
@@ -199,19 +207,37 @@ chart.on('tradeLevelClose', ({ label, type, action }) => {
199
207
  | `series` | | `"candlestick"` | Initial chart type |
200
208
  | `showVolume` | | `true` | Show volume overlay |
201
209
  | `showUI` | | `true` | Render top / bottom / left bars |
202
- | `timeframe` | | `"1D"` | Initial timeframe label |
210
+ | `showDrawingTools` | | `true` | Show drawing toolbar and pencil button |
211
+ | `timeframe` | | `"1D"` | Initial timeframe |
203
212
  | `duration` | | — | Initial active duration button |
204
213
  | `symbol` | | — | Symbol name shown in the top bar |
214
+ | `isins` | | — | Symbol list for the picker modal |
215
+ | `onIsinSelect` | | — | Called when user picks a symbol from the picker modal |
205
216
  | `padding` | | `{top:8,right:0,bottom:0,left:0}` | Canvas padding (px) |
206
217
  | `minLots` | | `1` | Default lot size in the trade popover |
207
218
  | `tickActivityMs` | | `30000` | ms the stream dot stays green after last tick |
208
219
  | `maxCandles` | | `200` | Max bars fetched per data-load request |
220
+ | `mobileBarDivisor` | | `2` | Divide desktop visible bar count on touch devices (`2`, `3`, or `4`) |
221
+ | `targetCandleWidth` | | `10` | Target px width per candle for auto-calculating initial bar count |
209
222
  | `durationTimeframeMap` | | *(see below)* | Override duration → timeframe pairings |
210
223
  | `dataLoader` | | — | `(params) => Promise<OHLCVBar[]>` auto-called on load / change |
224
+ | `themeOverrides` | | — | Deep-partial color overrides applied on top of the built-in dark/light themes |
211
225
  | `uiConfig` | | `DEFAULT_UI_CONFIG` | Deep-partial size / font overrides per component |
212
226
  | `labels` | | `DEFAULT_LABELS` | Deep-partial string overrides for i18n/translation |
227
+ | `tickClosePriceSource` | | `"bid"` | Which quote side drives live tick close/high/low (`"bid"` or `"ask"`) |
228
+ | `showBidAskLines` | | `false` | Show both bid and ask as dashed lines during a live stream |
229
+ | `showActLogo` | | `false` | Show the ACT watermark logo in the bottom-left corner |
230
+ | `showCandleCountdown` | | `true` | Show countdown timer on the live candle |
231
+ | `candleCountdownTimeframes` | | intraday only | Timeframes where the countdown appears; `'all'` or `Timeframe[]` |
232
+ | `maxSubPanes` | | `3` | Max simultaneous oscillator sub-panes |
233
+ | `tradeDisplayFilter` | | `"all"` | Which TFC levels are visible: `"all"` · `"positions"` · `"orders"` · `"none"` |
234
+ | `positionRenderStyle` | | auto | Force position render style: `"line"` or `"dot"` |
235
+ | `tradesThresholdForHorizontalLine` | | `2` | Level count above which render auto-switches to `"dot"` mode |
236
+ | `canvasColors` | | — | Per-theme canvas background color overrides (persisted from Settings dialog) |
237
+ | `aggregateFrom` | | — | Fetch finer-grained data and aggregate client-side per timeframe |
213
238
  | `onOrderSubmit` | | — | Called when user submits a trade via the floating button |
214
239
  | `onLevelEdit` | | — | Called when user confirms a TFC level edit |
240
+ | `onLotsChange` | | — | Called when user changes qty on a draft order |
215
241
  | `onLevelDragEnd` | | — | *(deprecated — use `onLevelEdit`)* |
216
242
 
217
243
  ### `OHLCVBar`
@@ -622,12 +648,15 @@ chart.on('stateChange', ({ symbol, state }) => {
622
648
  });
623
649
 
624
650
  // TFC events
625
- chart.on('tradeLevelEdit', ({ label, type, data, changes }) => {});
626
- chart.on('tradeLevelClose', ({ label, type, action, data }) => {});
627
- chart.on('tradeLevelDragEnd', ({ label, type, newPrice, data }) => {}); // deprecated
651
+ // `isFullscreen` is true when the chart is in fullscreen mode (native or CSS) at the time of the action.
652
+ // Use it to conditionally show toast notifications only while fullscreen.
653
+ chart.on('tradeLevelEdit', ({ label, type, data, changes, isFullscreen }) => {});
654
+ chart.on('tradeLevelClose', ({ label, type, action, data, isFullscreen }) => {});
655
+ chart.on('tradeLevelDrag', ({ label, newPrice, data, bracketType, isFullscreen }) => {}); // fires on every mouse-move during drag
656
+ chart.on('tradeLevelEditOpen', ({ label, type, price, side, stopLossPrice, takeProfitPrice, data, isFullscreen }) => {});
657
+ chart.on('tradeLevelConfirmed',({ label, type, isFullscreen }) => {});
658
+ chart.on('tradeLevelDragEnd', ({ label, type, newPrice, data }) => {}); // deprecated — use tradeLevelEdit
628
659
  chart.on('tradeLevelBracketDrag', ({ label, bracketType, newPrice, data }) => {}); // deprecated
629
- chart.on('tradeLevelEditOpen', ({ label, type, price, side, stopLossPrice, takeProfitPrice, data }) => {});
630
- chart.on('tradeLevelConfirmed',({ label, type }) => {});
631
660
  ```
632
661
 
633
662
  ---
@@ -894,6 +894,8 @@ type ChartEventMap = {
894
894
  data: unknown;
895
895
  /** Present only when closing an SL or TP bracket line (not the main level). */
896
896
  bracketType?: 'SL' | 'TP';
897
+ /** True when the chart is in fullscreen mode (native or CSS) at the time of the action. */
898
+ isFullscreen: boolean;
897
899
  };
898
900
  /** Emitted when user finishes dragging a pending/position level line to a new price. */
899
901
  tradeLevelDragEnd: {
@@ -918,6 +920,8 @@ type ChartEventMap = {
918
920
  side?: 'buy' | 'sell';
919
921
  stopLossPrice?: number;
920
922
  takeProfitPrice?: number;
923
+ /** True when the chart is in fullscreen mode (native or CSS) at the time of the action. */
924
+ isFullscreen: boolean;
921
925
  };
922
926
  /** Emitted on every mouse-move while dragging a trade level line (before confirm).
923
927
  * `bracketType` is present when dragging an SL/TP bracket line; absent for main entry drag. */
@@ -926,11 +930,13 @@ type ChartEventMap = {
926
930
  newPrice: number;
927
931
  data: unknown;
928
932
  bracketType?: 'stopLoss' | 'takeProfit';
933
+ isFullscreen: boolean;
929
934
  };
930
935
  /** Emitted when chart's ✓ button confirms an edit (including draft orders). External panel listens to reset/close itself. */
931
936
  tradeLevelConfirmed: {
932
937
  label: string;
933
938
  type: TradeLevelType | 'draft';
939
+ isFullscreen: boolean;
934
940
  };
935
941
  /** Emitted after any user-driven change to chart configuration (timeframe, series, indicators, drawings, etc.).
936
942
  * The payload is a full serializable snapshot — consumers can persist it keyed by symbol. */
@@ -955,6 +961,8 @@ type ChartEventMap = {
955
961
  type: TradeLevelType;
956
962
  /** Parent level's data. */
957
963
  data: unknown;
964
+ /** True when the chart is in fullscreen mode (native or CSS) at the time of the action. */
965
+ isFullscreen: boolean;
958
966
  changes: Array<{
959
967
  /** MAIN = entry price edit; SL/TP = bracket edit; ADD_SL/ADD_TP = new bracket placed; REMOVE_SL/REMOVE_TP = bracket removed. */
960
968
  field: 'MAIN' | 'SL' | 'TP' | 'ADD_SL' | 'ADD_TP' | 'REMOVE_SL' | 'REMOVE_TP';
@@ -894,6 +894,8 @@ type ChartEventMap = {
894
894
  data: unknown;
895
895
  /** Present only when closing an SL or TP bracket line (not the main level). */
896
896
  bracketType?: 'SL' | 'TP';
897
+ /** True when the chart is in fullscreen mode (native or CSS) at the time of the action. */
898
+ isFullscreen: boolean;
897
899
  };
898
900
  /** Emitted when user finishes dragging a pending/position level line to a new price. */
899
901
  tradeLevelDragEnd: {
@@ -918,6 +920,8 @@ type ChartEventMap = {
918
920
  side?: 'buy' | 'sell';
919
921
  stopLossPrice?: number;
920
922
  takeProfitPrice?: number;
923
+ /** True when the chart is in fullscreen mode (native or CSS) at the time of the action. */
924
+ isFullscreen: boolean;
921
925
  };
922
926
  /** Emitted on every mouse-move while dragging a trade level line (before confirm).
923
927
  * `bracketType` is present when dragging an SL/TP bracket line; absent for main entry drag. */
@@ -926,11 +930,13 @@ type ChartEventMap = {
926
930
  newPrice: number;
927
931
  data: unknown;
928
932
  bracketType?: 'stopLoss' | 'takeProfit';
933
+ isFullscreen: boolean;
929
934
  };
930
935
  /** Emitted when chart's ✓ button confirms an edit (including draft orders). External panel listens to reset/close itself. */
931
936
  tradeLevelConfirmed: {
932
937
  label: string;
933
938
  type: TradeLevelType | 'draft';
939
+ isFullscreen: boolean;
934
940
  };
935
941
  /** Emitted after any user-driven change to chart configuration (timeframe, series, indicators, drawings, etc.).
936
942
  * The payload is a full serializable snapshot — consumers can persist it keyed by symbol. */
@@ -955,6 +961,8 @@ type ChartEventMap = {
955
961
  type: TradeLevelType;
956
962
  /** Parent level's data. */
957
963
  data: unknown;
964
+ /** True when the chart is in fullscreen mode (native or CSS) at the time of the action. */
965
+ isFullscreen: boolean;
958
966
  changes: Array<{
959
967
  /** MAIN = entry price edit; SL/TP = bracket edit; ADD_SL/ADD_TP = new bracket placed; REMOVE_SL/REMOVE_TP = bracket removed. */
960
968
  field: 'MAIN' | 'SL' | 'TP' | 'ADD_SL' | 'ADD_TP' | 'REMOVE_SL' | 'REMOVE_TP';
package/dist/index.cjs CHANGED
@@ -16545,7 +16545,7 @@ var _ChartEngine = class _ChartEngine {
16545
16545
  Math.min(Math.ceil(this.viewport.endIndex), Math.round(rawBarIndex))
16546
16546
  );
16547
16547
  const bar = this.dataStore.all[clamped] ?? null;
16548
- this.crosshair = isInChartArea && this.tradeButton === null ? { x, y, barIndex: clamped, price, bar } : null;
16548
+ this.crosshair = isInChartArea && !this.tradePopover?.isVisible ? { x, y, barIndex: clamped, price, bar } : null;
16549
16549
  if (this.crosshair) this.emitter.emit("crosshair", this.crosshair);
16550
16550
  const hoveringDotLevel = this.positionRenderStyle === "dot" && this.hoveredTradeLabel !== null;
16551
16551
  if (this.tradeButton) {
@@ -16645,7 +16645,8 @@ var _ChartEngine = class _ChartEngine {
16645
16645
  label: draggingLevel.label,
16646
16646
  newPrice: this.tradeDragNewPrice,
16647
16647
  data: draggingLevel.data,
16648
- bracketType
16648
+ bracketType,
16649
+ isFullscreen: this.isFullscreen
16649
16650
  });
16650
16651
  }
16651
16652
  }
@@ -16992,7 +16993,8 @@ var _ChartEngine = class _ChartEngine {
16992
16993
  label: draggingLevel.label,
16993
16994
  newPrice: this.tradeDragNewPrice,
16994
16995
  data: draggingLevel.data,
16995
- bracketType
16996
+ bracketType,
16997
+ isFullscreen: this.isFullscreen
16996
16998
  });
16997
16999
  }
16998
17000
  }
@@ -17151,7 +17153,8 @@ var _ChartEngine = class _ChartEngine {
17151
17153
  price: level.price,
17152
17154
  side: level.side,
17153
17155
  stopLossPrice: level.stopLossPrice,
17154
- takeProfitPrice: level.takeProfitPrice
17156
+ takeProfitPrice: level.takeProfitPrice,
17157
+ isFullscreen: this.isFullscreen
17155
17158
  });
17156
17159
  }
17157
17160
  return;
@@ -17905,6 +17908,9 @@ var _ChartEngine = class _ChartEngine {
17905
17908
  return true;
17906
17909
  }).map((s) => s.indicator);
17907
17910
  }
17911
+ get isFullscreen() {
17912
+ return this._isCssFullscreen || !!document.fullscreenElement;
17913
+ }
17908
17914
  // ── Public API ────────────────────────────────────────────────────────────
17909
17915
  loadData(bars, fitAll = false) {
17910
17916
  this.isFetching = false;
@@ -19291,7 +19297,8 @@ var _ChartEngine = class _ChartEngine {
19291
19297
  label: result.label,
19292
19298
  newPrice: result.newPrice,
19293
19299
  data: draggedLevel?.data,
19294
- bracketType: field
19300
+ bracketType: field,
19301
+ isFullscreen: this.isFullscreen
19295
19302
  });
19296
19303
  }
19297
19304
  this.tradeDragNewPrice = null;
@@ -19357,7 +19364,7 @@ var _ChartEngine = class _ChartEngine {
19357
19364
  ...slEntry ? { stopLoss: slEntry.newPrice } : {},
19358
19365
  ...tpEntry ? { takeProfit: tpEntry.newPrice } : {}
19359
19366
  });
19360
- this.emitter.emit("tradeLevelConfirmed", { label, type: "draft" });
19367
+ this.emitter.emit("tradeLevelConfirmed", { label, type: "draft", isFullscreen: this.isFullscreen });
19361
19368
  this.removeDraftOrder();
19362
19369
  return;
19363
19370
  }
@@ -19365,6 +19372,7 @@ var _ChartEngine = class _ChartEngine {
19365
19372
  label,
19366
19373
  type: level.type,
19367
19374
  data: level.data,
19375
+ isFullscreen: this.isFullscreen,
19368
19376
  changes: changes.map((c) => {
19369
19377
  const lbd = level.data;
19370
19378
  let changeData = level.data;
@@ -19390,7 +19398,7 @@ var _ChartEngine = class _ChartEngine {
19390
19398
  };
19391
19399
  })
19392
19400
  });
19393
- this.emitter.emit("tradeLevelConfirmed", { label, type: level.type });
19401
+ this.emitter.emit("tradeLevelConfirmed", { label, type: level.type, isFullscreen: this.isFullscreen });
19394
19402
  this.pendingLevelDrags.delete(label);
19395
19403
  this.selectedTradeLabel = null;
19396
19404
  this.renderTradeLayer();
@@ -20019,6 +20027,7 @@ var _ChartEngine = class _ChartEngine {
20019
20027
  label: closedLevel.label,
20020
20028
  data: parentLevel?.data,
20021
20029
  type: "pending",
20030
+ isFullscreen: this.isFullscreen,
20022
20031
  changes: [
20023
20032
  {
20024
20033
  field: closedLevel.bracketType === "stopLoss" ? "REMOVE_SL" : "REMOVE_TP",
@@ -20055,7 +20064,8 @@ var _ChartEngine = class _ChartEngine {
20055
20064
  label: closedLevel.label,
20056
20065
  type: closedLevel.type,
20057
20066
  action: closeAction,
20058
- data: closedLevel.data
20067
+ data: closedLevel.data,
20068
+ isFullscreen: this.isFullscreen
20059
20069
  });
20060
20070
  }
20061
20071
  /** Activates the mobile crosshair at canvas coords (x, y). */
@@ -20152,7 +20162,8 @@ var _ChartEngine = class _ChartEngine {
20152
20162
  price: level.price,
20153
20163
  side: level.side,
20154
20164
  stopLossPrice: level.stopLossPrice,
20155
- takeProfitPrice: level.takeProfitPrice
20165
+ takeProfitPrice: level.takeProfitPrice,
20166
+ isFullscreen: this.isFullscreen
20156
20167
  });
20157
20168
  }
20158
20169
  this._pendingBracketOrderLabel = null;