@trdrs/quickcharts 3.0.0 → 4.1.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/README.md +270 -30
  3. package/dist/{ar-HLKX6L6O.js → ar-VILLYPAA.js} +208 -56
  4. package/dist/ar-VILLYPAA.js.map +1 -0
  5. package/dist/{assets-C1VjN7DP.d.ts → assets-BF-NDyHl.d.ts} +288 -60
  6. package/dist/{ca_ES-3ALUJ2FI.js → ca_ES-EJXLAXOA.js} +208 -56
  7. package/dist/ca_ES-EJXLAXOA.js.map +1 -0
  8. package/dist/chunk-TBOVLJAK.js +12091 -0
  9. package/dist/chunk-TBOVLJAK.js.map +1 -0
  10. package/dist/{de-GXKOZYHP.js → de-PHID4SVN.js} +208 -56
  11. package/dist/de-PHID4SVN.js.map +1 -0
  12. package/dist/drawings.d.ts +34 -12
  13. package/dist/drawings.js +11 -1
  14. package/dist/{es-R7WSUWO2.js → es-KD4FBLOP.js} +208 -56
  15. package/dist/es-KD4FBLOP.js.map +1 -0
  16. package/dist/feature-manifest.json +74 -11
  17. package/dist/{fr-EBUMQLPT.js → fr-KTTX3FF3.js} +208 -56
  18. package/dist/fr-KTTX3FF3.js.map +1 -0
  19. package/dist/{he_IL-GCAXKEWB.js → he_IL-Z3DXMAKZ.js} +208 -56
  20. package/dist/he_IL-Z3DXMAKZ.js.map +1 -0
  21. package/dist/{id_ID-6JYEEKEA.js → id_ID-FFX6X4C5.js} +208 -56
  22. package/dist/id_ID-FFX6X4C5.js.map +1 -0
  23. package/dist/index.d.ts +1852 -1720
  24. package/dist/index.js +4664 -1870
  25. package/dist/index.js.map +1 -1
  26. package/dist/{it-IMLHI5VO.js → it-X2GFCLGU.js} +208 -56
  27. package/dist/it-X2GFCLGU.js.map +1 -0
  28. package/dist/{ja-QDEQ2EYA.js → ja-TG3WO2KH.js} +208 -56
  29. package/dist/ja-TG3WO2KH.js.map +1 -0
  30. package/dist/{ko-MTA7BZI3.js → ko-4HHHO7KV.js} +208 -56
  31. package/dist/ko-4HHHO7KV.js.map +1 -0
  32. package/dist/{ms_MY-K4EAHE5J.js → ms_MY-HPVQKVPY.js} +208 -56
  33. package/dist/ms_MY-HPVQKVPY.js.map +1 -0
  34. package/dist/{pl-CIIDQ3SB.js → pl-2W2HP34O.js} +208 -56
  35. package/dist/pl-2W2HP34O.js.map +1 -0
  36. package/dist/{pt-3HA2PDUN.js → pt-XQUBSXO7.js} +208 -56
  37. package/dist/pt-XQUBSXO7.js.map +1 -0
  38. package/dist/quickcharts.css +1660 -424
  39. package/dist/{ru-2F2VGHMW.js → ru-XKFQPFDM.js} +208 -56
  40. package/dist/ru-XKFQPFDM.js.map +1 -0
  41. package/dist/{sv-HCBRKFRZ.js → sv-ZMEGAPCR.js} +208 -56
  42. package/dist/sv-ZMEGAPCR.js.map +1 -0
  43. package/dist/{th-WWPM2QKB.js → th-4735BUT4.js} +208 -56
  44. package/dist/th-4735BUT4.js.map +1 -0
  45. package/dist/theme-manifest.json +148 -14
  46. package/dist/{tr-M57AMCWK.js → tr-PG3CW2L3.js} +208 -56
  47. package/dist/tr-PG3CW2L3.js.map +1 -0
  48. package/dist/{vi-YJHN2OK7.js → vi-YPRIAJ33.js} +208 -56
  49. package/dist/vi-YPRIAJ33.js.map +1 -0
  50. package/dist/{zh-AIFC65OE.js → zh-RVHEWNSW.js} +208 -56
  51. package/dist/zh-RVHEWNSW.js.map +1 -0
  52. package/dist/{zh_TW-2LLLW4H6.js → zh_TW-ZFJMDA64.js} +208 -56
  53. package/dist/zh_TW-ZFJMDA64.js.map +1 -0
  54. package/package.json +1 -1
  55. package/dist/ar-HLKX6L6O.js.map +0 -1
  56. package/dist/ca_ES-3ALUJ2FI.js.map +0 -1
  57. package/dist/chunk-DBJQXHLQ.js +0 -7003
  58. package/dist/chunk-DBJQXHLQ.js.map +0 -1
  59. package/dist/de-GXKOZYHP.js.map +0 -1
  60. package/dist/es-R7WSUWO2.js.map +0 -1
  61. package/dist/fr-EBUMQLPT.js.map +0 -1
  62. package/dist/he_IL-GCAXKEWB.js.map +0 -1
  63. package/dist/id_ID-6JYEEKEA.js.map +0 -1
  64. package/dist/it-IMLHI5VO.js.map +0 -1
  65. package/dist/ja-QDEQ2EYA.js.map +0 -1
  66. package/dist/ko-MTA7BZI3.js.map +0 -1
  67. package/dist/ms_MY-K4EAHE5J.js.map +0 -1
  68. package/dist/pl-CIIDQ3SB.js.map +0 -1
  69. package/dist/pt-3HA2PDUN.js.map +0 -1
  70. package/dist/ru-2F2VGHMW.js.map +0 -1
  71. package/dist/sv-HCBRKFRZ.js.map +0 -1
  72. package/dist/th-WWPM2QKB.js.map +0 -1
  73. package/dist/tr-M57AMCWK.js.map +0 -1
  74. package/dist/vi-YJHN2OK7.js.map +0 -1
  75. package/dist/zh-AIFC65OE.js.map +0 -1
  76. package/dist/zh_TW-2LLLW4H6.js.map +0 -1
package/README.md CHANGED
@@ -1627,7 +1627,13 @@ chrome is painted from it and renders nothing without it.
1627
1627
  asks where to begin rather than choosing a starting bar. Its starting-point menu answers with a
1628
1628
  bar picked on the plot, a date, the first available date, or a random bar. The first available
1629
1629
  date runs `chart.replay.startFirst`: the chart pages the feed's history back to its oldest bar,
1630
- within the 20,000 bars one session holds, and starts there. Undo and
1630
+ within the 20,000 bars one session holds, and starts there. A date opens Select date over the
1631
+ undimmed chart, carried by its title: a date field, on an intraday chart a time field whose clock
1632
+ lists the day in quarter hours, a calendar of the loaded window whose heading turns to the months
1633
+ and the years, and a chip that moves the choice to the first available day. Picking moves the
1634
+ choice and the dialog stays up; Select starts replay at the first bar at or after the date and
1635
+ time, in UTC, and Cancel leaves replay asking where to start. The arrows walk the days, Page Up
1636
+ and Page Down turn the month, Enter picks and Escape closes. Undo and
1631
1637
  redo step back and forward through the active chart's own content, and each names the change it
1632
1638
  would move. Layout setup offers the arrangements and sync switches the chart offers (by default
1633
1639
  the 55 arrangements and the five sync switches); the saved-layouts menu, shown with a layouts
@@ -1929,11 +1935,13 @@ void withMarks
1929
1935
  render can import it.
1930
1936
  A host with a language the package does not ship registers it through `createChartI18n(code,
1931
1937
  { locales })`: a `ChartCustomLocale` names the code, tag, direction and endonym and supplies the
1932
- dictionary chunk, a `ChartDictionary` typed against the English catalog so it cannot miss a key or
1933
- flatten a plural. A code or tag the built-in inventory already holds is refused. A dictionary that
1934
- arrives from data and misses a key reads English for that key and reports it to the `onMissing`
1935
- option. A host can also supply `i18n: ChartI18n` of its own to own its codes, tags, dictionaries,
1936
- loading, and fallback outright.
1938
+ dictionary chunk, a `ChartDictionary` typed against the English catalog so it cannot flatten a
1939
+ plural or miss a key of the major's first release. A key the catalog gains within a major is
1940
+ optional in your dictionary: the chart reads it in English until your dictionary carries it and
1941
+ reports it to the `onMissing` option, and the next major makes it required. A code or tag the
1942
+ built-in inventory already holds is refused. A dictionary that arrives from data and misses a key
1943
+ reads English for that key and reports it to `onMissing` too. A host can also supply
1944
+ `i18n: ChartI18n` of its own to own its codes, tags, dictionaries, loading, and fallback outright.
1937
1945
  Every piece of the chart's own chrome speaks the language; symbols, prices and anything the
1938
1946
  datafeed says are data and pass through untranslated. A host composing the chrome modules itself
1939
1947
  hands them a `ChartI18n` from `createChartI18n(code)` and reads the chart's words for drawing
@@ -2019,24 +2027,58 @@ inventory, and the built-in palettes and the generated stylesheet are built from
2019
2027
  property names are private, so a color, a size or a radius is always set through a role. The
2020
2028
  class names inside the stylesheet are private too, except the supported hooks below.
2021
2029
 
2030
+ ### The built-in palettes
2031
+
2032
+ The two built-in palettes paint every dialog, menu and popover the chart opens from these roles,
2033
+ among the others `THEME_ROLES` lists:
2034
+
2035
+ | Role | Light | Dark | What it paints |
2036
+ |---|---|---|---|
2037
+ | `overlay.surface` | `#ffffff` | `#1f1f1f` | The ground of a dialog, menu or popover. |
2038
+ | `overlay.separator` | `#ebebeb` | `#4a4a4a` | The rule under a dialog header and over its footer, and between menu groups. |
2039
+ | `overlay.scrim` | `rgba(156, 156, 156, 0.5)` | `rgba(0, 0, 0, 0.5)` | The veil behind a modal dialog. |
2040
+ | `text.primary` | `#0f0f0f` | `#dbdbdb` | The ink of rows, labels and values. |
2041
+ | `text.muted` | `#6a6a6a` | `#9b9b9b` | A section title, a hint, a placeholder. |
2042
+ | `chrome.caret` | `#707070` | `#8c8c8c` | The chevron of a select and the arrow that opens a flyout. |
2043
+ | `text.link` | `#2962ff` | `#5b9cf6` | A text link. |
2044
+ | `state.hover` | `#f2f2f2` | `#2e2e2e` | The fill under the pointer. |
2045
+ | `state.pressed` | `#ebebeb` | `#3d3d3d` | The fill while the pointer is down. |
2046
+ | `control.outline` | `#2e2e2e` | `#ffffff` | The edge and the words of an outlined button at rest, such as a dialog's Cancel. |
2047
+ | `control.onInk` | `#ffffff` | `#000000` | A mark cut from the emphasis fill: a chosen thickness, line style or line end. |
2048
+ | `control.neutral` | `#f2f2f2` | `#2e2e2e` | The quiet fill: a dialog's shortcut chip, the band over a calendar's columns, a chosen month or year. |
2049
+ | `control.neutralHover` | `#ebebeb` | `#3d3d3d` | The quiet fill under the pointer. |
2050
+ | `control.neutralPressed` | `#dbdbdb` | `#4a4a4a` | The quiet fill while the pointer is down. |
2051
+ | `control.neutralInk` | `#000000` | `#ffffff` | The words on the quiet fill, and what a quiet control's words and mark brighten to under the pointer, such as a calendar's day. |
2052
+ | `status.positive` | `#078671` | `#089981` | A gain or a success. |
2053
+ | `status.negative` | `#df323f` | `#f34452` | A loss or a failure. |
2054
+ | `status.warning` | `#ac6600` | `#ff9800` | A condition to notice before acting. |
2055
+
2056
+ Every ink is held to the WCAG 2.2 AA ratio on each ground it is drawn over, so the light status
2057
+ inks are the darkest steps of their hues that still read at 4.5 to 1 on white, the dark red reads at
2058
+ 4.5 to 1 on the dialog ground, and the muted ink reads at 4.5 to 1 over the hover and selected fills
2059
+ of a menu row and over the quiet fill. `drawing.line` is `#2962ff` in both modes; `drawing.selected`,
2060
+ the ring of a selected drawing's handles, is `#2962ff` light and `#1e53e5` dark, around a center of
2061
+ `drawing.handle`, the chart's own ground.
2062
+
2022
2063
  ### Fields
2023
2064
 
2024
2065
  Every text field, select, number field and color well the chart draws in its dialogs and settings
2025
2066
  is one box: 34px tall, a 1px edge with an 8px corner around a clear ground, and its words at 14 on
2026
- 18, 8px in from the edge. A select ends in an 18px chevron. Four roles in the `control` family
2027
- paint the box, and the focus ring is `state.focusRing`:
2067
+ 18, 8px in from the edge. A select ends in an 18px chevron in `chrome.caret`. Five roles in the
2068
+ `control` family paint the box, and the focus ring is `state.focusRing`:
2028
2069
 
2029
2070
  | Role | Light | Dark | What it paints |
2030
2071
  |---|---|---|---|
2031
2072
  | `control.fieldEdge` | `#dbdbdb` | `#575757` | The edge of a field at rest. |
2032
2073
  | `control.fieldEdgeHover` | `#a8a8a8` | `#707070` | The edge of a field under the pointer. |
2074
+ | `control.selectEdgeHover` | `#a8a8a8` | `#808080` | The edge of a list button under the pointer, such as a select on a drawing's settings page. |
2033
2075
  | `control.fieldInvalid` | `#f23645` | `#f23645` | The edge and the focus ring of a field holding a value it refuses. |
2034
2076
  | `control.fieldFill` | `#f2f2f2` | `#2e2e2e` | The ground of a field that is read-only or disabled. |
2035
2077
 
2036
2078
  Focus draws a 2px ring over the edge, the edge itself and the pixel inside it, so the ring follows
2037
- the corner and a dialog that scrolls never clips it. A number past its bounds or off its step turns
2038
- the edge `control.fieldInvalid` once the viewer leaves the field, so a number on its way to a valid
2039
- one never turns red while it is typed. The symbol search field draws its own outline in
2079
+ the corner and a dialog that scrolls never clips it. Only a value the chart refuses turns the edge
2080
+ `control.fieldInvalid`; a number past its bounds or off its step is clamped or rounded, so its
2081
+ field never turns red. The symbol search field draws its own outline in
2040
2082
  `chrome.fieldBorder`.
2041
2083
 
2042
2084
  ### Motion
@@ -2052,21 +2094,25 @@ same values:
2052
2094
  | `motion.durationModerate` | `250ms` | A control moving to its new state, such as a switch knob sliding. |
2053
2095
  | `motion.durationSlow` | `350ms` | A small mark settling, such as a disclosure caret turning or a checkbox filling. |
2054
2096
  | `motion.durationSlower` | `500ms` | A larger mark turning, such as the drawing toolbar's chevron. |
2097
+ | `motion.durationGlide` | `100ms` | A mark gliding to a new place, such as a dialog's tab bar or an opacity knob. |
2055
2098
  | `motion.easingStandard` | `ease` | A modal dialog box, the replay row, a caret dip, a checkbox fill. |
2056
2099
  | `motion.easingOut` | `ease-out` | A modal backdrop fading, a switch knob sliding. |
2057
2100
  | `motion.easingLinear` | `linear` | A color or opacity change under the pointer. |
2058
2101
  | `motion.easingSpring` | `cubic-bezier(0.175, 0.885, 0.32, 1.275)` | A caret or chevron turning with a slight overshoot. |
2102
+ | `motion.easingInOut` | `ease-in-out` | A dialog's tab bar sliding to the page shown. |
2059
2103
  | `motion.scaleEnter` | `0.97` | The scale a modal dialog box grows from as it opens. |
2060
2104
 
2061
2105
  Every modal dialog the chart opens (the symbol search, chart settings, the indicator browser and
2062
- indicator settings, the saved-layouts browser, the name and confirm prompts, go to date, and the
2063
- drawing settings, image picker and template prompts) opens with its backdrop fading in over
2106
+ indicator settings, the saved-layouts browser, the name and confirm prompts, and the drawing image
2107
+ picker and template prompts) opens with its backdrop fading in over
2064
2108
  `motion.durationBase` on `motion.easingOut`, and its box fading in and growing from
2065
2109
  `motion.scaleEnter` to full size over `motion.durationBase` on `motion.easingStandard`. It closes
2066
2110
  with the same motion reversed. A closing dialog stops taking input and returns focus at once, and the
2067
2111
  chart removes it when the same `motion.durationBase` has elapsed, so a duration you set times both
2068
2112
  the transition and the removal. A dialog opened over another moves on its own and closes first, and
2069
- a dialog the chart replaces or tears down goes at once.
2113
+ a dialog the chart replaces or tears down goes at once. The drawing settings dialog and the replay
2114
+ date picker work on the chart they stand over, so they open in place: they appear and leave at once,
2115
+ and their backdrop dims nothing while still taking the press that closes them.
2070
2116
 
2071
2117
  A duration takes a CSS duration such as `200ms` or `0.2s`; an easing takes any CSS timing function,
2072
2118
  such as `ease-in-out`, `steps(4)` or `cubic-bezier(0.2, 0, 0, 1)`; a scale takes a unitless factor
@@ -2110,6 +2156,12 @@ between `quickcharts.chart` and `host`. Inline styles the chart writes for measu
2110
2156
  outrank any stylesheet rule, and a rule marked `!important` reverses layer order, so neither is a
2111
2157
  way to restyle the chart.
2112
2158
 
2159
+ The chart states its box model and every inherited text value its measurements are built on at
2160
+ each of its roots, among them the widget's root and its layer on the document body, where its
2161
+ dialogs, menus and panels stand. An unlayered rule of yours that sizes every element by its border
2162
+ box, or the font, line height, weight, letter spacing or alignment you set on your page's body,
2163
+ leaves each of those surfaces as it is measured.
2164
+
2113
2165
  ### Supported styling hooks
2114
2166
 
2115
2167
  A hook is a block-level surface you may write a rule against. Each announces its state through an
@@ -2772,7 +2824,7 @@ re-tile opens in the current one.
2772
2824
 
2773
2825
  ## Drawings
2774
2826
 
2775
- The widget ships with a complete drawing product, on by default: every one of the 90 tools places
2827
+ The widget ships with a complete drawing product, on by default: every one of the 89 tools places
2776
2828
  from the toolbar, the selected drawing gets a floating settings bar and a settings dialog, tool
2777
2829
  defaults and named templates ride the adapter's template family, and a symbol's drawings persist
2778
2830
  through the adapter's drawings family. Turn the whole layer off with `features.drawings: false`,
@@ -2844,14 +2896,180 @@ chosen.
2844
2896
  Selecting a drawing shows the settings bar: templates, the stroke color with its opacity, the
2845
2897
  background for tools that have one, the text color and font size for text tools, thickness and
2846
2898
  line style, the settings gear, lock, delete, and a More menu with the stacking moves, the
2847
- per-timeframe visibility presets, clone, copy and hide. Every edit persists at once and becomes the
2848
- tool's default for the next drawing of that type. The settings dialog opens from the gear with
2899
+ per-timeframe visibility presets, clone, copy and hide. A right-click on a drawing raises its own
2900
+ menu instead of the chart's: a table's edits first, then the templates, the stacking moves and the
2901
+ visibility presets as submenus, clone, copy, lock, hide, remove and the settings. Every edit persists
2902
+ at once and becomes the tool's default for the next drawing of that type. The settings dialog opens from the gear with
2849
2903
  Inputs, Style, Text, Table, Coordinates and Visibility pages as the tool has them; its edits apply
2850
- live, Cancel restores the drawing, and Ok commits the session as one edit.
2851
-
2852
- Text-bearing tools open an inline editor where the text sits, in the drawing's own type. A fresh
2853
- placement committed empty is removed; an existing note committed empty is blanked. Ctrl or Cmd
2854
- with Enter commits, Escape cancels, and a press on the chart commits.
2904
+ live, Cancel restores the drawing, and Ok commits the session as one edit. Its header carries the
2905
+ drawing's name, the tool's own until the viewer renames it with the pencil beside it; the name is
2906
+ `DrawingOptions.name`, saved with the drawing, and Cancel restores it with the rest. A page shown
2907
+ puts the keyboard in its first field, and the dialog keeps its top edge where it opened as pages of
2908
+ other sizes come and go. Its lists hang under the controls that open them, past the dialog's edge
2909
+ where they need to. The Template menu saves the current setup under a name, applies a saved one,
2910
+ or applies the tool's defaults: its own look and setup, put on the drawing at once, with its words
2911
+ kept.
2912
+
2913
+ A color in the dialog opens its popover under the button that holds it: the offered colors, the
2914
+ colors the viewer added with the plus after them, and the opacity, and for a stroke its thickness
2915
+ and line style. Every choice applies at once and the popover stays up for the next one; Escape
2916
+ returns to the button. The plus opens a custom color editor that takes a hex of three or six digits
2917
+ or a pick on its saturation and brightness area and hue strip. A color added there joins the
2918
+ viewer's own, newest first, kept with the drawing preferences in `ChartStorage`, and the settings
2919
+ bar's palette offers them too.
2920
+
2921
+ The line tools' Style page carries the stroke with its two ends, the extensions, the middle point,
2922
+ the price labels and, under Info, the stats a line reads (price range, percent change, the change
2923
+ counted in the symbol's smallest price move, bars, date and time range, its length on the pane,
2924
+ angle), where they stand (left, center, right, or auto, which keeps them inside the pane), and
2925
+ whether they show always or only while the line is selected. A horizontal line offers its price
2926
+ label, a vertical line its time label, a cross line both. A rectangle offers its extensions, its border, a middle line with a stroke
2927
+ of its own and its background; every other shape its border and background; a curve its stroke and
2928
+ ends, its extensions along the tangents it ends on, and its background. A background switched off
2929
+ keeps its color and opacity for when it is switched back on. The Text page sets the words' color,
2930
+ size, weight and slant on one line over the words, and where the tool places them, where they stand:
2931
+ above, on or below a line, above, inside or below a box, along it from left to right, and for a
2932
+ vertical line whether they read across it or run up it. `NO_COORDINATES_TAB` names the tools whose
2933
+ points are drawn rather than typed, and `PRICE_ONLY_COORDS` the levels that span every bar.
2934
+
2935
+ On the chart a line rests as its stroke. While the pointer rests on it its handles show thin, and a
2936
+ press on one moves that point and selects the line; two clicks place a line, its second point
2937
+ following the pointer between them. Selected, a line marks its points' prices and times on the
2938
+ axes, the times in the chart's own format, with a band across their span. A horizontal line's
2939
+ handle stands nine tenths of the way across the pane and a vertical line's nine tenths of the way
2940
+ down, and a drag of either sets both coordinates of its point. An info line stands its stats in a
2941
+ box beside its middle, a row for the price move, one for the span and one for the angle, and a
2942
+ trend angle marks its angle with a dotted level and an arc from its first point.
2943
+
2944
+ A retracement, a trend-based extension and a fib channel lay their levels out two to a line, each
2945
+ level its switch, its value and its color, under the thickness and style every level line is drawn
2946
+ in. The one color recolors every level at once, and shows the color the levels share or a split
2947
+ well while they differ. The bands between levels fill at `backgroundOpacity` while
2948
+ `fillBackground` holds them; `coeffsAsPercents` reads a level's ratio as a percent, and
2949
+ `labelsHAlign` and `labelsVAlign` stand the labels before, at the middle of or after the levels,
2950
+ above, on or below each line. A retracement and an extension draw their trend line through the
2951
+ swing points in a stroke of its own (`trendLine`, `trendLineColor`, `trendLineWidth`,
2952
+ `trendLineStyle`), stand each level's own words where `showText`, `textHAlign` and
2953
+ `textVAlign` put them, and with `levelsOnLogScale` divide the swing by log price while the price
2954
+ scale is logarithmic, which `Viewport.logScale` reports.
2955
+
2956
+ A time zone, a trend-based time, fib circles, speed resistance arcs, a fib wedge and a pitchfan
2957
+ stand their levels one to a line, each level its switch, its value and its own stroke: a level's
2958
+ `width` and `style` draw it apart from the drawing's own. A time zone and a trend-based time label
2959
+ their lines where `labelsHAlign` and `labelsVAlign` put them along and across the pane; a circle
2960
+ fib reads its ratios as percents with `coeffsAsPercents`; an arc fib closes its arcs into circles
2961
+ with `fullCircles`; the trend-based time, the circles, the arcs and the wedge draw a trend line in a
2962
+ stroke of its own, and a pitchfan its median (`medianColor`, `medianWidth`, `medianStyle`). A
2963
+ speed resistance fan and a gann box divide their box on `priceLevels` across it and `timeLevels`
2964
+ down it, each side's labels switched on their own; a fan draws a grid at the divisions in a stroke
2965
+ of its own, and a gann box shades its price and time bands on their own switches and draws its
2966
+ angles corner to corner in `anglesColor`. `reverse` counts a box's divisions from the other
2967
+ corner.
2968
+
2969
+ A pitchfork stands its line pairs one to a line the same way, each pair its switch, its value and
2970
+ its own stroke, under its median's stroke (`medianColor`, `medianWidth`, `medianStyle`) and over
2971
+ the bands between pairs, each in its outer pair's color at `backgroundOpacity` while
2972
+ `fillBackground` is on. `extendLines` runs every line back past the fork's start, and `variant`
2973
+ switches its construction in place: `original`, `schiff`, `modified_schiff` or `inside`.
2974
+ A fib spiral winds clockwise out from its first point, and `counterclockwise` winds it the other
2975
+ way.
2976
+
2977
+ A gann square and a gann square fixed draw a grid of six lines at their fifths (`levels`), fan
2978
+ lines from the corner they count from out to their far sides (`fans`) and arcs about that corner
2979
+ (`arcs`), each line its switch, its color and its width, a fan line or an arc at its ratio of the
2980
+ square's unit, `x` along the time side for `y` along the price side. Their pages set each set
2981
+ under its section, two to a line; the bands between arcs follow `fillBackground` and
2982
+ `backgroundOpacity`, and `reverse` counts from the other corner. A gann square holds its second
2983
+ corner at `scaleRatio` price for every bar between its corners, a ratio it takes from the pane
2984
+ when it is first drawn so it opens square, and typing a Price/bar ratio moves the corner to it; with
2985
+ `showLabels` it reads its price and bar ranges and their ratio under it. A square fixed stays
2986
+ square on the pane whatever its scale. A gann fan draws its rays at their price-to-time ratios, 1/8
2987
+ to 8/1, each in its own stroke, with the bands between them and each ray's ratio at its end.
2988
+
2989
+ A regression trend fits its line through the `source` of the bars between its points: a bar's
2990
+ open, high, low, close or volume, or one of the averages `hl2`, `hlc3`, `ohlc4` and `hlcc4`
2991
+ (`BAR_PRICE_SOURCES`). Its bands stand `upperDeviation` and `lowerDeviation` standard deviations
2992
+ from it, the lower counted down, each shown by `useUpper` and `useLower`; the line and each band
2993
+ switch and stroke on their own (`baseLine`, `upLine`, `downLine` with their colors, widths and
2994
+ styles), `extendLines` runs them to the pane's edges, and `showPearsons` reads the correlation
2995
+ under them.
2996
+
2997
+ A parallel channel draws its levels at ratios of its width, 0 its baseline and 1 the parallel through
2998
+ its third point, each level its switch, its value and its own stroke, over its body between 0 and 1.
2999
+ A flat top/bottom and a disjoint channel end their sides as `leftEnd` and `rightEnd` set and read
3000
+ each side's prices at its ends with `showPrices`, in `pricesColor`, `pricesFontSize`,
3001
+ `pricesBold` and `pricesItalic`. A channel's `fillBackground` switches its body, and its words
3002
+ stand above it, inside it or below it with `textVAlign`, at its start, middle or end with
3003
+ `textHAlign`. A parallel channel's Coordinates page writes its third point as the price its
3004
+ parallel stands from the baseline.
3005
+
3006
+ A sector shades the two halves of its slice, parted by the ray through its arc's middle, in `color1`
3007
+ and `color2` while `fillBackground` is on. A bars pattern paints its captured bars as `mode` says
3008
+ (`BARS_PATTERN_MODES`): `hl` their high-low ranges, `oc` their open-close ranges, or a line through each bar's close, open,
3009
+ high, low or `hl2`. A ghost feed's average candle span is held as a price and written on its page in
3010
+ the symbol's minimum ticks.
3011
+
3012
+ An anchored VWAP weighs the `source` of every bar since its point by the bar's volume, and stands
3013
+ its bands off the average by `bandMultipliers` standard deviations or, with `bandsMode`
3014
+ `percent`, percents of it, each band calculated while its `bandsOn` switch is on. A volume profile
3015
+ reads its rows' volumes beside them with `showValues` and its point of control and shown value
3016
+ area bounds on the price scale with `showLabelsOnPriceScale`. A range meter reads the stats its
3017
+ switches choose in a label of its own color, size and background.
3018
+
3019
+ A text's box switches its background (`fillBackground`) and its border (`drawBorder`, in the
3020
+ drawing's stroke color) on their own, and with `wordWrap` its words wrap at `wordWrapWidth` pixels;
3021
+ a callout's words wrap the same way inside a border at the drawing's width. A note ties a label to
3022
+ the point it notes: its first point is that point, its second the label's, with a line between them
3023
+ in the drawing's stroke color and the label's border in `borderColor`; a pin's words stand in a box
3024
+ of the same kind under its marker. A price note runs a line from its price to a tag that reads it,
3025
+ the tag in a text style and colors of its own (`labelTextColor`, `labelFontSize`, `labelBold`,
3026
+ `labelItalic`, `labelBackgroundColor`, `labelBorderColor`), its words along the line where
3027
+ `textVAlign` and `textHAlign` stand them. A signpost stands on its bar's high, or its low for a
3028
+ plate below the bar, its plate `position` percent of the pane's height away, so the plate keeps its
3029
+ height over the bar as the price scale moves; with `showImage` the plate leads with its `emoji`,
3030
+ and its words read in white or black, whichever reads on the plate. A table stands its cells' words
3031
+ at their left, middle or right with `textHAlign`, its border and grid in the drawing's stroke color.
3032
+
3033
+ A brush fills the area its stroke closes back to its start while `fillBackground` is on, and a brush
3034
+ and a path head their ends with arrows as `leftEnd` and `rightEnd` say, a path with an arrow at its
3035
+ last point at first. A highlighter's width is in pixels, 8 to 96 on its page. The emoji and the
3036
+ sticker have no settings beyond their visibility: a glyph's size is set by its grips on the chart. An
3037
+ icon's page sets its tint, and an image's page chooses its picture from a
3038
+ box that names the formats and the size the intake takes, and sets how see-through it is drawn.
3039
+
3040
+ The pattern tools are read by their letters and carry no words of their own: their Style page sets
3041
+ the letters' color, size, weight and slant on a Label row, then the border and, for the patterns
3042
+ that shade their legs, the background, which `fillBackground` switches off and on keeping its
3043
+ color. A three drives pattern stands on seven points, its reversal after the third drive the last.
3044
+
3045
+ An Elliott wave count writes its labels in its wave's color, as its `degree` writes them: the
3046
+ fifteen degrees from `supermillennium` to `minuscule` (`ELLIOTT_DEGREES`) stand in five threes,
3047
+ each three ringed, in parentheses and bare, in roman numerals or figures and in capitals or small
3048
+ letters. `showWave` switches the wave through its pivots, and the labels stand without it.
3049
+
3050
+ The text, the comment, the note, the signpost, the callout and the pin type their words on the
3051
+ chart. The drawing paints the words as they are typed, with their caret, selection and
3052
+ placeholder, while a field nobody sees, laid exactly over them in their own type and line height,
3053
+ takes the keys: the session's `inline` (`TextInlineEdit`) says where the words stand
3054
+ (`TextEditFrame`) and hears what the field holds (`TextDraft`). Enter and Shift with Enter break
3055
+ the line; Escape, Ctrl or Cmd with Enter, and a press elsewhere commit the words exactly as typed,
3056
+ the drawing still selected after Escape. A click on the words of the selected drawing types again,
3057
+ and a double-click opens its settings. A text, a comment, a note or a signpost left without words
3058
+ stays while it is selected and goes once it is not; a callout left without words goes as its edit
3059
+ ends; a pin keeps its place without words. `AttachDrawingsOptions.placeholder` names the words an
3060
+ empty drawing shows and `AttachDrawingsOptions.inks` the chart's own inks (`DrawingInks`).
3061
+
3062
+ A table types into the cell a click on the selected table lands in, Tab moving on to the next cell
3063
+ and from the last to the first. Its floating bar and its menu add a column right of the cell last
3064
+ typed in and a row below it, or at the table's ends where no cell is, and its menu removes that
3065
+ cell's row and column (`chart.drawings.tableRemoveRow`, `chart.drawings.tableRemoveColumn`). A
3066
+ hovered grid line resizes its column or row, and the corners scale the table. A line types its
3067
+ words along it: a selected line without words invites them where they would stand, turned with the
3068
+ line, and a click there or on its words types them in place; a horizontal ray's words are set in
3069
+ its settings. The price label, the price note, the arrow marks, the arrow marker and the flag open
3070
+ no editor: their words, where they have any, are set in their settings, which a double-click
3071
+ opens. Any other text-bearing tool types in a box of its own: Ctrl or Cmd with Enter commits,
3072
+ Escape cancels, and a press on the chart commits.
2855
3073
 
2856
3074
  Templates are named setups a viewer saves from either surface and applies on demand. They and
2857
3075
  the remembered defaults ride `ChartSaveLoadAdapter.templates('drawing')`, so a host that keeps
@@ -2866,7 +3084,9 @@ adapter they last the page.
2866
3084
 
2867
3085
  The image and glyph tools reach your host through `ChartWidgetOptions.assets`. `intakeImage`
2868
3086
  turns a picked file into a payload within the caps and answers a refusal as a code the chart
2869
- resolves through its own catalog; `glyphSource` answers the artwork URL an emoji or sticker draws
3087
+ resolves through its own catalog. The payload's `dataUrl` is always a PNG or a JPEG, whatever the
3088
+ picked file was, so a saved chart opens everywhere: decode a WEBP and re-encode it on a canvas, as a
3089
+ PNG where it has transparency and a JPEG otherwise; `glyphSource` answers the artwork URL an emoji or sticker draws
2870
3090
  with, or null to draw the glyph as text. Emoji artwork from Twemoji is bundled and works without
2871
3091
  an asset port or external requests. Omit `glyphSource` to use it. It is a chunk of its own, which
2872
3092
  the chart imports the first time it draws an emoji, so a chart that never shows one never loads
@@ -2883,6 +3103,8 @@ layer.armTool('rectangle')
2883
3103
  layer.destroy()
2884
3104
  ```
2885
3105
 
3106
+ A layer you mount yourself is told the symbol's grid, formatter and currency through `setTick`,
3107
+ `setPriceFormatter` and `setCurrency`; a position offers its risk as an amount in that currency.
2886
3108
  A layer you mount yourself arms whatever you arm. Its `copies` option answers whether a new drawing
2887
3109
  may be made as a copy of a drawing of a type: return false for a tool you do not offer, and clone,
2888
3110
  paste and a Control- or Command-drag duplicate make nothing for its drawings, `canPaste` answers
@@ -2896,7 +3118,7 @@ never imports any of it.
2896
3118
  ```ts
2897
3119
  import { buildDrawingToolbarGroups, drawingTools, parseDrawingsStore, restoreDrawings, serializeDrawingsStore } from '@trdrs/quickcharts/drawings'
2898
3120
 
2899
- // The catalog: 90 tools in 14 categories, read-only.
3121
+ // The catalog: 89 tools in 14 categories, read-only.
2900
3122
  const trendLine = drawingTools.get('trend_line')
2901
3123
  const fibs = drawingTools.byCategory('fibonacci')
2902
3124
 
@@ -2936,8 +3158,9 @@ const preset = await templates.defaultFor('trend_line')
2936
3158
  ```
2937
3159
 
2938
3160
  Image-backed and glyph tools reach the host through one explicit asset port. The library owns the
2939
- rules (JPG or PNG, 2 MB, a 2000 px longest edge, downscaled rather than refused) and names each
2940
- refusal with a code that resolves through the chart's own catalog; the host owns the bytes.
3161
+ rules (a JPG, a PNG or a WEBP, stored as a PNG or a JPEG, 2 MB, a 2000 px longest edge, downscaled
3162
+ rather than refused) and names each refusal with a code that resolves through the chart's own
3163
+ catalog; the host owns the bytes.
2941
3164
 
2942
3165
  ```ts
2943
3166
  import { checkImageFile, fittedSize, IMAGE_ACCEPT, type DrawingAssetPort } from '@trdrs/quickcharts/drawings'
@@ -2947,7 +3170,8 @@ const assets: DrawingAssetPort = {
2947
3170
  const bad = checkImageFile(file)
2948
3171
  if (bad) return { ok: false, ...bad }
2949
3172
  const { width, height } = fittedSize(1200, 900)
2950
- return { ok: true, asset: { dataUrl: await myBackend.read(file), width, height, downscaled: false } }
3173
+ // A PNG or a JPEG whatever the picked file was: a WEBP is re-encoded before it is stored.
3174
+ return { ok: true, asset: { dataUrl: await myBackend.pngOrJpeg(file), width, height, downscaled: false } }
2951
3175
  },
2952
3176
  // Optional: glyphSource replaces the bundled emoji artwork.
2953
3177
  // glyphSource: (glyph) => myBackend.emojiUrl(glyph),
@@ -2963,14 +3187,21 @@ What to know:
2963
3187
  - **Every tool places.** Fixed-anchor tools place by press-drag-release or click then click; an
2964
3188
  instant tool (the position tools) lands whole from one press; a multipoint tool adds a point per
2965
3189
  click until a double-click ends the run; a freehand tool captures the drag as a stroke; a
2966
- text-bearing tool opens the inline editor as it lands. `armTool` **throws** only for a name the
2967
- catalog does not know, and `placeableByWidget(type)` answers in advance.
3190
+ text-bearing tool opens the inline editor as it lands; a right-click while a drawing is half
3191
+ placed takes it back and puts the tool down. `armTool` **throws** only for a name the catalog does
3192
+ not know, and `placeableByWidget(type)` answers in advance.
2968
3193
  - **Persistence speaks a shared codec.** The store document (`{ [symbol]: SerializedDrawing[] }`,
2969
3194
  via `parseDrawingsStore`/`serializeDrawingsStore`) is the SAME document every host of the codec
2970
3195
  reads and writes, so drawings survive moving between hosts. A drawing bound to one chart (sync
2971
3196
  off) lives in the adapter's chart-bound scope for the symbol; a shared drawing lives in the
2972
3197
  symbol's scope, and a refused write merges the stored document over the layer's own before it
2973
3198
  writes again.
3199
+ - **A save keeps its look.** A drawing saves at `v: 3` (`SERIAL_VERSION`). A save at `v: 2` restores with the look it
3200
+ was saved with: its tool writes the values that paint it so and saves at `v: 3` with them, the
3201
+ looks the tool's pages do not set riding in the props `INERT_PROPS` lists. A gann square, a gann
3202
+ square fixed, a speed resistance fan, a pitchfan, the text and annotation tools, the marks and a
3203
+ table saved at `v: 2` paint as they were saved (`savedLook`) until their settings change. A host
3204
+ that writes drawings itself writes `v: 3`.
2974
3205
  - **Keys run through the registry.** Delete and Backspace remove the selection, Escape cancels a
2975
3206
  placement, disarms, or closes the inline editor, and Ctrl (or Cmd) with C and V copy and paste a
2976
3207
  drawing. Each resolves to a `chart.drawings.*` command, so your access policy gates the keyboard
@@ -2982,7 +3213,8 @@ What to know:
2982
3213
  a placed or dragged anchor onto the bar's own open, high, low or close; a locked drawing
2983
3214
  selects, takes the Delete and Clone a viewer asks for by name, and refuses a move, a resize, a
2984
3215
  text edit, the eraser and a Ctrl-drag copy; lock all suspends every edit, Delete and Clone
2985
- included, until it is released.
3216
+ included, until it is released. A right-click selects the drawing it lands on, so the menu that
3217
+ follows acts on it, and the handle under a mouse stands out.
2986
3218
 
2987
3219
  ## Extensions
2988
3220
 
@@ -3057,6 +3289,10 @@ What to know:
3057
3289
  default), an action on the price the pointer landed on, placed under Copy price and Paste; or
3058
3290
  `view`, a switch over what the chart shows, placed under the remove rows. Rows keep the order
3059
3291
  they were contributed in within their group.
3292
+ - **A right-click on a drawing carries your rows too.** It raises the drawing's own menu, and your
3293
+ `level` rows stand under its Clone and Copy and your `view` rows under its Remove. On a table,
3294
+ `ChartExtensionMenuContext.table` names it, and `table.cell` says whether a cell of it is being
3295
+ typed in; anywhere else the context carries no `table`.
3060
3296
  - **A drawn layer can join the drawing toolbar's eye.**
3061
3297
  `ctx.contributeHideLayer({ id, label, icon, apply })` lists the layer in the eye's menu after the
3062
3298
  chart's own drawings and indicators and before "Hide all", which blanks it with them. `label`
@@ -3133,6 +3369,10 @@ Every claim in this document maps to a test or a generated artifact in the packa
3133
3369
  and fields (`config` and `serverTime` are the pattern): an existing
3134
3370
  implementation keeps compiling, and the widget treats absence as "unconstrained / not supported".
3135
3371
  Your integration never breaks by standing still within a major.
3372
+ - **A key the catalog gains within a major is optional in a dictionary of your own.**
3373
+ `ChartDictionary` requires every key of the major's first release. A key added since reads English
3374
+ until your dictionary carries it, `onMissing` reports it, and the next major makes it required,
3375
+ its upgrading guide listing each such key.
3136
3376
  - **A major version may rename or remove public names.** Its upgrading guide in
3137
3377
  [CHANGELOG.md](CHANGELOG.md) lists each one, old to new, with how saved state carries over: what
3138
3378
  the previous major saved still opens, and the next save writes the current names.