acttrader-charts 1.4.0-beta.11 → 1.4.0-beta.12
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 +31 -0
- package/dist/index.cjs +92 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +92 -8
- package/dist/index.js.map +1 -1
- package/dist/webview/chart.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -223,6 +223,21 @@ chart.on('compareRemoved', ({ symbol }) => console.log('-', symbol));
|
|
|
223
223
|
chart.on('compareError', ({ symbol, message }) => console.warn(symbol, message));
|
|
224
224
|
```
|
|
225
225
|
|
|
226
|
+
#### Saving and syncing compares
|
|
227
|
+
|
|
228
|
+
`getState().compares` is the ordered list of compare symbols, and `[]` once the
|
|
229
|
+
last one is removed (it is `undefined` only when no `compareDataLoader` is set).
|
|
230
|
+
Save the list as it is, including `[]`, so a removal reaches the trader's
|
|
231
|
+
other devices. `setState({ compares })` applies a saved list: `[]` clears every
|
|
232
|
+
compare, the current list is left as it is (no refetch), and a list applied
|
|
233
|
+
before the primary's first load waits as `loading` and is fetched with that
|
|
234
|
+
load instead of failing.
|
|
235
|
+
|
|
236
|
+
The % on each legend chip uses the same baseline as the lines: the compare's
|
|
237
|
+
close at the leftmost visible bar, measured at the last bar (or the hovered
|
|
238
|
+
bar). It updates as you scroll and zoom, so two screens showing different
|
|
239
|
+
ranges show different %.
|
|
240
|
+
|
|
226
241
|
When any compare is active the Y-axis switches to percent (`+12.34%` /
|
|
227
242
|
`-5.67%`); removing every compare returns it to absolute-price labels.
|
|
228
243
|
The Compare button in the advanced toolbar opens an in-chart picker filtered
|
|
@@ -1595,6 +1610,22 @@ const chart = new ChartEngine({
|
|
|
1595
1610
|
chart.setDrawingTool('icon'); // uses the last glyph picked
|
|
1596
1611
|
```
|
|
1597
1612
|
|
|
1613
|
+
#### Hosts with their own picker (native apps)
|
|
1614
|
+
|
|
1615
|
+
The panel above is part of the web drawing toolbar. A host that draws its own
|
|
1616
|
+
toolbar (the Android and iOS apps in native-UI mode) builds the picker from the
|
|
1617
|
+
catalog instead: the `icon` tool carries `glyphTabs`, each with a `kind`, a
|
|
1618
|
+
`label` and its `groups` (`id`, `name`, `tabIcon`, `glyphs`), the same list the
|
|
1619
|
+
web panel shows. On a tap, choose the glyph and then arm the tool:
|
|
1620
|
+
|
|
1621
|
+
```ts
|
|
1622
|
+
chart.setIconGlyph('😍', 'sticker'); // kind: 'emoji' (default) | 'sticker' | 'icon'
|
|
1623
|
+
chart.setDrawingTool('icon');
|
|
1624
|
+
```
|
|
1625
|
+
|
|
1626
|
+
Before `glyphTabs` and `setIconGlyph`, a host without the web toolbar had no
|
|
1627
|
+
list to show and every icon it placed was the default ⭐.
|
|
1628
|
+
|
|
1598
1629
|
#### The picker
|
|
1599
1630
|
|
|
1600
1631
|
Opening the **Icons & Emojis** group gives a panel, not a list of rows: a row per
|
package/dist/index.cjs
CHANGED
|
@@ -27156,7 +27156,12 @@ var ChartSettingsDialog = class {
|
|
|
27156
27156
|
display: "flex",
|
|
27157
27157
|
flexDirection: "column",
|
|
27158
27158
|
width: "540px",
|
|
27159
|
-
|
|
27159
|
+
// One height for every tab. Sized to its content, the panel grew
|
|
27160
|
+
// and shrank as you switched tabs (Appearance tall, Status Line
|
|
27161
|
+
// short) and the footer jumped about; a long tab now scrolls
|
|
27162
|
+
// inside the content area instead.
|
|
27163
|
+
height: "min(620px, calc(100vh - 48px))",
|
|
27164
|
+
minHeight: "min(340px, calc(100vh - 48px))",
|
|
27160
27165
|
maxWidth: "calc(100vw - 32px)",
|
|
27161
27166
|
maxHeight: "calc(100vh - 48px)",
|
|
27162
27167
|
background: theme.tooltip.background,
|
|
@@ -30734,6 +30739,25 @@ var CompareManager = class {
|
|
|
30734
30739
|
});
|
|
30735
30740
|
return;
|
|
30736
30741
|
}
|
|
30742
|
+
const entry = this.createEntry(symbol);
|
|
30743
|
+
await this.fetchOne(entry, this.lastParams, this.generation);
|
|
30744
|
+
}
|
|
30745
|
+
/** True once the primary has a loaded range that `add()` can fetch against. */
|
|
30746
|
+
hasRange() {
|
|
30747
|
+
return this.lastParams !== null;
|
|
30748
|
+
}
|
|
30749
|
+
/**
|
|
30750
|
+
* Add a compare symbol as `loading` without fetching. Used when restoring a
|
|
30751
|
+
* saved list before the primary's first load: the next `refetchAll()` (run
|
|
30752
|
+
* when the primary range arrives) loads it. No-op for a duplicate, an empty
|
|
30753
|
+
* symbol, or past `maxCompares`.
|
|
30754
|
+
*/
|
|
30755
|
+
addPending(symbol) {
|
|
30756
|
+
if (!symbol || this.entries.has(symbol)) return;
|
|
30757
|
+
if (this.entries.size >= this.maxCompares) return;
|
|
30758
|
+
this.createEntry(symbol);
|
|
30759
|
+
}
|
|
30760
|
+
createEntry(symbol) {
|
|
30737
30761
|
const color = this.assignColor();
|
|
30738
30762
|
const entry = {
|
|
30739
30763
|
symbol,
|
|
@@ -30744,7 +30768,7 @@ var CompareManager = class {
|
|
|
30744
30768
|
this.entries.set(symbol, entry);
|
|
30745
30769
|
this.order.push(symbol);
|
|
30746
30770
|
this.emitter.emit("compareAdded", { symbol, color });
|
|
30747
|
-
|
|
30771
|
+
return entry;
|
|
30748
30772
|
}
|
|
30749
30773
|
remove(symbol) {
|
|
30750
30774
|
if (!this.entries.has(symbol)) return;
|
|
@@ -37547,6 +37571,8 @@ var _ChartEngine = class _ChartEngine {
|
|
|
37547
37571
|
this.valueTooltipEnabled = false;
|
|
37548
37572
|
this.valueTooltip = null;
|
|
37549
37573
|
this.compareLegend = null;
|
|
37574
|
+
/** Inputs the compare chips were last computed from (see syncCompareLegend). */
|
|
37575
|
+
this._compareLegendKey = "";
|
|
37550
37576
|
this.comparePickerModal = null;
|
|
37551
37577
|
this.compareDataLoader = null;
|
|
37552
37578
|
/** Crosshair-hovered bar index used to drive live compare percent values. */
|
|
@@ -42270,7 +42296,11 @@ var _ChartEngine = class _ChartEngine {
|
|
|
42270
42296
|
tfcEnabled: this.tfcActive,
|
|
42271
42297
|
viewport: this.getViewportTimestamps(),
|
|
42272
42298
|
priceScale: this.priceScaleFactor !== 1 || this.pricePanOffset !== 0 ? { factor: this.priceScaleFactor, panOffset: this.pricePanOffset } : void 0,
|
|
42273
|
-
|
|
42299
|
+
// Always a list when compare is available — `[]` once the last one
|
|
42300
|
+
// is removed. Hosts merge the saved block over the stored one, so
|
|
42301
|
+
// leaving the key out kept the old list on the server and the
|
|
42302
|
+
// compares came back on the trader's other devices.
|
|
42303
|
+
compares: this.compareManager ? this.compareManager.list().map((e) => e.symbol) : void 0
|
|
42274
42304
|
};
|
|
42275
42305
|
}
|
|
42276
42306
|
/**
|
|
@@ -42390,12 +42420,26 @@ var _ChartEngine = class _ChartEngine {
|
|
|
42390
42420
|
};
|
|
42391
42421
|
}
|
|
42392
42422
|
}
|
|
42393
|
-
if (
|
|
42394
|
-
this.compareManager
|
|
42395
|
-
|
|
42396
|
-
|
|
42423
|
+
if (Array.isArray(state.compares) && this.compareManager) {
|
|
42424
|
+
const cm = this.compareManager;
|
|
42425
|
+
const current = cm.list().map((e) => e.symbol);
|
|
42426
|
+
const same = current.length === state.compares.length && current.every((s, i) => s === state.compares[i]);
|
|
42427
|
+
if (!same) {
|
|
42428
|
+
cm.clear();
|
|
42429
|
+
for (const sym of state.compares) {
|
|
42430
|
+
if (cm.hasRange()) {
|
|
42431
|
+
void cm.add(sym).then(() => {
|
|
42432
|
+
this.recomputeIndicators();
|
|
42433
|
+
this.refreshCompareLegend();
|
|
42434
|
+
this.scheduleRender();
|
|
42435
|
+
});
|
|
42436
|
+
} else {
|
|
42437
|
+
cm.addPending(sym);
|
|
42438
|
+
}
|
|
42439
|
+
}
|
|
42440
|
+
this.recomputeIndicators();
|
|
42441
|
+
this.refreshCompareLegend();
|
|
42397
42442
|
}
|
|
42398
|
-
this.refreshCompareLegend();
|
|
42399
42443
|
}
|
|
42400
42444
|
} finally {
|
|
42401
42445
|
this.isRestoringState = false;
|
|
@@ -42957,6 +43001,20 @@ var _ChartEngine = class _ChartEngine {
|
|
|
42957
43001
|
console.warn("[acttrader-charts] setDraftOrderLabels() is deprecated and is a no-op. DraftOrderQtyInput has been removed.");
|
|
42958
43002
|
return this;
|
|
42959
43003
|
}
|
|
43004
|
+
/**
|
|
43005
|
+
* Choose the glyph the next `icon` drawing places — what a tap in the
|
|
43006
|
+
* Emojis / Stickers / Icons picker does. For hosts that draw their own
|
|
43007
|
+
* picker from the catalog's `glyphTabs` (the native apps): call this, then
|
|
43008
|
+
* `setDrawingTool('icon')`. `kind` sets the size and whether the drawing
|
|
43009
|
+
* colour applies (stickers are larger; icons take the colour). An empty
|
|
43010
|
+
* glyph is ignored.
|
|
43011
|
+
*/
|
|
43012
|
+
setIconGlyph(glyph, kind = "emoji") {
|
|
43013
|
+
if (typeof glyph !== "string" || glyph.length === 0) return this;
|
|
43014
|
+
this.pendingIconGlyph = glyph;
|
|
43015
|
+
this.pendingIconKind = kind === "sticker" || kind === "icon" ? kind : "emoji";
|
|
43016
|
+
return this;
|
|
43017
|
+
}
|
|
42960
43018
|
setDrawingTool(tool) {
|
|
42961
43019
|
this.drawingManager.setActiveTool(tool);
|
|
42962
43020
|
this.leftBar?.setActiveTool(tool);
|
|
@@ -45570,6 +45628,31 @@ var _ChartEngine = class _ChartEngine {
|
|
|
45570
45628
|
});
|
|
45571
45629
|
this.compareLegend.update(states);
|
|
45572
45630
|
}
|
|
45631
|
+
/**
|
|
45632
|
+
* Called from render while comparing. The lines re-base to the leftmost
|
|
45633
|
+
* visible bar every frame; the chips used to be computed only on
|
|
45634
|
+
* add/remove/crosshair, so after a scroll, zoom, new bar or refetch they
|
|
45635
|
+
* showed a % from an older view. Recompute them whenever anything the
|
|
45636
|
+
* chip % depends on has changed.
|
|
45637
|
+
*/
|
|
45638
|
+
syncCompareLegend(baselineIdx, entries) {
|
|
45639
|
+
const all = this.dataStore.all;
|
|
45640
|
+
const last = all[all.length - 1];
|
|
45641
|
+
const key = [
|
|
45642
|
+
baselineIdx,
|
|
45643
|
+
all.length,
|
|
45644
|
+
last?.time,
|
|
45645
|
+
last?.close,
|
|
45646
|
+
this.compareHoveredIndex,
|
|
45647
|
+
...entries.map((e) => {
|
|
45648
|
+
const b = e.bars[e.bars.length - 1];
|
|
45649
|
+
return `${e.symbol}:${e.status}:${e.bars.length}:${b?.time}:${b?.close}`;
|
|
45650
|
+
})
|
|
45651
|
+
].join("|");
|
|
45652
|
+
if (key === this._compareLegendKey) return;
|
|
45653
|
+
this._compareLegendKey = key;
|
|
45654
|
+
this.refreshCompareLegend();
|
|
45655
|
+
}
|
|
45573
45656
|
/** Returns the index of the leftmost visible bar in the primary store,
|
|
45574
45657
|
* used as the baseline anchor for percent-change normalization. */
|
|
45575
45658
|
compareBaselineIndex(primaryBars) {
|
|
@@ -45683,6 +45766,7 @@ var _ChartEngine = class _ChartEngine {
|
|
|
45683
45766
|
(e) => e.status === "ready" && e.bars.length > 0 ? buildComparePctSeries(e.bars, primaryTimes, baselineIdx ?? 0) : []
|
|
45684
45767
|
);
|
|
45685
45768
|
compareColors = entries.map((e) => e.color);
|
|
45769
|
+
this.syncCompareLegend(baselineIdx, entries);
|
|
45686
45770
|
bars = transformBarsToPct(absBars, baseline);
|
|
45687
45771
|
pctTargetRange = combinedPercentRange(
|
|
45688
45772
|
absBars,
|