@devexperts/dxcharts-lite 1.0.2 → 2.0.1

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 (258) hide show
  1. package/README.md +2 -2
  2. package/dist/chart/animation/canvas-animation.js +134 -1
  3. package/dist/chart/animation/types/animation.js +43 -1
  4. package/dist/chart/animation/types/color-alpha-animation.d.ts +1 -1
  5. package/dist/chart/animation/types/color-alpha-animation.js +60 -1
  6. package/dist/chart/animation/types/color-transition-animation.d.ts +1 -1
  7. package/dist/chart/animation/types/color-transition-animation.js +86 -1
  8. package/dist/chart/animation/types/viewport-movement-animation.js +63 -1
  9. package/dist/chart/animation/viewport-model-animation.js +20 -1
  10. package/dist/chart/bootstrap.d.ts +51 -48
  11. package/dist/chart/bootstrap.js +449 -1
  12. package/dist/chart/canvas/canvas-bounds-container.d.ts +0 -5
  13. package/dist/chart/canvas/canvas-bounds-container.js +815 -1
  14. package/dist/chart/canvas/canvas-chart-html.js +16 -18
  15. package/dist/chart/canvas/chart-elements.d.ts +1 -4
  16. package/dist/chart/canvas/chart-elements.js +22 -1
  17. package/dist/chart/canvas/cursor.handler.js +122 -1
  18. package/dist/chart/canvas/layout-creator.js +34 -1
  19. package/dist/chart/canvas/y-axis-bounds.container.d.ts +2 -2
  20. package/dist/chart/canvas/y-axis-bounds.container.js +67 -1
  21. package/dist/chart/chart-container.js +1 -1
  22. package/dist/chart/chart.config.d.ts +4 -5
  23. package/dist/chart/chart.config.js +645 -1
  24. package/dist/chart/chart.d.ts +62 -0
  25. package/dist/chart/chart.js +106 -0
  26. package/dist/chart/components/chart/basic-scale.d.ts +2 -2
  27. package/dist/chart/components/chart/basic-scale.js +31 -1
  28. package/dist/chart/components/chart/candle-transformer.functions.js +15 -1
  29. package/dist/chart/components/chart/candle-width-calculator.functions.js +2 -1
  30. package/dist/chart/components/chart/candle.functions.js +44 -1
  31. package/dist/chart/components/chart/chart-area-pan.handler.d.ts +3 -3
  32. package/dist/chart/components/chart/chart-area-pan.handler.js +197 -1
  33. package/dist/chart/components/chart/chart-base.model.js +66 -1
  34. package/dist/chart/components/chart/chart.component.d.ts +7 -3
  35. package/dist/chart/components/chart/chart.component.js +408 -1
  36. package/dist/chart/components/chart/chart.model.d.ts +4 -11
  37. package/dist/chart/components/chart/chart.model.js +954 -1
  38. package/dist/chart/components/chart/data-series.high-low-provider.js +34 -1
  39. package/dist/chart/components/chart/fake-candles.js +97 -1
  40. package/dist/chart/components/chart/price.formatter.js +35 -1
  41. package/dist/chart/components/chart/secondary-chart-colors-pool.js +68 -1
  42. package/dist/chart/components/cross_tool/cross-tool.component.js +85 -1
  43. package/dist/chart/components/cross_tool/cross-tool.drawer.js +32 -1
  44. package/dist/chart/components/cross_tool/cross-tool.model.js +107 -1
  45. package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +137 -1
  46. package/dist/chart/components/cross_tool/types/none.drawer.js +3 -1
  47. package/dist/chart/components/dran-n-drop_helper/drag-n-drop-x.component.js +28 -1
  48. package/dist/chart/components/dran-n-drop_helper/drag-n-drop-y.component.js +24 -1
  49. package/dist/chart/components/dran-n-drop_helper/drag-n-drop.component.js +53 -1
  50. package/dist/chart/components/dynamic-objects/dynamic-objects.component.d.ts +13 -0
  51. package/dist/chart/components/dynamic-objects/dynamic-objects.component.js +20 -0
  52. package/dist/chart/components/dynamic-objects/dynamic-objects.drawer.d.ts +18 -0
  53. package/dist/chart/components/dynamic-objects/dynamic-objects.drawer.js +23 -0
  54. package/dist/chart/components/dynamic-objects/dynamic-objects.model.d.ts +63 -0
  55. package/dist/chart/components/dynamic-objects/dynamic-objects.model.js +136 -0
  56. package/dist/chart/components/events/events-hit-test.drawer.js +63 -1
  57. package/dist/chart/components/events/events.component.js +61 -1
  58. package/dist/chart/components/events/events.drawer.js +195 -1
  59. package/dist/chart/components/events/events.model.js +69 -1
  60. package/dist/chart/components/grid/grid.component.d.ts +2 -2
  61. package/dist/chart/components/grid/grid.component.js +31 -1
  62. package/dist/chart/components/grid/grid.drawer.d.ts +4 -3
  63. package/dist/chart/components/grid/grid.drawer.js +106 -1
  64. package/dist/chart/components/high_low/high-low.component.js +12 -1
  65. package/dist/chart/components/high_low/high-low.drawer.js +126 -1
  66. package/dist/chart/components/highlights/highlights.component.js +46 -1
  67. package/dist/chart/components/highlights/highlights.drawer.js +154 -1
  68. package/dist/chart/components/highlights/highlights.model.js +75 -1
  69. package/dist/chart/components/labels_generator/numeric-axis-labels.generator.d.ts +1 -1
  70. package/dist/chart/components/labels_generator/numeric-axis-labels.generator.js +199 -1
  71. package/dist/chart/components/navigation_map/navigation-map-move.handler.d.ts +2 -2
  72. package/dist/chart/components/navigation_map/navigation-map-move.handler.js +108 -1
  73. package/dist/chart/components/navigation_map/navigation-map.component.js +112 -1
  74. package/dist/chart/components/navigation_map/navigation-map.drawer.js +244 -1
  75. package/dist/chart/components/navigation_map/navigation-map.model.js +33 -2
  76. package/dist/chart/components/pan/chart-pan.component.d.ts +2 -2
  77. package/dist/chart/components/pan/chart-pan.component.js +51 -1
  78. package/dist/chart/components/pane/extent/y-extent-component.d.ts +12 -18
  79. package/dist/chart/components/pane/extent/y-extent-component.js +120 -1
  80. package/dist/chart/components/pane/pane-hit-test.controller.d.ts +2 -2
  81. package/dist/chart/components/pane/pane-hit-test.controller.js +55 -1
  82. package/dist/chart/components/pane/pane-manager.component.d.ts +12 -6
  83. package/dist/chart/components/pane/pane-manager.component.js +149 -1
  84. package/dist/chart/components/pane/pane.component.d.ts +16 -32
  85. package/dist/chart/components/pane/pane.component.js +278 -1
  86. package/dist/chart/components/resizer/bar-resizer.component.js +139 -1
  87. package/dist/chart/components/resizer/bar-resizer.drawer.js +46 -1
  88. package/dist/chart/components/snapshot/snapshot.component.js +48 -1
  89. package/dist/chart/components/volumes/separate-volumes.component.d.ts +6 -10
  90. package/dist/chart/components/volumes/separate-volumes.component.js +63 -1
  91. package/dist/chart/components/volumes/volume-color-resolvers.functions.js +18 -1
  92. package/dist/chart/components/volumes/volumes.component.d.ts +6 -7
  93. package/dist/chart/components/volumes/volumes.component.js +94 -1
  94. package/dist/chart/components/volumes/volumes.drawer.d.ts +5 -12
  95. package/dist/chart/components/volumes/volumes.drawer.js +140 -1
  96. package/dist/chart/components/volumes/volumes.formatter.js +31 -1
  97. package/dist/chart/components/volumes/volumes.model.d.ts +2 -2
  98. package/dist/chart/components/volumes/volumes.model.js +43 -1
  99. package/dist/chart/components/watermark/water-mark.component.js +103 -1
  100. package/dist/chart/components/watermark/water-mark.drawer.js +187 -1
  101. package/dist/chart/components/x_axis/numeric-x-axis-labels.generator.js +27 -1
  102. package/dist/chart/components/x_axis/time/parser/time-formats-matchers.functions.js +187 -1
  103. package/dist/chart/components/x_axis/time/parser/time-formats-parser.functions.js +76 -1
  104. package/dist/chart/components/x_axis/time/parser/time-formats-validators.functions.js +79 -1
  105. package/dist/chart/components/x_axis/time/parser/time-formats.model.js +14 -1
  106. package/dist/chart/components/x_axis/time/x-axis-weights.functions.d.ts +1 -1
  107. package/dist/chart/components/x_axis/time/x-axis-weights.functions.js +143 -1
  108. package/dist/chart/components/x_axis/time/x-axis-weights.generator.js +73 -1
  109. package/dist/chart/components/x_axis/x-axis-draw.functions.js +49 -1
  110. package/dist/chart/components/x_axis/x-axis-labels.drawer.js +70 -1
  111. package/dist/chart/components/x_axis/x-axis-labels.generator.d.ts +2 -2
  112. package/dist/chart/components/x_axis/x-axis-labels.generator.js +332 -1
  113. package/dist/chart/components/x_axis/x-axis-labels.model.js +35 -1
  114. package/dist/chart/components/x_axis/x-axis-scale.handler.d.ts +2 -2
  115. package/dist/chart/components/x_axis/x-axis-scale.handler.js +60 -1
  116. package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +82 -1
  117. package/dist/chart/components/x_axis/x-axis.component.d.ts +2 -2
  118. package/dist/chart/components/x_axis/x-axis.component.js +119 -1
  119. package/dist/chart/components/y_axis/label-color.functions.js +53 -1
  120. package/dist/chart/components/y_axis/numeric-y-axis-labels.generator.d.ts +4 -4
  121. package/dist/chart/components/y_axis/numeric-y-axis-labels.generator.js +33 -1
  122. package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.d.ts +3 -3
  123. package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.js +67 -1
  124. package/dist/chart/components/y_axis/price_labels/labels-positions-calculator.js +56 -1
  125. package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.d.ts +4 -3
  126. package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +96 -1
  127. package/dist/chart/components/y_axis/price_labels/price-label.drawer.d.ts +2 -2
  128. package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +119 -1
  129. package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.d.ts +9 -8
  130. package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +201 -1
  131. package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.d.ts +6 -7
  132. package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.js +58 -1
  133. package/dist/chart/components/y_axis/y-axis-base-labels.model.d.ts +6 -4
  134. package/dist/chart/components/y_axis/y-axis-base-labels.model.js +47 -1
  135. package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +4 -4
  136. package/dist/chart/components/y_axis/y-axis-labels.drawer.js +161 -1
  137. package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +2 -2
  138. package/dist/chart/components/y_axis/y-axis-scale.handler.js +72 -1
  139. package/dist/chart/components/y_axis/y-axis.component.d.ts +32 -41
  140. package/dist/chart/components/y_axis/y-axis.component.js +220 -1
  141. package/dist/chart/components/y_axis/y-axis.drawer.d.ts +9 -12
  142. package/dist/chart/components/y_axis/y-axis.drawer.js +96 -1
  143. package/dist/chart/components/y_axis/y-axis.model.d.ts +10 -17
  144. package/dist/chart/components/y_axis/y-axis.model.js +34 -1
  145. package/dist/chart/drawers/chart-background.drawer.js +69 -1
  146. package/dist/chart/drawers/chart-type-drawers/area.drawer.js +69 -1
  147. package/dist/chart/drawers/chart-type-drawers/bar.drawer.js +57 -1
  148. package/dist/chart/drawers/chart-type-drawers/baseline.drawer.js +84 -1
  149. package/dist/chart/drawers/chart-type-drawers/candle.drawer.js +162 -1
  150. package/dist/chart/drawers/chart-type-drawers/histogram.drawer.js +57 -1
  151. package/dist/chart/drawers/chart-type-drawers/line.drawer.js +38 -1
  152. package/dist/chart/drawers/chart-type-drawers/scatter-plot.drawer.js +19 -1
  153. package/dist/chart/drawers/clear-canvas.drawer.js +14 -1
  154. package/dist/chart/drawers/composite.drawer.js +67 -1
  155. package/dist/chart/drawers/data-series-drawers/candle-series-wrapper.js +50 -1
  156. package/dist/chart/drawers/data-series-drawers/color-candle.drawer.js +35 -1
  157. package/dist/chart/drawers/data-series-drawers/data-series-drawers.utils.js +16 -1
  158. package/dist/chart/drawers/data-series-drawers/difference-cloud.drawer.js +106 -1
  159. package/dist/chart/drawers/data-series-drawers/histogram.drawer.js +23 -1
  160. package/dist/chart/drawers/data-series-drawers/linear.drawer.js +19 -1
  161. package/dist/chart/drawers/data-series-drawers/points.drawer.js +19 -1
  162. package/dist/chart/drawers/data-series-drawers/rectangular-tool.drawer.js +7 -1
  163. package/dist/chart/drawers/data-series-drawers/text.drawer.js +25 -1
  164. package/dist/chart/drawers/data-series-drawers/trend-histogram.drawer.js +35 -1
  165. package/dist/chart/drawers/data-series-drawers/triangle.drawer.js +22 -1
  166. package/dist/chart/drawers/data-series.drawer.d.ts +5 -7
  167. package/dist/chart/drawers/data-series.drawer.js +56 -1
  168. package/dist/chart/drawers/drawing-manager.d.ts +1 -1
  169. package/dist/chart/drawers/drawing-manager.js +177 -1
  170. package/dist/chart/drawers/ht-data-series.drawer.js +37 -1
  171. package/dist/chart/events/event-bus.js +73 -1
  172. package/dist/chart/events/events.js +3 -1
  173. package/dist/chart/inputhandlers/candle-tap.handler.js +46 -1
  174. package/dist/chart/inputhandlers/chart-resize.handler.js +98 -1
  175. package/dist/chart/inputhandlers/cross-event-producer.component.js +67 -1
  176. package/dist/chart/inputhandlers/hover-producer.component.d.ts +2 -2
  177. package/dist/chart/inputhandlers/hover-producer.component.js +228 -1
  178. package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +2 -2
  179. package/dist/chart/inputhandlers/main-canvas-touch.handler.js +80 -1
  180. package/dist/chart/inputlisteners/canvas-input-listener.component.js +629 -1
  181. package/dist/chart/model/baseline.model.js +88 -1
  182. package/dist/chart/model/bounds.model.js +1 -1
  183. package/dist/chart/model/candle-hover.js +70 -1
  184. package/dist/chart/model/candle-series-high-low.provider.js +45 -1
  185. package/dist/chart/model/candle-series.model.d.ts +3 -3
  186. package/dist/chart/model/candle-series.model.js +245 -1
  187. package/dist/chart/model/candle.model.js +69 -1
  188. package/dist/chart/model/canvas.model.js +228 -1
  189. package/dist/chart/model/chart-base-element.js +129 -1
  190. package/dist/chart/model/compare-series-hover.js +25 -1
  191. package/dist/chart/model/data-series-view.d.ts +5 -5
  192. package/dist/chart/model/data-series-view.js +111 -1
  193. package/dist/chart/model/data-series.config.js +14 -1
  194. package/dist/chart/model/data-series.model.d.ts +4 -4
  195. package/dist/chart/model/data-series.model.js +281 -1
  196. package/dist/chart/model/date-time.formatter.js +151 -1
  197. package/dist/chart/model/hit-test-canvas.model.d.ts +1 -1
  198. package/dist/chart/model/hit-test-canvas.model.js +256 -1
  199. package/dist/chart/model/main-candle-series.model.d.ts +1 -1
  200. package/dist/chart/model/main-candle-series.model.js +29 -1
  201. package/dist/chart/model/scale.model.d.ts +3 -2
  202. package/dist/chart/model/scale.model.js +316 -1
  203. package/dist/chart/model/scaling/auto-scale.model.d.ts +2 -4
  204. package/dist/chart/model/scaling/auto-scale.model.js +91 -1
  205. package/dist/chart/model/scaling/constrait.functions.js +61 -1
  206. package/dist/chart/model/scaling/lock-ratio.model.js +17 -1
  207. package/dist/chart/model/scaling/move-chart.functions.js +22 -1
  208. package/dist/chart/model/scaling/viewport.model.d.ts +2 -2
  209. package/dist/chart/model/scaling/viewport.model.js +279 -1
  210. package/dist/chart/model/scaling/x-zooming.functions.js +35 -1
  211. package/dist/chart/model/time-zone.model.js +109 -1
  212. package/dist/chart/model/visual-candle.js +134 -1
  213. package/dist/chart/utils/__tests__/array.utils.test.js +135 -1
  214. package/dist/chart/utils/__tests__/math.utils.test.js +14 -1
  215. package/dist/chart/utils/__tests__/object.utils.test.js +11 -1
  216. package/dist/chart/utils/__tests__/priceIncrementsUtils.test.js +29 -1
  217. package/dist/chart/utils/array.utils.d.ts +1 -1
  218. package/dist/chart/utils/array.utils.js +269 -1
  219. package/dist/chart/utils/auto-period-detector.utils.js +39 -1
  220. package/dist/chart/utils/candles-generator-ts.utils.js +20 -1
  221. package/dist/chart/utils/candles-generator.utils.js +161 -1
  222. package/dist/chart/utils/candles.utils.js +42 -1
  223. package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +144 -1
  224. package/dist/chart/utils/canvas/canvas-font-measure-tool.utils.js +51 -1
  225. package/dist/chart/utils/canvas/canvas-text-functions.utils.js +156 -1
  226. package/dist/chart/utils/color.utils.js +31 -1
  227. package/dist/chart/utils/device/browser.utils.js +10 -1
  228. package/dist/chart/utils/device/device-detector.utils.js +24 -1
  229. package/dist/chart/utils/device/device-pixel-ratio.utils.js +21 -1
  230. package/dist/chart/utils/device/touchpad.utils.js +91 -1
  231. package/dist/chart/utils/dom.utils.js +15 -1
  232. package/dist/chart/utils/function.utils.js +16 -1
  233. package/dist/chart/utils/linkedList.utils.d.ts +28 -0
  234. package/dist/chart/utils/linkedList.utils.js +138 -0
  235. package/dist/chart/utils/math.utils.js +115 -1
  236. package/dist/chart/utils/merge.utils.js +56 -1
  237. package/dist/chart/utils/object.utils.js +43 -1
  238. package/dist/chart/utils/performance/animation-frame-cache.utils.js +77 -0
  239. package/dist/chart/utils/{perfomance → performance}/debounce.utils.js +7 -1
  240. package/dist/chart/utils/performance/memoize.utils.js +74 -0
  241. package/dist/chart/utils/performance/request-animation-frame-throttle.utils.js +43 -0
  242. package/dist/chart/utils/performance/throttle.utils.js +26 -0
  243. package/dist/chart/utils/price-increments.utils.d.ts +1 -0
  244. package/dist/chart/utils/price-increments.utils.js +127 -1
  245. package/dist/chart/utils/uuid.utils.js +4 -1
  246. package/dist/dxchart.min.js +9 -12
  247. package/dist/index.d.ts +3 -3
  248. package/dist/index.js +20 -1
  249. package/package.json +4 -4
  250. package/dist/chart/utils/perfomance/animation-frame-cache.utils.js +0 -6
  251. package/dist/chart/utils/perfomance/memoize.utils.js +0 -6
  252. package/dist/chart/utils/perfomance/request-animation-frame-throttle.utils.js +0 -6
  253. package/dist/chart/utils/perfomance/throttle.utils.js +0 -6
  254. /package/dist/chart/utils/{perfomance → performance}/animation-frame-cache.utils.d.ts +0 -0
  255. /package/dist/chart/utils/{perfomance → performance}/debounce.utils.d.ts +0 -0
  256. /package/dist/chart/utils/{perfomance → performance}/memoize.utils.d.ts +0 -0
  257. /package/dist/chart/utils/{perfomance → performance}/request-animation-frame-throttle.utils.d.ts +0 -0
  258. /package/dist/chart/utils/{perfomance → performance}/throttle.utils.d.ts +0 -0
@@ -3,4 +3,49 @@
3
3
  * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import{HighlightsModel as r}from"./highlights.model";import{HighlightsDrawer as l}from"./highlights.drawer";import{ChartBaseElement as o}from"../../model/chart-base-element";const d="HIGHLIGHTS_PLUGIN";export class HighlightsComponent extends o{constructor(h,i,t,s,e,g){super(),this.eventBus=h,this.config=i,this.highlightsModel=new r(t),this.addChildEntity(this.highlightsModel),this.highLightsDrawer=new l(this.highlightsModel,t,s,e,i),g.addDrawer(this.highLightsDrawer,d)}getHighlights(){return this.highlightsModel.getHighlights()}setHighlights(h){this.highlightsModel.setHighlights(h)}setHighlightsVisible(h=!0){this.config.components.highlights.visible=h,this.eventBus.fireDraw(this.highLightsDrawer.getCanvasIds())}observeHighlightsUpdated(){return this.highlightsModel.observeHighlightsUpdated()}}
6
+ import { HighlightsModel } from './highlights.model';
7
+ import { HighlightsDrawer } from './highlights.drawer';
8
+ import { ChartBaseElement } from '../../model/chart-base-element';
9
+ const HIGHLIGHTS_DRAWER_TYPE = 'HIGHLIGHTS_PLUGIN';
10
+ export class HighlightsComponent extends ChartBaseElement {
11
+ constructor(eventBus, config, chartModel, canvasModel, canvasBoundsContainer, drawingManager) {
12
+ super();
13
+ this.eventBus = eventBus;
14
+ this.config = config;
15
+ this.highlightsModel = new HighlightsModel(chartModel);
16
+ this.addChildEntity(this.highlightsModel);
17
+ this.highLightsDrawer = new HighlightsDrawer(this.highlightsModel, chartModel, canvasModel, canvasBoundsContainer, config);
18
+ drawingManager.addDrawer(this.highLightsDrawer, HIGHLIGHTS_DRAWER_TYPE);
19
+ }
20
+ /**
21
+ * Returns the highlights from the highlightsModel
22
+ * @returns {Array} An array of highlights
23
+ */
24
+ getHighlights() {
25
+ return this.highlightsModel.getHighlights();
26
+ }
27
+ /**
28
+ * Sets the highlights of the highlights model.
29
+ * @param {Highlight[]} highlights - An array of Highlight objects to be set as the highlights of the model.
30
+ * @returns {void}
31
+ */
32
+ setHighlights(highlights) {
33
+ this.highlightsModel.setHighlights(highlights);
34
+ }
35
+ /**
36
+ * Sets the visibility of the highlights component.
37
+ * @param {boolean} visible - A boolean value indicating whether the highlights should be visible or not. Default value is true.
38
+ * @returns {void}
39
+ */
40
+ setHighlightsVisible(visible = true) {
41
+ this.config.components.highlights.visible = visible;
42
+ this.eventBus.fireDraw(this.highLightsDrawer.getCanvasIds());
43
+ }
44
+ /**
45
+ * Returns an observable that emits when the highlights are updated.
46
+ * @returns {Observable} An observable that emits when the highlights are updated.
47
+ */
48
+ observeHighlightsUpdated() {
49
+ return this.highlightsModel.observeHighlightsUpdated();
50
+ }
51
+ }
@@ -3,4 +3,157 @@
3
3
  * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import{calculateTextWidth as A}from"../../utils/canvas/canvas-font-measure-tool.utils";import{HIGHLIGHTS_TYPES as F}from"./highlights.model";import{CanvasElement as x}from"../../canvas/canvas-bounds-container";import{unitToPixels as X}from"../../model/scaling/viewport.model";import{clipToBounds as G}from"../../drawers/data-series.drawer";const n=[20,10];export class HighlightsDrawer{constructor(e,o,s,l,i){this.highlightsModel=e,this.chartModel=o,this.canvasModel=s,this.canvasBoundsContainer=l,this.config=i}draw(){var e,o,s,l;if(this.config.components.highlights.visible){const i=this.chartModel.getCandles(),t=this.canvasModel.ctx,d=this.highlightsModel.getVisualHighlights();if(this.highlightsModel.getHighlights().length&&i.length!==0&&this.chartModel.scaleModel.isScaleReady()){const r=this.canvasBoundsContainer.getBounds(x.ALL_PANES);t.save(),G(t,r);const w=(e=this.config.components.highlights.border.width)!==null&&e!==void 0?e:1,E=(o=this.config.components.highlights.border.dash)!==null&&o!==void 0?o:[0,0],H=(s=this.config.components.highlights.fontSize)!==null&&s!==void 0?s:11,L=(l=this.config.components.highlights.fontFamily)!==null&&l!==void 0?l:"monospace",p=`${H}px ${L}, monospace`;t.font=p,t.lineWidth=w,t.setLineDash(E),F.forEach(y=>{var f,g;const S=d[y];if(S){const a=this.config.colors.highlights[y],k=(f=a==null?void 0:a.border)!==null&&f!==void 0?f:"#ffffff",B=(g=a==null?void 0:a.background)!==null&&g!==void 0?g:"#ffffff";t.save(),t.beginPath(),t.fillStyle=B,t.strokeStyle=k,S.forEach(h=>{var v,m,b;const P=this.chartModel.candleFromTimestamp(h.from),D=X(P.width,this.chartModel.scaleModel.zoomX),c=P.xStart(this.chartModel.scaleModel),_=this.chartModel.candleFromTimestamp(h.to),C=X(_.width,this.chartModel.scaleModel.zoomX),u=_.xStart(this.chartModel.scaleModel)+C;if(h.border&&this.drawBorders(h.border,t,c+D,u-C,r),t.fillRect(c,r.y,u-c,r.y+r.height),h.label){const T=(v=h.label.text)!==null&&v!==void 0?v:"",M=this.config.colors.highlights[h.type];t.save(),t.fillStyle=(m=M==null?void 0:M.label)!==null&&m!==void 0?m:"#ffffff";const I=A(T,t,p),[W,z]=this.resolveHighlightLabelPosition((b=h.label.placement)!==null&&b!==void 0?b:"left-left",r,[c,u],I);t.fillText(T,W,z),t.restore()}}),t.closePath(),t.restore()}}),t.restore()}}}resolveHighlightLabelPosition(e,o,s,l){const[i,t]=s;switch(e){case"right-left":return[t-n[1]-l,o.y+n[0]];case"left-left":return[i-n[1]-l,o.y+n[0]];case"right-right":return[t+n[1],o.y+n[0]];case"left-right":default:return[i+n[1],o.y+n[0]]}}drawBorders(e,o,s,l,i){const t=e.left,d=e.right;t&&(o.beginPath(),o.moveTo(s,i.y),o.lineTo(s,i.y+i.height),o.stroke(),o.closePath()),d&&(o.beginPath(),o.moveTo(l,i.y),o.lineTo(l,i.y+i.height),o.stroke(),o.closePath())}getCanvasIds(){return[this.canvasModel.canvasId]}}
6
+ import { calculateTextWidth } from '../../utils/canvas/canvas-font-measure-tool.utils';
7
+ import { HIGHLIGHTS_TYPES } from './highlights.model';
8
+ import { CanvasElement } from '../../canvas/canvas-bounds-container';
9
+ import { unitToPixels } from '../../model/scaling/viewport.model';
10
+ import { clipToBounds } from '../../drawers/data-series.drawer';
11
+ const LABEL_PADDINGS = [20, 10];
12
+ export class HighlightsDrawer {
13
+ constructor(highlightsModel, chartModel, canvasModel, canvasBoundsContainer, config) {
14
+ this.highlightsModel = highlightsModel;
15
+ this.chartModel = chartModel;
16
+ this.canvasModel = canvasModel;
17
+ this.canvasBoundsContainer = canvasBoundsContainer;
18
+ this.config = config;
19
+ }
20
+ /**
21
+ * Draws highlights on the chart canvas if they are visible.
22
+ * @function
23
+ * @name draw
24
+ * @memberof ChartComponent.prototype
25
+ *
26
+ * @returns {void}
27
+ *
28
+ * @example
29
+ * chartComponent.draw();
30
+ */
31
+ draw() {
32
+ var _a, _b, _c, _d;
33
+ if (this.config.components.highlights.visible) {
34
+ const candles = this.chartModel.getCandles();
35
+ const ctx = this.canvasModel.ctx;
36
+ const highlights = this.highlightsModel.getVisualHighlights();
37
+ const highlightsExist = this.highlightsModel.getHighlights().length;
38
+ if (highlightsExist && candles.length !== 0 && this.chartModel.scale.isScaleReady()) {
39
+ const chartBounds = this.canvasBoundsContainer.getBounds(CanvasElement.ALL_PANES);
40
+ ctx.save();
41
+ //clip rect to throw away everything that doesn't fit chart bounds
42
+ clipToBounds(ctx, chartBounds);
43
+ const borderWidth = (_a = this.config.components.highlights.border.width) !== null && _a !== void 0 ? _a : 1;
44
+ const borderDash = (_b = this.config.components.highlights.border.dash) !== null && _b !== void 0 ? _b : [0, 0];
45
+ const fontSize = (_c = this.config.components.highlights.fontSize) !== null && _c !== void 0 ? _c : 11;
46
+ const fontFamily = (_d = this.config.components.highlights.fontFamily) !== null && _d !== void 0 ? _d : 'monospace';
47
+ const font = `${fontSize}px ${fontFamily}, monospace`;
48
+ ctx.font = font;
49
+ ctx.lineWidth = borderWidth;
50
+ ctx.setLineDash(borderDash);
51
+ HIGHLIGHTS_TYPES.forEach(highlightType => {
52
+ var _a, _b;
53
+ const items = highlights[highlightType];
54
+ if (items) {
55
+ const itemColors = this.config.colors.highlights[highlightType];
56
+ const strokeStyle = (_a = itemColors === null || itemColors === void 0 ? void 0 : itemColors.border) !== null && _a !== void 0 ? _a : '#ffffff';
57
+ const fillStyle = (_b = itemColors === null || itemColors === void 0 ? void 0 : itemColors.background) !== null && _b !== void 0 ? _b : '#ffffff';
58
+ ctx.save();
59
+ // start line path to draw highlights' borders
60
+ // it is done once for all highlights because it is more perfomant
61
+ ctx.beginPath();
62
+ ctx.fillStyle = fillStyle;
63
+ ctx.strokeStyle = strokeStyle;
64
+ items.forEach(item => {
65
+ var _a, _b, _c;
66
+ const fromXCandle = this.chartModel.candleFromTimestamp(item.from);
67
+ const fromXCandleWidth = unitToPixels(fromXCandle.width, this.chartModel.scale.zoomX);
68
+ const fromX = fromXCandle.xStart(this.chartModel.scale);
69
+ const toXCandle = this.chartModel.candleFromTimestamp(item.to);
70
+ const toXCandleWidth = unitToPixels(toXCandle.width, this.chartModel.scale.zoomX);
71
+ const toX = toXCandle.xStart(this.chartModel.scale) + toXCandleWidth;
72
+ // draw highlight' borders
73
+ if (item.border) {
74
+ this.drawBorders(item.border, ctx, fromX + fromXCandleWidth, toX - toXCandleWidth, chartBounds);
75
+ }
76
+ // draw highlight' background
77
+ ctx.fillRect(fromX, chartBounds.y, toX - fromX, chartBounds.y + chartBounds.height);
78
+ // draw highlight' label
79
+ if (item.label) {
80
+ const label = (_a = item.label.text) !== null && _a !== void 0 ? _a : '';
81
+ const itemColors = this.config.colors.highlights[item.type];
82
+ ctx.save();
83
+ ctx.fillStyle = (_b = itemColors === null || itemColors === void 0 ? void 0 : itemColors.label) !== null && _b !== void 0 ? _b : '#ffffff';
84
+ const labelWidth = calculateTextWidth(label, ctx, font);
85
+ const [labelX, labelY] = this.resolveHighlightLabelPosition((_c = item.label.placement) !== null && _c !== void 0 ? _c : 'left-left', chartBounds, [fromX, toX], labelWidth);
86
+ ctx.fillText(label, labelX, labelY);
87
+ ctx.restore();
88
+ }
89
+ });
90
+ ctx.closePath();
91
+ ctx.restore();
92
+ }
93
+ });
94
+ ctx.restore();
95
+ }
96
+ }
97
+ }
98
+ /**
99
+ * Calculates the position of the highlight label based on the given parameters.
100
+ * @param {HighlightTextPlacement} placement - The placement of the highlight text.
101
+ * @param {Bounds} bounds - The bounds of the highlight.
102
+ * @param {[number, number]} highlightFromTo - The start and end position of the highlight.
103
+ * @param {number} labelWidth - The width of the label.
104
+ * @returns {[number, number]} - The x and y position of the highlight label.
105
+ */
106
+ resolveHighlightLabelPosition(placement, bounds, highlightFromTo, labelWidth) {
107
+ const [fromX, toX] = highlightFromTo;
108
+ switch (placement) {
109
+ case 'right-left': {
110
+ return [toX - LABEL_PADDINGS[1] - labelWidth, bounds.y + LABEL_PADDINGS[0]];
111
+ }
112
+ case 'left-left': {
113
+ return [fromX - LABEL_PADDINGS[1] - labelWidth, bounds.y + LABEL_PADDINGS[0]];
114
+ }
115
+ case 'right-right': {
116
+ return [toX + LABEL_PADDINGS[1], bounds.y + LABEL_PADDINGS[0]];
117
+ }
118
+ case 'left-right':
119
+ default: {
120
+ return [fromX + LABEL_PADDINGS[1], bounds.y + LABEL_PADDINGS[0]];
121
+ }
122
+ }
123
+ }
124
+ /**
125
+ * Draws borders on a canvas context for a given chart.
126
+ * @param {HighlightBorder} border - The border to draw.
127
+ * @param {CanvasRenderingContext2D} ctx - The canvas context to draw on.
128
+ * @param {number} fromX - The starting x-coordinate of the border.
129
+ * @param {number} toX - The ending x-coordinate of the border.
130
+ * @param {Bounds} chartBounds - The bounds of the chart to draw the border on.
131
+ * @returns {void}
132
+ */
133
+ drawBorders(border, ctx, fromX, toX, chartBounds) {
134
+ const leftBorder = border.left;
135
+ const rightBorder = border.right;
136
+ if (leftBorder) {
137
+ ctx.beginPath();
138
+ ctx.moveTo(fromX, chartBounds.y);
139
+ ctx.lineTo(fromX, chartBounds.y + chartBounds.height);
140
+ ctx.stroke();
141
+ ctx.closePath();
142
+ }
143
+ if (rightBorder) {
144
+ ctx.beginPath();
145
+ ctx.moveTo(toX, chartBounds.y);
146
+ ctx.lineTo(toX, chartBounds.y + chartBounds.height);
147
+ ctx.stroke();
148
+ ctx.closePath();
149
+ }
150
+ }
151
+ /**
152
+ * Returns an array of canvas IDs.
153
+ *
154
+ * @returns {Array<string>} An array containing the canvas ID.
155
+ */
156
+ getCanvasIds() {
157
+ return [this.canvasModel.canvasId];
158
+ }
159
+ }
@@ -3,4 +3,78 @@
3
3
  * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import{Subject as l}from"rxjs";import{ChartBaseElement as a}from"../../model/chart-base-element";import{getElementsInRange as r}from"../../utils/array.utils";export const HIGHLIGHTS_TYPES=["AFTER_MARKET","PRE_MARKET","NO_TRADING","REGULAR"];const o=24*60*60*1e3;export class HighlightsModel extends a{constructor(t){super(),this.chartModel=t,this.highlights=[],this.visualHighlights={},this.highlightsUpdatedSubject=new l}activate(){this.addRxSubscription(this.chartModel.scaleModel.xChanged.subscribe(()=>this.highlights.length&&this.recalculateVisualHighlights()))}getHighlights(){return this.highlights}getVisualHighlights(){return this.visualHighlights}recalculateVisualHighlights(){this.visualHighlights={};const t=this.chartModel.getFirstTimestamp(),h=this.chartModel.getLastTimestamp()+o;r(this.highlights,t,h,c).forEach(i=>{var s;this.visualHighlights[i.type]||(this.visualHighlights[i.type]=[]),(s=this.visualHighlights[i.type])===null||s===void 0||s.push(i)})}setHighlights(t){this.highlights=t,this.highlights.sort((h,e)=>h.to-e.to),this.highlightsUpdatedSubject.next(this.highlights),this.highlights.length?this.recalculateVisualHighlights():this.visualHighlights={}}observeHighlightsUpdated(){return this.highlightsUpdatedSubject.asObservable()}}const c=g=>g.to;
6
+ import { Subject } from 'rxjs';
7
+ import { ChartBaseElement } from '../../model/chart-base-element';
8
+ import { getElementsInRange } from '../../utils/array.utils';
9
+ export const HIGHLIGHTS_TYPES = ['AFTER_MARKET', 'PRE_MARKET', 'NO_TRADING', 'REGULAR'];
10
+ const DAY_MS = 24 * 60 * 60 * 1000;
11
+ export class HighlightsModel extends ChartBaseElement {
12
+ constructor(chartModel) {
13
+ super();
14
+ this.chartModel = chartModel;
15
+ this.highlights = [];
16
+ this.visualHighlights = {};
17
+ this.highlightsUpdatedSubject = new Subject();
18
+ }
19
+ /**
20
+ * Activates the chart by subscribing to the xChanged event of the scaleModel.
21
+ * If there are highlights, it recalculates the visual highlights.
22
+ */
23
+ activate() {
24
+ this.addRxSubscription(this.chartModel.scale.xChanged.subscribe(() => this.highlights.length && this.recalculateVisualHighlights()));
25
+ }
26
+ /**
27
+ * Returns an array of Highlight objects.
28
+ * @returns {Highlight[]} - An array of Highlight objects.
29
+ */
30
+ getHighlights() {
31
+ return this.highlights;
32
+ }
33
+ /**
34
+ * Returns the visual highlights object.
35
+ *
36
+ * @returns {VisualHighlights} The visual highlights object.
37
+ */
38
+ getVisualHighlights() {
39
+ return this.visualHighlights;
40
+ }
41
+ /**
42
+ * Recalculates the visual highlights based on the current chart model and highlights.
43
+ * @private
44
+ * @returns {void}
45
+ */
46
+ recalculateVisualHighlights() {
47
+ this.visualHighlights = {};
48
+ const firstTimestamp = this.chartModel.getFirstTimestamp();
49
+ const lastTimestamp = this.chartModel.getLastTimestamp() + DAY_MS;
50
+ const highlightsInRange = getElementsInRange(this.highlights, firstTimestamp, lastTimestamp, highlightTransformFunc);
51
+ highlightsInRange.forEach(h => {
52
+ var _a;
53
+ if (!this.visualHighlights[h.type]) {
54
+ this.visualHighlights[h.type] = [];
55
+ }
56
+ (_a = this.visualHighlights[h.type]) === null || _a === void 0 ? void 0 : _a.push(h);
57
+ });
58
+ }
59
+ /**
60
+ * Sets the highlights of the component and updates the visual highlights accordingly.
61
+ * @param {Highlight[]} highlights - An array of Highlight objects to be set as the new highlights.
62
+ * @returns {void}
63
+ */
64
+ setHighlights(highlights) {
65
+ this.highlights = highlights;
66
+ this.highlights.sort((a, b) => a.to - b.to);
67
+ this.highlightsUpdatedSubject.next(this.highlights);
68
+ this.highlights.length ? this.recalculateVisualHighlights() : (this.visualHighlights = {});
69
+ }
70
+ /**
71
+ * Returns an Observable that emits an array of Highlight objects whenever the highlightsUpdatedSubject emits a new value.
72
+ * @returns {Observable<Highlight[]>} An Observable that emits an array of Highlight objects.
73
+ */
74
+ observeHighlightsUpdated() {
75
+ return this.highlightsUpdatedSubject.asObservable();
76
+ }
77
+ }
78
+ const highlightTransformFunc = (item) => {
79
+ return item.to;
80
+ };
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { Observable, Subject } from 'rxjs';
7
7
  import { Unit } from '../../model/scaling/viewport.model';
8
- import { AnimationFrameCache } from '../../utils/perfomance/animation-frame-cache.utils';
8
+ import { AnimationFrameCache } from '../../utils/performance/animation-frame-cache.utils';
9
9
  export type PriceAxisType = 'regular' | 'percent' | 'logarithmic';
10
10
  export interface LabelsGenerator {
11
11
  readonly observeLabelsChanged: () => Observable<NumericAxisLabel[]>;
@@ -3,4 +3,202 @@
3
3
  * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import{Subject as h}from"rxjs";import{logValueToUnit as u,percentToUnit as d,calcLogValue as b}from"../../model/scaling/viewport.model";import{AnimationFrameCache as g}from"../../utils/perfomance/animation-frame-cache.utils";import{identity as m}from"../../utils/function.utils";import{MathUtils as l}from"../../utils/math.utils";import{PriceIncrementsUtils as L}from"../../utils/price-increments.utils";const x=0,p=.01;export class NumericAxisLabelsGenerator{constructor(e,s,a,t,i=!1,r,n,c=m,o=23){this.increment=e,this.startEndProvider=s,this.lengthProvider=a,this.valueFormatter=t,this.withZero=i,this.axisTypeProvider=r,this.baseLineProvider=n,this.labelFilter=c,this.singleLabelHeightPixels=o,this.gridDistanceMultipliers=[2,4,5,10],this.lastSingleLabelHeightValue=0,this.distanceBetweenLabelsChangeSubject=new h,this.newGeneratedLabelsSubject=new h,this.lastStart=0,this.lastEnd=0,this.labelsCache=new g(()=>this.labelFilter(this.doGenerateLabels()))}generateRegularLabels(e,s,a){const t=[];this.withZero&&t.push({value:0,text:"0"});let i=l.roundToNearest(e,a);for(;i<s;){const r=l.roundToNearest(i,a),n=this.valueFormatter(r);t.push({value:r,text:n}),i=l.roundDecimal(i+a)}return t}generatePercentLabels(e,s,a){const t=[],i=this.baseLineProvider();let r=l.roundToNearest(e,a);for(;r<s;){const n=l.roundToNearest(r,a),c=d(n,i),o=this.valueFormatter(c);t.push({value:n,text:o}),r=l.roundDecimal(r+a)}return t}generateLogarithmLabels(e,s,a){const t=[];let i=l.roundToNearest(e,a);for(;i<s;){const r=u(i),n=this.valueFormatter(r);t.push({value:i,text:n}),i=l.roundDecimal(i+a)}return t}doGenerateLabels(){var e;const s=this.lengthProvider();if(s<=0)return[];const[a,t]=this.calculateMinMax(),i=this.getAxisStep(a,t,s);this.lastSingleLabelHeightValue||(this.lastSingleLabelHeightValue=i);let r;const n=this.axisTypeProvider();if(n==="logarithmic"?r=this.generateLogarithmLabels(a,t,i):n==="percent"?r=this.generatePercentLabels(a,t,i):r=this.generateRegularLabels(a,t,i),this.lastSingleLabelHeightValue!==i&&this.labelsCache.cache){const c=(e=this.labelsCache.getLastCachedValue())!==null&&e!==void 0?e:[];this.distanceBetweenLabelsChangeSubject.next([c,r]),this.lastSingleLabelHeightValue=i}return this.newGeneratedLabelsSubject.next(r),r}calculateMinMax(){const[e,s]=this.startEndProvider(),a=this.lengthProvider(),t=NumericAxisLabelsGenerator.getLabelBounds(e,s,a);return[t[0],t[1]]}getAxisStep(e,s,a){const t=s-e,i=a/this.singleLabelHeightPixels,r=this.calculateIncrement(t),n=t/i;return this.calculateAxisStep(n,r)}observeDistanceBetweenLabelsChanged(){return this.distanceBetweenLabelsChangeSubject.asObservable()}observeLabelsChanged(){return this.newGeneratedLabelsSubject.asObservable()}calculateIncrement(e){if(this.increment)return this.increment;if(!isNaN(e)){const s=L.autoDetectIncrementOfValueRange(e);return this.adjustIncrementOnAxisType(s)}return this.adjustIncrementOnAxisType(p)}adjustIncrementOnAxisType(e){switch(this.axisTypeProvider()){case"percent":return e;case"logarithmic":const[s]=this.calculateMinMax(),t=u(s)+e;return b(t)-s;case"regular":return e}}generateNumericLabels(){const[e,s]=this.startEndProvider();return(e!==this.lastStart||s!==this.lastEnd)&&this.labelsCache.invalidate(),this.lastStart=e,this.lastEnd=s,this.labelsCache.calculateOrGet()}static getLabelBounds(e,s,a){const t=Math.abs((s-e)*(x/a));return[e-t,s+t]}calculateAxisStep(e,s){if(s===0)return console.error("NumericAxisLabelsGenerator failed at calculateAxisStep: increment = 0"),0;let a=s,t=s,i=0;for(;a<e&&a>0;)i>=this.gridDistanceMultipliers.length&&(i=0,t*=10),a=t*this.gridDistanceMultipliers[i++];return a}}
6
+ import { Subject } from 'rxjs';
7
+ import { logValueToUnit, percentToUnit, calcLogValue } from '../../model/scaling/viewport.model';
8
+ import { AnimationFrameCache } from '../../utils/performance/animation-frame-cache.utils';
9
+ import { identity } from '../../utils/function.utils';
10
+ import { MathUtils } from '../../utils/math.utils';
11
+ import { PriceIncrementsUtils } from '../../utils/price-increments.utils';
12
+ const PIXEL_OFFSET = 0;
13
+ const DEFAULT_REGULAR_INCREMENT = 0.01;
14
+ /**
15
+ * Generator of axes labels.
16
+ */
17
+ export class NumericAxisLabelsGenerator {
18
+ constructor(increment, startEndProvider, lengthProvider, valueFormatter, withZero = false, axisTypeProvider, baseLineProvider, labelFilter = identity, singleLabelHeightPixels = 23) {
19
+ this.increment = increment;
20
+ this.startEndProvider = startEndProvider;
21
+ this.lengthProvider = lengthProvider;
22
+ this.valueFormatter = valueFormatter;
23
+ this.withZero = withZero;
24
+ this.axisTypeProvider = axisTypeProvider;
25
+ this.baseLineProvider = baseLineProvider;
26
+ this.labelFilter = labelFilter;
27
+ this.singleLabelHeightPixels = singleLabelHeightPixels;
28
+ /**
29
+ * Multipliers which are using for price increments to
30
+ * calculate horizontal grid and price lines step.
31
+ */
32
+ this.gridDistanceMultipliers = [2, 4, 5, 10];
33
+ this.lastSingleLabelHeightValue = 0;
34
+ this.distanceBetweenLabelsChangeSubject = new Subject();
35
+ this.newGeneratedLabelsSubject = new Subject();
36
+ // optimization to not recalculate labels on same viewport
37
+ // TODO rework, generate 1-2 screens outside viewport as well
38
+ this.lastStart = 0;
39
+ this.lastEnd = 0;
40
+ this.labelsCache = new AnimationFrameCache(() => this.labelFilter(this.doGenerateLabels()));
41
+ }
42
+ generateRegularLabels(min, max, singleLabelHeightValue) {
43
+ const newLabels = [];
44
+ this.withZero && newLabels.push({ value: 0, text: '0' });
45
+ let value = MathUtils.roundToNearest(min, singleLabelHeightValue);
46
+ while (value < max) {
47
+ // Adjust value to increment
48
+ const adjustedValue = MathUtils.roundToNearest(value, singleLabelHeightValue);
49
+ const labelText = this.valueFormatter(adjustedValue);
50
+ newLabels.push({
51
+ value: adjustedValue,
52
+ text: labelText,
53
+ });
54
+ value = MathUtils.roundDecimal(value + singleLabelHeightValue);
55
+ }
56
+ return newLabels;
57
+ }
58
+ generatePercentLabels(min, max, singleLabelHeightValue) {
59
+ const newLabels = [];
60
+ const baseLine = this.baseLineProvider();
61
+ let value = MathUtils.roundToNearest(min, singleLabelHeightValue);
62
+ while (value < max) {
63
+ // Adjust value to increment
64
+ const adjustedValue = MathUtils.roundToNearest(value, singleLabelHeightValue);
65
+ const valueUnit = percentToUnit(adjustedValue, baseLine);
66
+ const labelText = this.valueFormatter(valueUnit);
67
+ newLabels.push({
68
+ value: adjustedValue,
69
+ text: labelText,
70
+ });
71
+ value = MathUtils.roundDecimal(value + singleLabelHeightValue);
72
+ }
73
+ return newLabels;
74
+ }
75
+ generateLogarithmLabels(min, max, singleLabelHeightValue) {
76
+ const newLabels = [];
77
+ let value = MathUtils.roundToNearest(min, singleLabelHeightValue);
78
+ while (value < max) {
79
+ const realValue = logValueToUnit(value);
80
+ const labelText = this.valueFormatter(realValue);
81
+ newLabels.push({
82
+ value,
83
+ text: labelText,
84
+ });
85
+ value = MathUtils.roundDecimal(value + singleLabelHeightValue);
86
+ }
87
+ return newLabels;
88
+ }
89
+ doGenerateLabels() {
90
+ var _a;
91
+ const lengthPixels = this.lengthProvider();
92
+ if (lengthPixels <= 0) {
93
+ return [];
94
+ }
95
+ const [min, max] = this.calculateMinMax();
96
+ const axisStep = this.getAxisStep(min, max, lengthPixels);
97
+ if (!this.lastSingleLabelHeightValue) {
98
+ this.lastSingleLabelHeightValue = axisStep;
99
+ }
100
+ let newLabels;
101
+ const axisType = this.axisTypeProvider();
102
+ if (axisType === 'logarithmic') {
103
+ newLabels = this.generateLogarithmLabels(min, max, axisStep);
104
+ }
105
+ else if (axisType === 'percent') {
106
+ newLabels = this.generatePercentLabels(min, max, axisStep);
107
+ }
108
+ else {
109
+ newLabels = this.generateRegularLabels(min, max, axisStep);
110
+ }
111
+ if (this.lastSingleLabelHeightValue !== axisStep && this.labelsCache.cache) {
112
+ const currentLabels = (_a = this.labelsCache.getLastCachedValue()) !== null && _a !== void 0 ? _a : [];
113
+ this.distanceBetweenLabelsChangeSubject.next([currentLabels, newLabels]);
114
+ this.lastSingleLabelHeightValue = axisStep;
115
+ }
116
+ this.newGeneratedLabelsSubject.next(newLabels);
117
+ return newLabels;
118
+ }
119
+ calculateMinMax() {
120
+ const [min, max] = this.startEndProvider();
121
+ const lengthPixels = this.lengthProvider();
122
+ const labelBounds = NumericAxisLabelsGenerator.getLabelBounds(min, max, lengthPixels);
123
+ return [labelBounds[0], labelBounds[1]];
124
+ }
125
+ getAxisStep(min, max, lengthPixels) {
126
+ const valueRange = max - min;
127
+ const labelsCount = lengthPixels / this.singleLabelHeightPixels;
128
+ const increment = this.calculateIncrement(valueRange);
129
+ const singleLabelHeightValue = valueRange / labelsCount;
130
+ return this.calculateAxisStep(singleLabelHeightValue, increment);
131
+ }
132
+ observeDistanceBetweenLabelsChanged() {
133
+ return this.distanceBetweenLabelsChangeSubject.asObservable();
134
+ }
135
+ observeLabelsChanged() {
136
+ return this.newGeneratedLabelsSubject.asObservable();
137
+ }
138
+ calculateIncrement(valueLength) {
139
+ // provided increment
140
+ if (this.increment) {
141
+ return this.increment;
142
+ }
143
+ // auto-generated increment
144
+ if (!isNaN(valueLength)) {
145
+ const calculatedIncrement = PriceIncrementsUtils.autoDetectIncrementOfValueRange(valueLength);
146
+ return this.adjustIncrementOnAxisType(calculatedIncrement);
147
+ }
148
+ return this.adjustIncrementOnAxisType(DEFAULT_REGULAR_INCREMENT);
149
+ }
150
+ adjustIncrementOnAxisType(increment) {
151
+ switch (this.axisTypeProvider()) {
152
+ case 'percent':
153
+ return increment;
154
+ case 'logarithmic':
155
+ const [logMin] = this.calculateMinMax();
156
+ const regularMin = logValueToUnit(logMin);
157
+ const regularIncrementedValue = regularMin + increment;
158
+ const incrementedLogValue = calcLogValue(regularIncrementedValue);
159
+ return incrementedLogValue - logMin;
160
+ case 'regular':
161
+ return increment;
162
+ }
163
+ }
164
+ // TODO rework, generator should act as model and update itself on scaleChanged
165
+ // TODO this should be called 1-2 times and very rarely, there should be 1-3 viewport of labels
166
+ generateNumericLabels() {
167
+ const [start, end] = this.startEndProvider();
168
+ if (start !== this.lastStart || end !== this.lastEnd) {
169
+ this.labelsCache.invalidate();
170
+ }
171
+ this.lastStart = start;
172
+ this.lastEnd = end;
173
+ return this.labelsCache.calculateOrGet();
174
+ }
175
+ static getLabelBounds(start, end, lengthPixels) {
176
+ const offset = Math.abs((end - start) * (PIXEL_OFFSET / lengthPixels));
177
+ return [start - offset, end + offset];
178
+ }
179
+ /**
180
+ * Calculates the distance between two axis labels as:
181
+ * - Take increment (0.01 for price or 1 for natural number);
182
+ * - Take step which was calculated as (chart height / max lines count provided by config (or default 10));
183
+ * - Multiplying increment with gridDistanceMultipliers until it will greater then step
184
+ * @param step
185
+ * @param increment
186
+ */
187
+ calculateAxisStep(step, increment) {
188
+ if (increment === 0) {
189
+ console.error('NumericAxisLabelsGenerator failed at calculateAxisStep: increment = 0');
190
+ return 0;
191
+ }
192
+ let distance = increment;
193
+ let currentNumberOrder = increment;
194
+ let multipliersPointer = 0;
195
+ while (distance < step && distance > 0) {
196
+ if (multipliersPointer >= this.gridDistanceMultipliers.length) {
197
+ multipliersPointer = 0;
198
+ currentNumberOrder *= 10;
199
+ }
200
+ distance = currentNumberOrder * this.gridDistanceMultipliers[multipliersPointer++];
201
+ }
202
+ return distance;
203
+ }
204
+ }
@@ -13,14 +13,14 @@ import { ChartPanComponent } from '../pan/chart-pan.component';
13
13
  export declare class NavigationMapMoveHandler extends ChartBaseElement {
14
14
  private bus;
15
15
  private chartModel;
16
- private scaleModel;
16
+ private scale;
17
17
  private canvasInputListeners;
18
18
  private canvasBoundsContainer;
19
19
  private chartPanComponent;
20
20
  private leftKnotDragStartXRelative;
21
21
  private rightKnotDragStartXRelative;
22
22
  private lastMousePosition;
23
- constructor(bus: EventBus, chartModel: ChartModel, scaleModel: ScaleModel, canvasInputListeners: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, chartPanComponent: ChartPanComponent);
23
+ constructor(bus: EventBus, chartModel: ChartModel, scale: ScaleModel, canvasInputListeners: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, chartPanComponent: ChartPanComponent);
24
24
  /**
25
25
  * Method that activates the navigation map buttons and subscribes to their click and touch events.
26
26
  * It also subscribes to the xChanged event of the scaleModel and updates the canvasBoundsContainer accordingly.
@@ -3,4 +3,111 @@
3
3
  * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import{CanvasElement as s}from"../../canvas/canvas-bounds-container";import{ChartBaseElement as B}from"../../model/chart-base-element";import{DragNDropXComponent as c}from"../dran-n-drop_helper/drag-n-drop-x.component";const d=4;export class NavigationMapMoveHandler extends B{constructor(o,r,n,l,u,g){super(),this.bus=o,this.chartModel=r,this.scaleModel=n,this.canvasInputListeners=l,this.canvasBoundsContainer=u,this.chartPanComponent=g,this.leftKnotDragStartXRelative=0,this.rightKnotDragStartXRelative=0,this.lastMousePosition=0,this.leftKnotDragStart=a=>{const t=this.canvasBoundsContainer.getBounds(s.N_MAP_CHART);this.leftKnotDragStartXRelative=a.x-t.x-d},this.leftKnotDragTick=a=>{const{delta:t}=a,i=this.canvasBoundsContainer.getBounds(s.N_MAP_CHART).width,e=(this.leftKnotDragStartXRelative+t)/i;this.canvasBoundsContainer.leftRatio=e,this.scaleModel.setXScale(Math.round(this.chartModel.mainCandleSeries.dataPoints.length*this.canvasBoundsContainer.leftRatio),this.scaleModel.xEnd)},this.rightKnotDragStart=a=>{const t=this.canvasBoundsContainer.getBounds(s.N_MAP_CHART);this.rightKnotDragStartXRelative=a.x-t.x+d},this.rightKnotDragTick=a=>{const{delta:t}=a,i=this.canvasBoundsContainer.getBounds(s.N_MAP_CHART).width,e=(this.rightKnotDragStartXRelative+t)/i;this.canvasBoundsContainer.rightRatio=e,this.scaleModel.setXScale(this.scaleModel.xStart,Math.round(this.chartModel.mainCandleSeries.dataPoints.length*this.canvasBoundsContainer.rightRatio))},this.sliderDragStart=()=>{this.lastMousePosition=0},this.sliderDragTick=a=>{const{delta:t}=a,h=this.canvasBoundsContainer.getBounds(s.N_MAP_CHART),i=this.chartModel.mainCandleSeries.meanCandleWidth/(h.width/this.chartModel.mainCandleSeries.dataPoints.length),e=(this.lastMousePosition-t)*i;this.scaleModel.moveXStart(this.scaleModel.xStart-e),this.lastMousePosition=t};const C=this.canvasBoundsContainer.getBoundsHitTest(s.N_MAP_KNOT_L),v=this.canvasBoundsContainer.getBoundsHitTest(s.N_MAP_KNOT_R),M=new c(C,{onDragStart:this.leftKnotDragStart,onDragTick:this.leftKnotDragTick},this.canvasInputListeners,this.chartPanComponent),S=new c(v,{onDragStart:this.rightKnotDragStart,onDragTick:this.rightKnotDragTick},this.canvasInputListeners,this.chartPanComponent);this.addChildEntity(M),this.addChildEntity(S);const p=this.canvasBoundsContainer.getBoundsHitTest(s.N_MAP_SLIDER_WINDOW),D=new c(p,{onDragStart:this.sliderDragStart,onDragTick:this.sliderDragTick},this.canvasInputListeners,this.chartPanComponent);this.addChildEntity(D)}doActivate(){super.doActivate();const o=this.canvasBoundsContainer.getBoundsHitTest(s.N_MAP_BTN_L);this.addRxSubscription(this.canvasInputListeners.observeClick(o).subscribe(()=>{this.scaleModel.moveXStart(this.scaleModel.xStart-1)})),this.addRxSubscription(this.canvasInputListeners.observeTouchStart(o).subscribe(()=>{this.scaleModel.moveXStart(this.scaleModel.xStart-1)}));const r=this.canvasBoundsContainer.getBoundsHitTest(s.N_MAP_BTN_R);this.addRxSubscription(this.canvasInputListeners.observeClick(r).subscribe(()=>{this.scaleModel.moveXStart(this.scaleModel.xStart+1)})),this.addRxSubscription(this.canvasInputListeners.observeTouchStart(r).subscribe(()=>{this.scaleModel.moveXStart(this.scaleModel.xStart+1)})),this.addRxSubscription(this.scaleModel.xChanged.subscribe(()=>{const n=this.chartModel.mainCandleSeries;this.canvasBoundsContainer.leftRatio=n.dataIdxStart/(n.dataPoints.length-1),this.canvasBoundsContainer.rightRatio=n.dataIdxEnd/(n.dataPoints.length-1),this.canvasBoundsContainer.recalculateNavigationMapElementBounds(),this.bus.fireDraw()}))}}
6
+ import { CanvasElement } from '../../canvas/canvas-bounds-container';
7
+ import { ChartBaseElement } from '../../model/chart-base-element';
8
+ import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.component';
9
+ // TODO find out why do we need this correction
10
+ const NAV_MAP_KNOT_CORRECTION = 4;
11
+ export class NavigationMapMoveHandler extends ChartBaseElement {
12
+ constructor(bus, chartModel, scale, canvasInputListeners, canvasBoundsContainer, chartPanComponent) {
13
+ super();
14
+ this.bus = bus;
15
+ this.chartModel = chartModel;
16
+ this.scale = scale;
17
+ this.canvasInputListeners = canvasInputListeners;
18
+ this.canvasBoundsContainer = canvasBoundsContainer;
19
+ this.chartPanComponent = chartPanComponent;
20
+ this.leftKnotDragStartXRelative = 0;
21
+ this.rightKnotDragStartXRelative = 0;
22
+ this.lastMousePosition = 0;
23
+ this.leftKnotDragStart = (point) => {
24
+ const nMapChart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
25
+ this.leftKnotDragStartXRelative = point.x - nMapChart.x - NAV_MAP_KNOT_CORRECTION;
26
+ };
27
+ this.leftKnotDragTick = (dragInfo) => {
28
+ const { delta: xDelta } = dragInfo;
29
+ const chart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
30
+ const knotsWindowWidth = chart.width;
31
+ const moveLeftRatio = (this.leftKnotDragStartXRelative + xDelta) / knotsWindowWidth;
32
+ this.canvasBoundsContainer.leftRatio = moveLeftRatio;
33
+ this.scale.setXScale(Math.round(this.chartModel.mainCandleSeries.dataPoints.length * this.canvasBoundsContainer.leftRatio), this.scale.xEnd);
34
+ };
35
+ this.rightKnotDragStart = (point) => {
36
+ const nMapChart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
37
+ this.rightKnotDragStartXRelative = point.x - nMapChart.x + NAV_MAP_KNOT_CORRECTION;
38
+ };
39
+ this.rightKnotDragTick = (dragInfo) => {
40
+ const { delta: xDelta } = dragInfo;
41
+ const nMapChart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
42
+ const nMapChartWidth = nMapChart.width;
43
+ const moveRightRatio = (this.rightKnotDragStartXRelative + xDelta) / nMapChartWidth;
44
+ this.canvasBoundsContainer.rightRatio = moveRightRatio;
45
+ this.scale.setXScale(this.scale.xStart, Math.round(this.chartModel.mainCandleSeries.dataPoints.length * this.canvasBoundsContainer.rightRatio));
46
+ };
47
+ this.sliderDragStart = () => {
48
+ this.lastMousePosition = 0;
49
+ };
50
+ this.sliderDragTick = (dragInfo) => {
51
+ const { delta: absoluteXDelta } = dragInfo;
52
+ const navMap = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
53
+ const moveMultiplier = this.chartModel.mainCandleSeries.meanCandleWidth /
54
+ (navMap.width / this.chartModel.mainCandleSeries.dataPoints.length);
55
+ const step = (this.lastMousePosition - absoluteXDelta) * moveMultiplier;
56
+ this.scale.moveXStart(this.scale.xStart - step);
57
+ this.lastMousePosition = absoluteXDelta;
58
+ };
59
+ //#region knots
60
+ const knotLeftHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_KNOT_L);
61
+ const knotRightHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_KNOT_R);
62
+ const leftKnotDNDComponent = new DragNDropXComponent(knotLeftHitTest, {
63
+ onDragStart: this.leftKnotDragStart,
64
+ onDragTick: this.leftKnotDragTick,
65
+ }, this.canvasInputListeners, this.chartPanComponent);
66
+ const rightKnotDNDComponent = new DragNDropXComponent(knotRightHitTest, {
67
+ onDragStart: this.rightKnotDragStart,
68
+ onDragTick: this.rightKnotDragTick,
69
+ }, this.canvasInputListeners, this.chartPanComponent);
70
+ this.addChildEntity(leftKnotDNDComponent);
71
+ this.addChildEntity(rightKnotDNDComponent);
72
+ //#endregion
73
+ //#region slider
74
+ const sliderHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_SLIDER_WINDOW);
75
+ const sliderDNDComponent = new DragNDropXComponent(sliderHitTest, {
76
+ onDragStart: this.sliderDragStart,
77
+ onDragTick: this.sliderDragTick,
78
+ }, this.canvasInputListeners, this.chartPanComponent);
79
+ this.addChildEntity(sliderDNDComponent);
80
+ //#endregion
81
+ }
82
+ /**
83
+ * Method that activates the navigation map buttons and subscribes to their click and touch events.
84
+ * It also subscribes to the xChanged event of the scaleModel and updates the canvasBoundsContainer accordingly.
85
+ * @returns {void}
86
+ */
87
+ doActivate() {
88
+ super.doActivate();
89
+ //#region btns
90
+ const btnLeftHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_BTN_L);
91
+ this.addRxSubscription(this.canvasInputListeners.observeClick(btnLeftHitTest).subscribe(() => {
92
+ this.scale.moveXStart(this.scale.xStart - 1);
93
+ }));
94
+ this.addRxSubscription(this.canvasInputListeners.observeTouchStart(btnLeftHitTest).subscribe(() => {
95
+ this.scale.moveXStart(this.scale.xStart - 1);
96
+ }));
97
+ const btnRightHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_BTN_R);
98
+ this.addRxSubscription(this.canvasInputListeners.observeClick(btnRightHitTest).subscribe(() => {
99
+ this.scale.moveXStart(this.scale.xStart + 1);
100
+ }));
101
+ this.addRxSubscription(this.canvasInputListeners.observeTouchStart(btnRightHitTest).subscribe(() => {
102
+ this.scale.moveXStart(this.scale.xStart + 1);
103
+ }));
104
+ this.addRxSubscription(this.scale.xChanged.subscribe(() => {
105
+ const candleSeries = this.chartModel.mainCandleSeries;
106
+ this.canvasBoundsContainer.leftRatio = candleSeries.dataIdxStart / (candleSeries.dataPoints.length - 1);
107
+ this.canvasBoundsContainer.rightRatio = candleSeries.dataIdxEnd / (candleSeries.dataPoints.length - 1);
108
+ this.canvasBoundsContainer.recalculateNavigationMapElementBounds();
109
+ this.bus.fireDraw();
110
+ }));
111
+ //#endregion
112
+ }
113
+ }