@trdrs/quickcharts 4.1.0 → 5.0.0
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/CHANGELOG.md +90 -0
- package/README.md +276 -59
- package/dist/adapters/rest.d.ts +4 -4
- package/dist/adapters/rest.js +1 -1
- package/dist/adapters/rest.js.map +1 -1
- package/dist/ar-TG26ZCCE.js +1322 -0
- package/dist/ar-TG26ZCCE.js.map +1 -0
- package/dist/{assets-BF-NDyHl.d.ts → assets-DF3nozNV.d.ts} +161 -17
- package/dist/ca_ES-WJWH5BXU.js +1322 -0
- package/dist/ca_ES-WJWH5BXU.js.map +1 -0
- package/dist/{chunk-D3S26ARP.js → chunk-EXJAJZTN.js} +1 -1
- package/dist/chunk-EXJAJZTN.js.map +1 -0
- package/dist/{chunk-TBOVLJAK.js → chunk-Q3DCXQDW.js} +85 -19
- package/dist/chunk-Q3DCXQDW.js.map +1 -0
- package/dist/de-SUDTTPQ3.js +1322 -0
- package/dist/de-SUDTTPQ3.js.map +1 -0
- package/dist/drawings.d.ts +3 -3
- package/dist/drawings.js +1 -1
- package/dist/es-FOBXUK2X.js +1322 -0
- package/dist/es-FOBXUK2X.js.map +1 -0
- package/dist/feature-manifest.json +105 -9
- package/dist/fr-7KQC4IJH.js +1322 -0
- package/dist/fr-7KQC4IJH.js.map +1 -0
- package/dist/he_IL-2T6XBA6D.js +1322 -0
- package/dist/he_IL-2T6XBA6D.js.map +1 -0
- package/dist/id_ID-SI25N57C.js +1322 -0
- package/dist/id_ID-SI25N57C.js.map +1 -0
- package/dist/index.d.ts +862 -103
- package/dist/index.js +12247 -7910
- package/dist/index.js.map +1 -1
- package/dist/it-PMSTWZDL.js +1322 -0
- package/dist/it-PMSTWZDL.js.map +1 -0
- package/dist/ja-PABDRAXV.js +1322 -0
- package/dist/ja-PABDRAXV.js.map +1 -0
- package/dist/ko-JHRYYFCV.js +1322 -0
- package/dist/ko-JHRYYFCV.js.map +1 -0
- package/dist/ms_MY-U4EE5Q4V.js +1322 -0
- package/dist/ms_MY-U4EE5Q4V.js.map +1 -0
- package/dist/pl-4HCG3T3J.js +1322 -0
- package/dist/pl-4HCG3T3J.js.map +1 -0
- package/dist/pt-6LTNN653.js +1322 -0
- package/dist/pt-6LTNN653.js.map +1 -0
- package/dist/quickcharts.css +586 -198
- package/dist/{resources-C0cYryO9.d.ts → resources-XglhzzW0.d.ts} +4 -2
- package/dist/rest-openapi.json +16 -11
- package/dist/ru-LFHCSDBV.js +1322 -0
- package/dist/ru-LFHCSDBV.js.map +1 -0
- package/dist/sv-4XVUXYK6.js +1322 -0
- package/dist/sv-4XVUXYK6.js.map +1 -0
- package/dist/{symbols-6V22WaRX.d.ts → symbols-DdHLHQFC.d.ts} +77 -8
- package/dist/symbols.d.ts +1 -1
- package/dist/th-WM2PVA24.js +1322 -0
- package/dist/th-WM2PVA24.js.map +1 -0
- package/dist/theme-manifest.json +105 -21
- package/dist/tr-HMAZXSJM.js +1322 -0
- package/dist/tr-HMAZXSJM.js.map +1 -0
- package/dist/vi-ITFBV5B7.js +1322 -0
- package/dist/vi-ITFBV5B7.js.map +1 -0
- package/dist/zh-ZGU2RI7K.js +1322 -0
- package/dist/zh-ZGU2RI7K.js.map +1 -0
- package/dist/zh_TW-PNINSQ6F.js +1322 -0
- package/dist/zh_TW-PNINSQ6F.js.map +1 -0
- package/package.json +1 -1
- package/dist/ar-VILLYPAA.js +0 -1181
- package/dist/ar-VILLYPAA.js.map +0 -1
- package/dist/ca_ES-EJXLAXOA.js +0 -1181
- package/dist/ca_ES-EJXLAXOA.js.map +0 -1
- package/dist/chunk-D3S26ARP.js.map +0 -1
- package/dist/chunk-TBOVLJAK.js.map +0 -1
- package/dist/de-PHID4SVN.js +0 -1181
- package/dist/de-PHID4SVN.js.map +0 -1
- package/dist/es-KD4FBLOP.js +0 -1181
- package/dist/es-KD4FBLOP.js.map +0 -1
- package/dist/fr-KTTX3FF3.js +0 -1181
- package/dist/fr-KTTX3FF3.js.map +0 -1
- package/dist/he_IL-Z3DXMAKZ.js +0 -1181
- package/dist/he_IL-Z3DXMAKZ.js.map +0 -1
- package/dist/id_ID-FFX6X4C5.js +0 -1181
- package/dist/id_ID-FFX6X4C5.js.map +0 -1
- package/dist/it-X2GFCLGU.js +0 -1181
- package/dist/it-X2GFCLGU.js.map +0 -1
- package/dist/ja-TG3WO2KH.js +0 -1181
- package/dist/ja-TG3WO2KH.js.map +0 -1
- package/dist/ko-4HHHO7KV.js +0 -1181
- package/dist/ko-4HHHO7KV.js.map +0 -1
- package/dist/ms_MY-HPVQKVPY.js +0 -1181
- package/dist/ms_MY-HPVQKVPY.js.map +0 -1
- package/dist/pl-2W2HP34O.js +0 -1181
- package/dist/pl-2W2HP34O.js.map +0 -1
- package/dist/pt-XQUBSXO7.js +0 -1181
- package/dist/pt-XQUBSXO7.js.map +0 -1
- package/dist/ru-XKFQPFDM.js +0 -1181
- package/dist/ru-XKFQPFDM.js.map +0 -1
- package/dist/sv-ZMEGAPCR.js +0 -1181
- package/dist/sv-ZMEGAPCR.js.map +0 -1
- package/dist/th-4735BUT4.js +0 -1181
- package/dist/th-4735BUT4.js.map +0 -1
- package/dist/tr-PG3CW2L3.js +0 -1181
- package/dist/tr-PG3CW2L3.js.map +0 -1
- package/dist/vi-YPRIAJ33.js +0 -1181
- package/dist/vi-YPRIAJ33.js.map +0 -1
- package/dist/zh-RVHEWNSW.js +0 -1181
- package/dist/zh-RVHEWNSW.js.map +0 -1
- package/dist/zh_TW-ZFJMDA64.js +0 -1181
- package/dist/zh_TW-ZFJMDA64.js.map +0 -1
package/README.md
CHANGED
|
@@ -43,15 +43,35 @@ await widget.ready()
|
|
|
43
43
|
Implement `ChartDatafeed` (see `datafeed.ts`). Required methods: `search`, `resolve`, `history`,
|
|
44
44
|
`subscribeBars`. Optional: `serverTime` (countdown skew correction) and `config` (a feed-level
|
|
45
45
|
capability declaration, described [below](#capability-declaration-config-optional)). The datafeed serves
|
|
46
|
-
symbol metadata, bars and bar updates
|
|
47
|
-
book) to its own consumers from its own source.
|
|
46
|
+
symbol metadata, bars and bar updates.
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
`subscribePrices(symbol, { onPrices })`, also optional, serves the prices one symbol stands at
|
|
49
|
+
(`SymbolPrices`: `bid`, `ask`, `last`, and `previousClose` or the `change` since it) and returns the
|
|
50
|
+
unsubscribe. A delivery may carry only what moved; a field it leaves out keeps its last value. The
|
|
51
|
+
chart subscribes only while a setting draws the prices: the bid and ask labels and lines, the
|
|
52
|
+
legend's change since the previous close, the previous close's label and line, and the percentage
|
|
53
|
+
under the last value. Without the port the bid and ask draw nothing, and the previous close is the
|
|
54
|
+
last regular-hours close of the trading day before the newest bar's, read off the bars.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import type { ChartDatafeed, SymbolPrices } from '@trdrs/quickcharts'
|
|
58
|
+
declare const feed: ChartDatafeed
|
|
59
|
+
declare function onBook(symbol: string, push: (prices: SymbolPrices) => void): () => void
|
|
60
|
+
|
|
61
|
+
const withPrices: ChartDatafeed = {
|
|
62
|
+
...feed,
|
|
63
|
+
subscribePrices: (symbol, { onPrices }) => onBook(symbol, onPrices),
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
While the `priceLabels.countdown` setting is on, as it is by default, a live streaming time bar
|
|
68
|
+
replaces the native last-value label with one price-and-time label. The price uses the resolved symbol formatter. Replay, stale,
|
|
51
69
|
delayed or end-of-day data, tick bars, closed declared sessions and missing bars retain the native
|
|
52
70
|
price label. `serverTime` corrects clock skew when available; absence or failure uses the client
|
|
53
71
|
clock. Bar opens define fixed and calendar alignment, and declared session facts shorten only a
|
|
54
|
-
bar they actually close.
|
|
72
|
+
bar they actually close. Under `priceLabels.symbolValueMode: 'priceAndPercent'` the same label
|
|
73
|
+
writes the change since the previous session's close under the price, two decimals and its sign,
|
|
74
|
+
with the countdown beneath that; each line is 14px below the one before at the 12px text size.
|
|
55
75
|
|
|
56
76
|
`resolve` answers with `SymbolInfo`, the symbology contract ([Symbology](#symbology)): the
|
|
57
77
|
symbol's identity (`ticker`, `name`, `description`), venue and type (`exchange`,
|
|
@@ -631,8 +651,8 @@ A layout also refuses writes while any child chart is not saving. A complete lay
|
|
|
631
651
|
its children only after the whole content and layout binding commit, and detaches their previous
|
|
632
652
|
standalone chart bindings. Partial content and copy saves do not establish recovery.
|
|
633
653
|
|
|
634
|
-
A saved chart carries its symbol, timeframe, style, scale,
|
|
635
|
-
state, combined-mode drawings, and every indicator instance. Indicator definitions remain code in
|
|
654
|
+
A saved chart carries its symbol, timeframe, style, scale, the chart settings a viewer chose,
|
|
655
|
+
comparisons, extension state, combined-mode drawings, and every indicator instance. Indicator definitions remain code in
|
|
636
656
|
your widget. The blob names each definition by `manifest.id` and carries the instance id, explicit
|
|
637
657
|
inputs, color, title, overrides and hidden state. Loading replaces the full instance list, so the
|
|
638
658
|
constructor's `indicators` are seeds only for a chart with no saved content. Definitions resolve
|
|
@@ -640,12 +660,14 @@ against the widget's built-ins and the host definitions that widget has carried.
|
|
|
640
660
|
access-denied definition is left out with one counted notice while the remaining content lands. A
|
|
641
661
|
definition of your own survives a save only when its manifest declares an `id`.
|
|
642
662
|
|
|
643
|
-
The opaque version-
|
|
663
|
+
The opaque version-5 reader validates the whole indicator list before changing a chart or layout.
|
|
644
664
|
Missing lists, duplicate instance ids and malformed inputs, titles, colors or overrides refuse the
|
|
645
665
|
body as `invalid`; values are not silently filtered or normalized. A load that omits a definition
|
|
646
666
|
because it is unavailable is partial and cannot clear an earlier `notSaving()` state.
|
|
647
|
-
Complete recovery requires
|
|
648
|
-
|
|
667
|
+
Complete recovery requires a `settings` record whose every leaf holds a value its leaf can hold,
|
|
668
|
+
every color a concrete one the renderer paints, and, in combined mode, a drawings array.
|
|
669
|
+
Separate-mode chart content does not need that array. A version-4 blob reads its `appearance`
|
|
670
|
+
record into the settings sections its leaves now live in.
|
|
649
671
|
|
|
650
672
|
Hydration and rollback do not emit `saveNeeded` for their own storage writes. An event already
|
|
651
673
|
queued by a viewer's edit is preserved. A late save result does not replace a newer load's binding;
|
|
@@ -702,7 +724,8 @@ tile.
|
|
|
702
724
|
### Templates
|
|
703
725
|
|
|
704
726
|
`adapter.templates(kind)` is a store per kind: `'indicator'` for indicator settings, `'drawing'` for
|
|
705
|
-
a drawing tool's look,
|
|
727
|
+
a drawing tool's look, `'chart'` for the chart settings a viewer saves from the settings dialog's
|
|
728
|
+
Template menu, and `'palette'`, which the chart itself does not write. A drawing template carries the `tool`
|
|
706
729
|
it belongs to, because a trend-line template means nothing on a rectangle. Their content is opaque,
|
|
707
730
|
like a chart's.
|
|
708
731
|
|
|
@@ -1343,7 +1366,14 @@ function toolbar(widget: ChartWidget): void {
|
|
|
1343
1366
|
|
|
1344
1367
|
A command whose one id spans many subjects declares `refuses(arg)` beside `available()`: an
|
|
1345
1368
|
argument your access policy turns away answers `denied` before availability is asked, which is how
|
|
1346
|
-
`chart.drawings.arm` refuses a tool. `
|
|
1369
|
+
`chart.drawings.arm` refuses a tool. `available(arg)` answers for the subject an argument names, and
|
|
1370
|
+
`commands.available(id, arg)` asks it: `chart.panes.moveUp` and `chart.panes.moveDown` take a pane's
|
|
1371
|
+
index, the top pane 0, so `commands.available('chart.panes.moveUp', 0)` is false, as is a move down
|
|
1372
|
+
for the bottom pane, and asked with no argument either says whether any pane could move.
|
|
1373
|
+
`chart.drawings.placeHorizontalLine` run with no argument places its line at the crosshair's price,
|
|
1374
|
+
so asked with none it answers for that price, and is false while the crosshair is off the main
|
|
1375
|
+
pane's plot. A refused
|
|
1376
|
+
argument is unavailable to ask about. `onChange` fires when the registered set or a shortcut changes,
|
|
1347
1377
|
and when `widget.refreshAccess()` says your policy may answer differently. A refusal is a value,
|
|
1348
1378
|
never a throw: `ok`, `unavailable`,
|
|
1349
1379
|
`denied`, `unknown`, or `failed` with the
|
|
@@ -1525,8 +1555,8 @@ container.before(undo, search)
|
|
|
1525
1555
|
```
|
|
1526
1556
|
|
|
1527
1557
|
The chart's own dialogs still open from their commands while its bars are hidden.
|
|
1528
|
-
`chart.symbol.search`, `chart.indicators.open`, `chart.compare.open
|
|
1529
|
-
them in the widget's layer on the document, and `widget.layout.save` asks a layout that was never
|
|
1558
|
+
`chart.symbol.search`, `chart.indicators.open`, `chart.compare.open`, `chart.settings.open` and
|
|
1559
|
+
`widget.layout.open` raise them in the widget's layer on the document, and `widget.layout.save` asks a layout that was never
|
|
1530
1560
|
saved for its name. Hide a dialog in `ui` when your interface provides its own.
|
|
1531
1561
|
|
|
1532
1562
|
The library draws its own controls over its own renderer and keeps its internal components to
|
|
@@ -1554,7 +1584,8 @@ async function shareable(widget: ChartWidget): Promise<void> {
|
|
|
1554
1584
|
|
|
1555
1585
|
`capture()` composes the chart, or every chart of a layout, into one PNG under a header carrying the
|
|
1556
1586
|
identity and the attribution you configured through `image`. Nothing is uploaded, shared or stored:
|
|
1557
|
-
you receive a blob and decide.
|
|
1587
|
+
you receive a blob and decide. `copy()` and `download()` take the same image, and an extension takes
|
|
1588
|
+
part in each through `contributeCapture` (see Extensions).
|
|
1558
1589
|
|
|
1559
1590
|
### Indicator picker content
|
|
1560
1591
|
|
|
@@ -1639,12 +1670,15 @@ chrome is painted from it and renders nothing without it.
|
|
|
1639
1670
|
the 55 arrangements and the five sync switches); the saved-layouts menu, shown with a layouts
|
|
1640
1671
|
store, saves, copies, renames, opens and deletes layouts through `saveLoad.layouts` and marks
|
|
1641
1672
|
unsaved changes, with an autosave switch and Download chart data.
|
|
1642
|
-
Chart settings
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1673
|
+
Chart settings opens the chart settings dialog: the Symbol, Status line, Scales and lines,
|
|
1674
|
+
Canvas and Events pages of the active chart's settings, and any page an extension adds. Every
|
|
1675
|
+
change previews on the chart; Cancel, the close and Escape put back the viewer's settings, the
|
|
1676
|
+
price-scale mode and the timezone as they were, and Ok keeps them. Its Template menu applies the
|
|
1677
|
+
defaults (`chart.settings.reset`), saves the viewer's settings under a name in
|
|
1678
|
+
`saveLoad.templates('chart')`, and lists the saved ones. `chart.settings.open` opens the same
|
|
1679
|
+
dialog, on the page `{ page }` names, whether or not the bar shows the gear. The theme mode is not
|
|
1680
|
+
among its pages: `ui: { topBar: { settings: { theme: false } } }` stays accepted and changes
|
|
1681
|
+
nothing, and the widget's theme API and theme commands are untouched. Fullscreen and the image menu (Download image, Copy image where the browser can, and
|
|
1648
1682
|
Download chart data when there is no layouts store) close the bar.
|
|
1649
1683
|
- **The bottom bar.** The range presets the chart offers, the clock in the display zone with the
|
|
1650
1684
|
list of the timezones it offers (UTC and the exchange choice first), and the session view for a
|
|
@@ -1662,8 +1696,8 @@ chrome is painted from it and renders nothing without it.
|
|
|
1662
1696
|
image that could not be copied, or a save the store refused.
|
|
1663
1697
|
|
|
1664
1698
|
Undo and redo step through the chart's own content: the symbol, the timeframe, the style, the price
|
|
1665
|
-
scale and whether it frames itself, the
|
|
1666
|
-
indicators and the drawings. A step is one reading of that content, so a step back puts the whole
|
|
1699
|
+
scale and whether it frames itself, the chart settings a viewer authored, the comparisons, the
|
|
1700
|
+
indicators, the order of the panes and the drawings. A step is one reading of that content, so a step back puts the whole
|
|
1667
1701
|
reading back rather than reversing a single verb, and the two controls name the change they would
|
|
1668
1702
|
move. Each chart keeps its own last 100 steps for as long as it is mounted. `chart.history.undo`
|
|
1669
1703
|
and `chart.history.redo` are the verbs, `chart.history` on the handle reads the two stacks, the
|
|
@@ -1802,7 +1836,9 @@ as a `TypeError` when the widget is created.
|
|
|
1802
1836
|
An id names what a glyph means, not one control. `settings` is the top bar's settings button, a
|
|
1803
1837
|
indicator's gear in the legend and the drawing settings bar's gear, so one drawing stands in all
|
|
1804
1838
|
three. Drawing tools take `tool.<type>`, chart styles `style.<style>` and layout arrangements
|
|
1805
|
-
`layout.<code>`, from the registries the rest of the API uses.
|
|
1839
|
+
`layout.<code>`, from the registries the rest of the API uses. The glyphs a time-scale mark wears in
|
|
1840
|
+
its ring take `mark.<shape>`, named for their shapes, since what a mark means is yours (see Neutral
|
|
1841
|
+
marks).
|
|
1806
1842
|
|
|
1807
1843
|
```ts
|
|
1808
1844
|
import { CHART_ICON_IDS, createChart, createUdfDatafeed, type ChartIconFactory, type ChartIcons } from '@trdrs/quickcharts'
|
|
@@ -1864,7 +1900,8 @@ something other than an `<svg>` element, or answers an element already in the do
|
|
|
1864
1900
|
before costs that one glyph its artwork. The control draws the chart's own glyph, and
|
|
1865
1901
|
`widget.chrome.iconDiagnostics()` records the icon's first failure.
|
|
1866
1902
|
|
|
1867
|
-
`icons` covers the chart's own controls
|
|
1903
|
+
`icons` covers the chart's own controls and the glyphs of the time-scale marks, whose ring the chart
|
|
1904
|
+
draws around your drawing in the mark's color. The emoji, sticker and icon glyphs a drawing places come
|
|
1868
1905
|
through the asset port, and a chart extension draws its rows and layers from the
|
|
1869
1906
|
`ChartExtensionIcon` descriptors it contributes. The product's mark in the plot's corner is the
|
|
1870
1907
|
chart's own artwork, outside `icons`. `mountContextMenu`, `openSymbolSearch`, `mountSymbolSearch`,
|
|
@@ -1874,13 +1911,43 @@ you mount without a widget.
|
|
|
1874
1911
|
### Neutral marks
|
|
1875
1912
|
|
|
1876
1913
|
Serve `marks` and `timescaleMarks` from your datafeed and the chart draws them. A mark is a note
|
|
1877
|
-
about a moment: its
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1914
|
+
about a moment: its words are yours, and the chart draws it as given. Its color stays readable in
|
|
1915
|
+
both modes: a semantic theme role (`neutral`, `up`, `down`, `info`, `warning`, `positive` or
|
|
1916
|
+
`negative`) that the mode resolves, or a `MarkColorPair`, `{ light, dark }`, one CSS color for each
|
|
1917
|
+
mode, of which the chart wears the one for the mode in effect. A single color for both modes is not
|
|
1918
|
+
a mark color, since a color chosen for one background can vanish on the other, and a pair with a
|
|
1919
|
+
side the chart cannot paint draws in the `neutral` role.
|
|
1920
|
+
|
|
1921
|
+
A bar mark (`BarMark`) sits on its bar, above or below it, with a letter or two. A time-scale mark
|
|
1922
|
+
(`TimescaleMark`) stands at the foot of the pane:
|
|
1923
|
+
|
|
1924
|
+
- **Its look.** Without `icon` it is a small dot. With one it is a 21px ring in its color, its foot
|
|
1925
|
+
just above the time scale and the chart's background inside, around a glyph of the icon catalog:
|
|
1926
|
+
`mark.bolt`, `mark.flag`, `mark.star`, `mark.clock` or `mark.exclamation`. Your `icons` drawing for
|
|
1927
|
+
one of those ids stands in the ring in place of the chart's own.
|
|
1928
|
+
- **Its line.** `line: { style, color, width }` draws a line through the whole pane at its time,
|
|
1929
|
+
always and under the bars: `solid`, `dashed` (5px drawn, 6px clear) or `dotted` (1px drawn, 4px
|
|
1930
|
+
clear). `color` takes a theme role or a light and dark pair, as a mark's does, and a line without
|
|
1931
|
+
one wears its mark's color; `width` is 1 to 4 CSS pixels, and 1 without it.
|
|
1932
|
+
- **Hovering it.** The pointer over a mark, or a finger or a pen pressing it, runs a dashed line in
|
|
1933
|
+
its color from the top of the pane down to it and tints its ring. A mark with a `label` shows it
|
|
1934
|
+
in a tooltip above the mark, and a mark without one shows the line alone. A press anywhere else
|
|
1935
|
+
lets go of a pressed mark.
|
|
1936
|
+
- **Its time.** A mark stands on the bar whose bucket holds its time, on the next bar when the time
|
|
1937
|
+
falls between bars (a session gap, a weekend), and after the last bar at the slot the time falls
|
|
1938
|
+
in, counting the timeframe's bar interval on from the last bar. Bar replay draws none after the
|
|
1939
|
+
last bar it shows, and a mark outside the view draws nothing.
|
|
1940
|
+
|
|
1941
|
+
The chart asks `marks` for the loaded bars' window (epoch seconds, inclusive of both ends) and
|
|
1942
|
+
`timescaleMarks` for the same window run on past the last bar while the view shows the empty space
|
|
1943
|
+
after it: to the end of the view, and as many bar intervals again as the view spans. It asks again
|
|
1944
|
+
on each page of history, and once the view comes to rest past what it asked for. A mark at a time
|
|
1945
|
+
to come therefore stands in that space as soon as the view reaches it.
|
|
1946
|
+
|
|
1947
|
+
```ts
|
|
1948
|
+
import { type BarMark, type ChartDatafeed, type TimescaleMark } from '@trdrs/quickcharts'
|
|
1949
|
+
|
|
1950
|
+
const withMarks: Pick<ChartDatafeed, 'marks' | 'timescaleMarks'> = {
|
|
1884
1951
|
async marks(symbol, from, to): Promise<readonly BarMark[]> {
|
|
1885
1952
|
const rows = await myBackend.events(symbol, from, to)
|
|
1886
1953
|
return rows.map((row: { id: string; at: number; headline: string }) => ({
|
|
@@ -1891,11 +1958,25 @@ const withMarks: Pick<ChartDatafeed, 'marks'> = {
|
|
|
1891
1958
|
label: row.headline,
|
|
1892
1959
|
}))
|
|
1893
1960
|
},
|
|
1961
|
+
async timescaleMarks(symbol, from, to): Promise<readonly TimescaleMark[]> {
|
|
1962
|
+
const rows = await myBackend.moments(symbol, from, to)
|
|
1963
|
+
return rows.map((row: { id: string; at: number; headline: string }) => ({
|
|
1964
|
+
id: row.id,
|
|
1965
|
+
time: row.at,
|
|
1966
|
+
color: { light: '#7b1fa2', dark: '#ab47bc' },
|
|
1967
|
+
icon: 'mark.bolt',
|
|
1968
|
+
label: row.headline,
|
|
1969
|
+
}))
|
|
1970
|
+
},
|
|
1894
1971
|
}
|
|
1895
1972
|
void withMarks
|
|
1896
1973
|
```
|
|
1897
1974
|
|
|
1898
|
-
|
|
1975
|
+
When a setting of your own changes what your feed serves, `chart.refreshMarks()` asks for both
|
|
1976
|
+
families again at once and draws the answer, so the change shows while your control is still open.
|
|
1977
|
+
The `chart.marks.refresh` command does the same from a menu, a shortcut or an automation adapter,
|
|
1978
|
+
and an extension calls `ctx.refreshMarks()`. `marks: false` draws none, even from a feed that serves
|
|
1979
|
+
them, and asks for none.
|
|
1899
1980
|
|
|
1900
1981
|
### The rest of the widget
|
|
1901
1982
|
|
|
@@ -1904,8 +1985,10 @@ void withMarks
|
|
|
1904
1985
|
- **The price scale** (shown by default; `ui: { priceScale: false }` hides it). Without it the bars
|
|
1905
1986
|
span the chart's whole width, and the last price draws no line across the plot and no label, since
|
|
1906
1987
|
nothing on screen points at one.
|
|
1907
|
-
- **Session bands** (
|
|
1908
|
-
|
|
1988
|
+
- **Session bands** (`features.sessions: false` opts out). While the chart's trading hours show
|
|
1989
|
+
the stretches outside regular hours (`symbol.session` of `extended` or `allHours`), each shades
|
|
1990
|
+
under the bars in the color the settings give it, and the `events.sessionBreaks` setting draws a
|
|
1991
|
+
line at each trading day's start, driven by the session model built from the symbol's own
|
|
1909
1992
|
`session`, `sessionHolidays`, `corrections` and `subsessions` in `resolve()`'s answer (see
|
|
1910
1993
|
Timezones and sessions). A continuous market never bands; intraday only; an UNRESOLVED symbol
|
|
1911
1994
|
never bands, which is the honest default rather than a coerced one, and it is enforced: the
|
|
@@ -1913,7 +1996,10 @@ void withMarks
|
|
|
1913
1996
|
outside a `resolve()`, or supplies its own, calls the primitive's `refresh()` when it does; the
|
|
1914
1997
|
chart does not invalidate the pane on a getter's value changing.
|
|
1915
1998
|
- **A legend** (on by default; `ui: { legend: false }` removes it). The header shows the resolved
|
|
1916
|
-
|
|
1999
|
+
name (the feed's description, its symbol, or both, as `statusLine.titleSource` says), venue,
|
|
2000
|
+
timeframe, OHLC, change against the previous painted close and, when `statusLine.volume` asks,
|
|
2001
|
+
the bar's volume; the `statusLine` settings show or hide each part over a backdrop of the
|
|
2002
|
+
chart's background. Prices use
|
|
1917
2003
|
the symbol's formatter. Hover selects a bar; leaving restores the latest painted reading. Replay
|
|
1918
2004
|
does not expose bars beyond its cursor. Missing metadata leaves the supplied symbol unchanged.
|
|
1919
2005
|
Legend and search rows wear your `symbolMark`, or a decorative monogram without one.
|
|
@@ -2203,30 +2289,111 @@ If a value you supply is not valid for the role it is written for, the chart kee
|
|
|
2203
2289
|
value and reports it. Read `theme.diagnostics()` for the role, the code and a sentence naming the
|
|
2204
2290
|
problem. Configuration errors never reach a render.
|
|
2205
2291
|
|
|
2206
|
-
### Theme and
|
|
2292
|
+
### Theme and chart settings are two ladders
|
|
2207
2293
|
|
|
2208
|
-
The theme palette is the broad brand surface.
|
|
2209
|
-
|
|
2210
|
-
|
|
2294
|
+
The theme palette is the broad brand surface. The chart settings are the specific one: one typed
|
|
2295
|
+
tree, `ChartSettings`, of every property a viewer tunes on a chart, from the candle anatomy and the
|
|
2296
|
+
line styles to the status line, the price labels, the time scale and the canvas. Where both could
|
|
2297
|
+
affect the same pixel, the settings win.
|
|
2211
2298
|
|
|
2212
2299
|
Theme palette precedence, lowest first:
|
|
2213
2300
|
|
|
2214
2301
|
1. the built-in palette for the selected mode;
|
|
2215
2302
|
2. your custom palette for that mode.
|
|
2216
2303
|
|
|
2217
|
-
Chart
|
|
2304
|
+
Chart settings precedence, lowest first:
|
|
2218
2305
|
|
|
2219
|
-
1. the
|
|
2220
|
-
2. the constructor's `
|
|
2221
|
-
3.
|
|
2222
|
-
4. runtime `chart.applyAppearance` patches.
|
|
2306
|
+
1. the theme's factory values for the mode in effect, `chartSettingsDefaults(theme)`;
|
|
2307
|
+
2. the constructor's `settings` partial;
|
|
2308
|
+
3. the viewer's own leaves: a restored chart, the settings dialog, and `chart.applySettings`.
|
|
2223
2309
|
|
|
2224
|
-
Resetting custom palettes returns the chart to the built-in mode and leaves saved chart
|
|
2310
|
+
Resetting custom palettes returns the chart to the built-in mode and leaves saved chart settings
|
|
2225
2311
|
alone.
|
|
2226
2312
|
|
|
2227
|
-
A saved chart carries the
|
|
2228
|
-
|
|
2229
|
-
|
|
2313
|
+
A saved chart carries the settings a viewer chose and no others, so a chart nobody restyled follows
|
|
2314
|
+
whatever theme the host gives it on the next load, and one whose owner picked candle colors opens in
|
|
2315
|
+
those colors on any theme.
|
|
2316
|
+
|
|
2317
|
+
## Chart settings
|
|
2318
|
+
|
|
2319
|
+
`chart.settings()` answers the effective tree; `chart.applySettings(partial)` layers a partial over
|
|
2320
|
+
the viewer's own leaves, ignoring a leaf the tree does not have or a value its leaf cannot hold; and
|
|
2321
|
+
`chart.resetSettings()` drops the viewer's leaves and returns the price scale to normal. The
|
|
2322
|
+
commands are `chart.settings.apply` with `{ settings }` and `chart.settings.reset`. A change is a
|
|
2323
|
+
content change: it marks the chart for saving and is a step of its history.
|
|
2324
|
+
|
|
2325
|
+
```ts
|
|
2326
|
+
import type { ChartWidget } from '@trdrs/quickcharts'
|
|
2327
|
+
declare const widget: ChartWidget
|
|
2328
|
+
|
|
2329
|
+
const chart = widget.activeChart()
|
|
2330
|
+
chart.applySettings({ candles: { upColor: '#26a69a' }, canvas: { marginRight: 20 } })
|
|
2331
|
+
chart.settings().candles.upColor // '#26a69a'
|
|
2332
|
+
widget.commands.execute('chart.settings.apply', { settings: { statusLine: { volume: true } } })
|
|
2333
|
+
chart.resetSettings()
|
|
2334
|
+
```
|
|
2335
|
+
|
|
2336
|
+
The factory values change with the mode in six canvas colors only: the background, both grids,
|
|
2337
|
+
the watermark, and the scale text and lines, each read from its theme role. Every other color is
|
|
2338
|
+
the same in both modes, in `CHART_FACTORY_COLORS`. The sections and what stands behind them:
|
|
2339
|
+
|
|
2340
|
+
- `candles`, `hollowCandles` and `bars`: the body, borders and wick, each on its own switch and in
|
|
2341
|
+
its own pair; coloring by the previous bar's close, written as each bar's own colors; thin bars
|
|
2342
|
+
and the open tick (`hlcBars`).
|
|
2343
|
+
- `line`, `stepLine`, `area` and `baseline`: the price source each bar is drawn from (its open,
|
|
2344
|
+
high or low, its close, or one of their averages), the line's color, style and width, the fills,
|
|
2345
|
+
and the baseline's level as a percentage of the pane. A line or step line in a gradient (the factory
|
|
2346
|
+
look) is stroked from its top color at the highest price on screen to its bottom color at the
|
|
2347
|
+
lowest, and a baseline whose halves differ in width strokes each at its own.
|
|
2348
|
+
- `symbol`: the trading hours (`session`: `regular`, `extended` or `allHours`), which are the
|
|
2349
|
+
chart's subsession, with the shading of the pre-market, post-market and overnight stretches; and
|
|
2350
|
+
the precision every price is written at, through the chart's one formatter.
|
|
2351
|
+
- `statusLine`: the legend's mark, its title and whether the title is the name, the symbol or both,
|
|
2352
|
+
the bar's values, its change and its volume, the latest price's change since the previous
|
|
2353
|
+
session's close (`lastDayChange`) in its direction's color, the indicator rows' titles, inputs
|
|
2354
|
+
and values, and a backdrop of the chart's background at an opacity.
|
|
2355
|
+
- `priceLabels`: the countdown, labels kept apart, the symbol's last value, its dotted line (its
|
|
2356
|
+
color, null to follow the last bar, and width) and its name, and each indicator's value and name.
|
|
2357
|
+
The previous session's close (on an intraday chart), the high and low of the bars in view, and
|
|
2358
|
+
the bid and ask from the feed's prices each take a value box on the scale in their color, a tag
|
|
2359
|
+
beside it ("High", "Low", "Bid", "Ask"), and a dotted line across the plot, each part on its own
|
|
2360
|
+
switch. The high and low wear grey lines and navy labels while their color is null. On an
|
|
2361
|
+
intraday chart of regular hours, a newest bar in a pre-market, post-market or overnight stretch
|
|
2362
|
+
is left off the chart and its close is marked instead, in that stretch's label color. The plus
|
|
2363
|
+
button (`plusButton`) is joined to the crosshair's price label while the crosshair is on the
|
|
2364
|
+
main pane's plot: the renderer paints it with the label, a box as tall as the label one pixel of
|
|
2365
|
+
the chart short of the scale's edge, in the label's fill with a ringed plus in the label's ink. Its
|
|
2366
|
+
press opens the price menu under it, which holds the actions on that price alone: every `level`
|
|
2367
|
+
row an extension contributes, each extension's rows together in the order the extensions
|
|
2368
|
+
attach, and then "Draw horizontal line at" the price, which runs
|
|
2369
|
+
`chart.drawings.placeHorizontalLine` and prints that command's shortcut ("Alt + H" unless you
|
|
2370
|
+
remap it). A chart without its context menu shows no plus.
|
|
2371
|
+
- `priceScale`: where the scales stand (`placement`): `left` stands the main series' scale on
|
|
2372
|
+
the left, with its mode, its framing and every series of the main pane that shares it, and a
|
|
2373
|
+
comparison on a scale of its own on the right; `right` and `auto` keep it on the right, with
|
|
2374
|
+
such a comparison on the left. The auto-scale and logarithmic buttons (`scaleModeButtons`) stand
|
|
2375
|
+
at the foot of the main scale while the pointer is over it, always, or never: "A" switches the
|
|
2376
|
+
scale between framing itself and holding where it was dragged, and "L" between a regular and a
|
|
2377
|
+
logarithmic scale, each the chart's own verb. The currency and unit box (`currencyAndUnit`)
|
|
2378
|
+
names what the symbol's prices are in (its `currencyCode` and `unitId`) at the top of the main
|
|
2379
|
+
scale on the same terms, and shows nothing for a symbol that states neither. The price-to-bar
|
|
2380
|
+
ratio lock (`lockPriceToBarRatio`) holds the price one bar's width spans: engaging it with no
|
|
2381
|
+
`priceToBarRatio` of its own takes the ratio on screen into that leaf, the scale stops framing
|
|
2382
|
+
itself, and every zoom of the time scale rescales the price axis by the same factor about its
|
|
2383
|
+
middle. A scale that is not regular holds no ratio.
|
|
2384
|
+
- `timeScale`: the crosshair label's date format (`CHART_DATE_FORMATS`), the weekday before it, and
|
|
2385
|
+
a clock of 24 hours or of 12, which the axis times follow too. With `keepLeftEdge`, a timeframe
|
|
2386
|
+
change stands the new bars from the moment the view's left edge stood at, showing as many bar
|
|
2387
|
+
slots, asking the feed once for older bars when that moment lies before the first page, in place
|
|
2388
|
+
of fitting the loaded history.
|
|
2389
|
+
- `canvas`: the background, solid or a vertical gradient; each grid's switch, color and stroke; the
|
|
2390
|
+
crosshair's color, stroke and width; the watermark's parts and ink; the scales' text and lines;
|
|
2391
|
+
when the navigation buttons show; when each pane's own buttons show (`paneButtons`): at a pane's
|
|
2392
|
+
top right, move it up or down past its neighbour, delete it, collapse or open it, and maximize or
|
|
2393
|
+
restore it, through the same pane operations and move verbs the legend's rows run, the main pane
|
|
2394
|
+
moving too and otherwise carrying maximize alone while another pane stands; and the margins, the
|
|
2395
|
+
right one in bars. The order the panes stand in is saved with the chart.
|
|
2396
|
+
- `events`: a line at each trading day's start, in its own stroke.
|
|
2230
2397
|
|
|
2231
2398
|
## Compare
|
|
2232
2399
|
|
|
@@ -2351,8 +2518,9 @@ if (model) {
|
|
|
2351
2518
|
parseSessionModel({ timezone: 'Etc/UTC', session: 'later' }) // null: the chart claims no session it cannot read
|
|
2352
2519
|
```
|
|
2353
2520
|
|
|
2354
|
-
Which named session a chart displays is its subsession,
|
|
2355
|
-
|
|
2521
|
+
Which named session a chart displays is its subsession, the chart's `symbol.session` setting, with
|
|
2522
|
+
`regular` as the factory value: `chart.subsession()` reads it and `chart.setSubsession()` writes it
|
|
2523
|
+
as the viewer's own. On a symbol with extended hours, `regular` filters intraday bars to
|
|
2356
2524
|
regular hours and `extended` shows every bar; a symbol with one continuous session has nothing to
|
|
2357
2525
|
filter.
|
|
2358
2526
|
|
|
@@ -2881,8 +3049,13 @@ out instead (see Refused controls), and a command the policy refuses answers `de
|
|
|
2881
3049
|
toolbar as from anywhere else, including `chart.drawings.arm` for a refused tool. A tool your
|
|
2882
3050
|
`drawingTools` list leaves out is not on the toolbar at all (see Offered drawing tools). An image is
|
|
2883
3051
|
placed through `chart.drawings.placeImage`, from the picker or a system-clipboard paste over the
|
|
2884
|
-
chart
|
|
2885
|
-
|
|
3052
|
+
chart, and a horizontal line at a price through `chart.drawings.placeHorizontalLine` with that
|
|
3053
|
+
price, which asks what arming the horizontal line asks and places nothing while lock all holds.
|
|
3054
|
+
Run with no price, as its shortcut `Alt+KeyH` runs it, the command places the line at the
|
|
3055
|
+
crosshair's price while the crosshair stands on the main pane's plot, on the symbol's own price
|
|
3056
|
+
grid, and is unavailable anywhere else, so the key is left to your page there.
|
|
3057
|
+
Every flyout, palette and dialog a surface opens sits inside the chart root and closes with it, and
|
|
3058
|
+
the eye and lock all announce their state through a live region. Lock all also makes Paste
|
|
2886
3059
|
unavailable, so a control never reports success for a drawing the layer refused.
|
|
2887
3060
|
|
|
2888
3061
|
Arm the transient tools by name: `measure` draws a readout the next gesture clears, `zoom` sets
|
|
@@ -3203,10 +3376,11 @@ What to know:
|
|
|
3203
3376
|
table saved at `v: 2` paint as they were saved (`savedLook`) until their settings change. A host
|
|
3204
3377
|
that writes drawings itself writes `v: 3`.
|
|
3205
3378
|
- **Keys run through the registry.** Delete and Backspace remove the selection, Escape cancels a
|
|
3206
|
-
placement, disarms, or closes the inline editor,
|
|
3207
|
-
drawing
|
|
3208
|
-
|
|
3209
|
-
|
|
3379
|
+
placement, disarms, or closes the inline editor, Ctrl (or Cmd) with C and V copy and paste a
|
|
3380
|
+
drawing, and Alt with H places a horizontal line at the crosshair's price while the crosshair
|
|
3381
|
+
stands on the main pane's plot. Each resolves to a `chart.drawings.*` command, so your access
|
|
3382
|
+
policy gates the keyboard as it gates the toolbar; the keys bind to the chart element and never
|
|
3383
|
+
the page, so an embedded chart cannot swallow the host page's keys.
|
|
3210
3384
|
- **Gestures follow the standard grammar.** Drag a drawing to move it (rigid whole-bar translation,
|
|
3211
3385
|
so anchors never drift apart); grab an anchor handle to reshape; hold Shift to constrain a
|
|
3212
3386
|
two-point placement or an anchor drag to 45 degree rays; Ctrl-drag duplicates; the magnet pulls
|
|
@@ -3300,6 +3474,49 @@ What to know:
|
|
|
3300
3474
|
its subject, and `apply(hidden)` is called with the current state at contribution and on every
|
|
3301
3475
|
change. The handle reads `hidden()`, flips `setHidden()` through the same eye the drawing toolbar
|
|
3302
3476
|
drives, and `remove()` withdraws the layer.
|
|
3477
|
+
- **Your settings join the chart settings dialog.** `ctx.contributeSettings(contribution)` adds a
|
|
3478
|
+
page of your own, placed after the page `place.page.after` names (or last), or rows inside one of
|
|
3479
|
+
the chart's pages, placed before the first of the rows `place.before` names (or at its end).
|
|
3480
|
+
`after` names one of the chart's pages or another contributed page, and a list names several, of
|
|
3481
|
+
which the first the dialog holds wins: `after: ['trading', 'canvas']` follows a contributed
|
|
3482
|
+
`trading` page where there is one and the Canvas page otherwise. The order is read once every
|
|
3483
|
+
contribution is known, so a page follows the contributed page it names whichever attached first.
|
|
3484
|
+
Pages that name the same page stand after it in the order their extensions attach, each followed
|
|
3485
|
+
by the pages that name it: the order of `extensions` (an extension attached again on a symbol
|
|
3486
|
+
switch keeps its place), and one extension's pages in the order it contributes them. A page that
|
|
3487
|
+
names no page the dialog holds stands last in the same order. The chart's rows are named by the
|
|
3488
|
+
leaf they edit, such as `background` on the Status line page, and the sections it shows only in
|
|
3489
|
+
some contexts by their own names, such as `indicators`.
|
|
3490
|
+
`build(form)` builds your rows with the form the chart builds its own with: headings, checkbox
|
|
3491
|
+
rows with a hint or a tip, sub-rows, and colors, lists, numbers and sliders, so your rows are the
|
|
3492
|
+
chart's in every measure. The dialog calls `open()` as it opens, `cancel(state)` with what `open`
|
|
3493
|
+
answered when the viewer cancels, `commit()` on Ok and `applyDefaults()` from the Template menu.
|
|
3494
|
+
The returned function withdraws the contribution, and detach withdraws it either way.
|
|
3495
|
+
- **A row of your own can stand in the legend.** `ctx.contributeLegendRow({ element, rank })`
|
|
3496
|
+
places your element in the pane's legend, under the symbol's reading and above the indicator
|
|
3497
|
+
rows, rows of a lower `rank` first and then as they were contributed. The row wears
|
|
3498
|
+
the status line's backdrop like the legend's own parts and takes the pointer, so a press on its
|
|
3499
|
+
controls reaches them rather than the chart, and collapsing the indicator rows leaves it standing.
|
|
3500
|
+
What it holds and whether it shows are yours: fill or hide the element as you like. The returned
|
|
3501
|
+
function takes it out, detach takes it out either way, and the element is given back unchanged.
|
|
3502
|
+
- **A setting of yours can redraw the marks at once.** `ctx.refreshMarks()` asks the datafeed for
|
|
3503
|
+
the chart's bar marks and time-scale marks again and draws the answer, so a row you contribute to
|
|
3504
|
+
the settings dialog previews its change while the dialog is open. A detached context asks nothing.
|
|
3505
|
+
- **What you draw can take part in the chart's image.** `ctx.contributeCapture({ before, paint })`
|
|
3506
|
+
is called around every image the chart produces of itself, by `widget.image.capture()`, `copy()`
|
|
3507
|
+
and `download()` alike. `before()` runs synchronously before the renderer draws the image and may
|
|
3508
|
+
answer a restore, which runs once the image is taken: hold out what you draw, and put it back.
|
|
3509
|
+
The renderer draws every pending change before it takes the image, so a price line you updated
|
|
3510
|
+
or a primitive you asked to redraw shows as it now stands. `paint(target, frame)` runs on the bitmap's
|
|
3511
|
+
2D context once it is drawn, to paint what the chart's canvases do not carry, such as labels on
|
|
3512
|
+
an overlay of your own. The origin is the chart element's top left, which is the top left of
|
|
3513
|
+
`ctx.container`; `frame.width` and `frame.height` are the element's size in CSS pixels, and
|
|
3514
|
+
`frame.pixelRatio` is the image's pixels per CSS pixel. The context arrives untransformed, and
|
|
3515
|
+
the chart puts back its state after each paint. Contributions run in the order their extensions
|
|
3516
|
+
attach and then as they were contributed, restores run the last answered first, and a throw in a
|
|
3517
|
+
`before`, a `paint` or a restore
|
|
3518
|
+
is contained: the image is still produced and every restore still runs. The returned function
|
|
3519
|
+
withdraws the contribution, and detach withdraws it either way.
|
|
3303
3520
|
- **A printed chord is a real binding.** `ChartExtensionMenuItem.shortcut` prints on the row and
|
|
3304
3521
|
answers to the key. The chart's dispatcher offers a press no built-in verb claims to the rows your
|
|
3305
3522
|
`contributeContextMenu` callback returns for the level under the pointer and runs that row's own
|
|
@@ -3329,8 +3546,8 @@ What to know:
|
|
|
3329
3546
|
re-attaches it on every switch, so a market-scoped overlay cannot carry one market's drawing onto
|
|
3330
3547
|
another's bars.
|
|
3331
3548
|
- **A failing extension is its own problem.** A throw in `attach` drops that extension and the
|
|
3332
|
-
chart still mounts; a throw in a subscriber, a menu builder, a command or a teardown
|
|
3333
|
-
contained.
|
|
3549
|
+
chart still mounts; a throw in a subscriber, a menu builder, a command, a capture or a teardown
|
|
3550
|
+
is contained.
|
|
3334
3551
|
- **Layouts attach per chart.** A widget hands its shared options to every chart it tiles, so each
|
|
3335
3552
|
chart gets its own attachment, its own context and its own state slot.
|
|
3336
3553
|
|
package/dist/adapters/rest.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { C as ChartSaveLoadAdapter } from '../resources-
|
|
1
|
+
import { C as ChartSaveLoadAdapter } from '../resources-XglhzzW0.js';
|
|
2
2
|
|
|
3
|
-
/** The
|
|
4
|
-
type RestTemplateKind = 'indicator' | 'drawing' | 'palette';
|
|
5
|
-
/** Which collection a request addresses. Templates are
|
|
3
|
+
/** The four template collections. */
|
|
4
|
+
type RestTemplateKind = 'indicator' | 'drawing' | 'palette' | 'chart';
|
|
5
|
+
/** Which collection a request addresses. Templates are four collections rather than one, so the
|
|
6
6
|
* kind is part of the address rather than a field inside it. */
|
|
7
7
|
type RestCollection = {
|
|
8
8
|
family: 'charts' | 'layouts' | 'drawings';
|