@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,198 @@
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 g}from"../../canvas/canvas-bounds-container";import{redrawBackgroundArea as v}from"../../drawers/chart-background.drawer";const f={"rhombus-small":4,rhombus:6,"rhombus-large":8},c=(h,t)=>`${h}_${t}`;export class EventsDrawer{constructor(t,e,o,s,n,i,a){this.backgroundCanvas=t,this.canvasModel=e,this.chartModel=o,this.config=s,this.canvasBoundsContainer=n,this.model=i,this.formatterProvider=a,this.customIcons={};const r=this.config.components.events.icons;r&&(this.createCustomIcon("earnings",r.earnings),this.createCustomIcon("dividends",r.dividends),this.createCustomIcon("splits",r.splits),this.createCustomIcon("conference-calls",r.conferenceCalls))}createCustomIcon(t,e){if(e){const o=this.createIconImage(e.normal),s=this.createIconImage(e.hover);this.customIcons[c(t,"normal")]=o,this.customIcons[c(t,"hover")]=s}}createIconImage(t){var e;const s=new DOMParser().parseFromString(t,"text/html").querySelector("svg");let n=0;s&&(n=parseInt((e=s.getAttribute("height"))!==null&&e!==void 0?e:"",10));const r="data:image/svg+xml;base64,"+btoa(t),l=new Image;return l.src=r,{img:l,svgHeight:n}}draw(){if(!this.config.components.events.visible)return;const t=this.canvasBoundsContainer.getBounds(g.EVENTS),e=this.canvasBoundsContainer.getBounds(g.ALL_PANES),o=this.canvasModel.ctx;o.save(),this.model.events.filter(s=>this.config.components.events.eventsVisibility[s.type]).forEach(s=>{const n=this.chartModel.candleFromTimestamp(s.timestamp).xCenter(this.chartModel.scaleModel);if(n>e.x&&n<e.x+e.width){const i=this.config.colors.events[s.type].color;o.strokeStyle=i,this.customIcons[c(s.type,"hover")]!==void 0?this.drawCustomSvgEvent(o,n,t,s):this.drawDefaultEvent(o,n,t,s,i),this.model.hoveredEvent.getValue()===s&&(o.beginPath(),o.moveTo(n,e.y),o.lineTo(n,t.y+t.height/2),o.stroke(),o.closePath(),this.config.components.xAxis.visible&&this.drawLabel(n,s))}}),o.restore()}drawCustomSvgEvent(t,e,o,s){const n=o.y+o.height/2,i=this.customIcons[c(s.type,"normal")],a=this.customIcons[c(s.type,"hover")];this.model.hoveredEvent.getValue()===s?t.drawImage(a.img,e-a.svgHeight/2,n-a.svgHeight/2):t.drawImage(i.img,e-i.svgHeight/2,n-i.svgHeight/2)}drawDefaultEvent(t,e,o,s,n){const i=o.y+o.height/2;t.fillStyle=n,t.lineWidth=1.5;const a=getEventSize(s);t.beginPath(),t.moveTo(e-a,i),t.lineTo(e,i-a),t.lineTo(e+a,i),t.lineTo(e,i+a),t.closePath(),this.model.hoveredEvent.getValue()===s?t.fill():t.stroke()}drawLabel(t,e){var o;const s=this.canvasModel.ctx,n=this.canvasBoundsContainer.getBounds(g.X_AXIS),i=this.config.components.xAxis.fontFamily,a=this.config.components.xAxis.fontSize,r=(o=this.config.components.xAxis.padding.top)!==null&&o!==void 0?o:0,l=n.y+a-1+r;s.font=`${a}px ${i}`;const d=this.formatterProvider()(e.timestamp),m=s.measureText(d).width;v(this.backgroundCanvas.ctx,s,t-m/2,n.y+1,m,n.height-1),s.fillStyle=this.config.colors.events[e.type].color,s.fillText(d,t-m/2,l)}getCanvasIds(){return[this.canvasModel.canvasId]}}export function getEventSize(h){return f[h.style]}
6
+ import { CanvasElement } from '../../canvas/canvas-bounds-container';
7
+ import { redrawBackgroundArea } from '../../drawers/chart-background.drawer';
8
+ const eventsSizesDict = {
9
+ 'rhombus-small': 4,
10
+ rhombus: 6,
11
+ 'rhombus-large': 8,
12
+ };
13
+ const getIconHash = (type, state) => `${type}_${state}`;
14
+ export class EventsDrawer {
15
+ constructor(backgroundCanvas, canvasModel, chartModel, config, canvasBoundsContainer, model, formatterProvider) {
16
+ this.backgroundCanvas = backgroundCanvas;
17
+ this.canvasModel = canvasModel;
18
+ this.chartModel = chartModel;
19
+ this.config = config;
20
+ this.canvasBoundsContainer = canvasBoundsContainer;
21
+ this.model = model;
22
+ this.formatterProvider = formatterProvider;
23
+ // cache of created icons
24
+ this.customIcons = {};
25
+ const iconsConfig = this.config.components.events.icons;
26
+ if (iconsConfig) {
27
+ this.createCustomIcon('earnings', iconsConfig.earnings);
28
+ this.createCustomIcon('dividends', iconsConfig.dividends);
29
+ this.createCustomIcon('splits', iconsConfig.splits);
30
+ this.createCustomIcon('conference-calls', iconsConfig.conferenceCalls);
31
+ }
32
+ }
33
+ /**
34
+ * Creates a custom icon for a given event type.
35
+ * @param {EventType} type - The type of the event.
36
+ * @param {CustomIcon} [icon] - The custom icon object containing the normal and hover images.
37
+ * @returns {void}
38
+ */
39
+ createCustomIcon(type, icon) {
40
+ if (icon) {
41
+ const normal = this.createIconImage(icon.normal);
42
+ const hover = this.createIconImage(icon.hover);
43
+ this.customIcons[getIconHash(type, 'normal')] = normal;
44
+ this.customIcons[getIconHash(type, 'hover')] = hover;
45
+ }
46
+ }
47
+ /**
48
+ * Creates an icon image from a string containing SVG data.
49
+ * @param {string} iconString - The string containing SVG data.
50
+ * @returns {Object} An object containing an Image object and the height of the SVG element.
51
+ */
52
+ createIconImage(iconString) {
53
+ var _a;
54
+ const parser = new DOMParser();
55
+ const svgSelector = parser.parseFromString(iconString, 'text/html').querySelector('svg');
56
+ let svgHeight = 0;
57
+ if (svgSelector) {
58
+ svgHeight = parseInt((_a = svgSelector.getAttribute('height')) !== null && _a !== void 0 ? _a : '', 10);
59
+ }
60
+ const svg64 = btoa(iconString);
61
+ const b64Start = 'data:image/svg+xml;base64,';
62
+ const image64 = b64Start + svg64;
63
+ const img = new Image();
64
+ img.src = image64;
65
+ return {
66
+ img,
67
+ svgHeight,
68
+ };
69
+ }
70
+ /**
71
+ * Draws events on the chart canvas if they are visible according to the configuration.
72
+ * The events are filtered by type and then iterated over to draw them on the chart.
73
+ * If a custom icon is available in the cache, it is used to draw the event, otherwise a default event is drawn.
74
+ * If the event is currently being hovered over, a vertical line is drawn and a label is added to the x-axis.
75
+ * @returns {void}
76
+ */
77
+ draw() {
78
+ if (!this.config.components.events.visible) {
79
+ return;
80
+ }
81
+ const bounds = this.canvasBoundsContainer.getBounds(CanvasElement.EVENTS);
82
+ const chartBounds = this.canvasBoundsContainer.getBounds(CanvasElement.ALL_PANES);
83
+ const ctx = this.canvasModel.ctx;
84
+ ctx.save();
85
+ this.model.events
86
+ .filter(e => this.config.components.events.eventsVisibility[e.type])
87
+ .forEach(event => {
88
+ const x = this.chartModel.candleFromTimestamp(event.timestamp).xCenter(this.chartModel.scale);
89
+ if (x > chartBounds.x && x < chartBounds.x + chartBounds.width) {
90
+ const color = this.config.colors.events[event.type].color;
91
+ ctx.strokeStyle = color;
92
+ // check custom icon in cache
93
+ if (this.customIcons[getIconHash(event.type, 'hover')] !== undefined) {
94
+ this.drawCustomSvgEvent(ctx, x, bounds, event);
95
+ }
96
+ else {
97
+ this.drawDefaultEvent(ctx, x, bounds, event, color);
98
+ }
99
+ // draw vertical line and label for the hovered event
100
+ if (this.model.hoveredEvent.getValue() === event) {
101
+ ctx.beginPath();
102
+ ctx.moveTo(x, chartBounds.y);
103
+ ctx.lineTo(x, bounds.y + bounds.height / 2);
104
+ ctx.stroke();
105
+ ctx.closePath();
106
+ if (this.config.components.xAxis.visible) {
107
+ this.drawLabel(x, event);
108
+ }
109
+ }
110
+ }
111
+ });
112
+ ctx.restore();
113
+ }
114
+ /**
115
+ * Draws a custom SVG event on a canvas context.
116
+ * @param {CanvasRenderingContext2D} ctx - The canvas context to draw on.
117
+ * @param {number} x - The x coordinate of the event.
118
+ * @param {Bounds} bounds - The bounds of the event.
119
+ * @param {EventWithId} event - The event to draw.
120
+ * @returns {void}
121
+ */
122
+ drawCustomSvgEvent(ctx, x, bounds, event) {
123
+ const y = bounds.y + bounds.height / 2;
124
+ const normal = this.customIcons[getIconHash(event.type, 'normal')];
125
+ const hover = this.customIcons[getIconHash(event.type, 'hover')];
126
+ if (this.model.hoveredEvent.getValue() === event) {
127
+ ctx.drawImage(hover.img, x - hover.svgHeight / 2, y - hover.svgHeight / 2);
128
+ }
129
+ else {
130
+ ctx.drawImage(normal.img, x - normal.svgHeight / 2, y - normal.svgHeight / 2);
131
+ }
132
+ }
133
+ /**
134
+ * Draws a default event on a canvas context.
135
+ * @param {CanvasRenderingContext2D} ctx - The canvas context to draw on.
136
+ * @param {number} x - The x coordinate of the event.
137
+ * @param {Bounds} bounds - The bounds of the event.
138
+ * @param {EventWithId} event - The event to draw.
139
+ * @param {string} color - The color of the event.
140
+ * @returns {void}
141
+ */
142
+ drawDefaultEvent(ctx, x, bounds, event, color) {
143
+ const y = bounds.y + bounds.height / 2;
144
+ ctx.fillStyle = color;
145
+ // draw figure
146
+ ctx.lineWidth = 1.5; // 1.5 pixels
147
+ const size = getEventSize(event);
148
+ ctx.beginPath();
149
+ ctx.moveTo(x - size, y);
150
+ ctx.lineTo(x, y - size);
151
+ ctx.lineTo(x + size, y);
152
+ ctx.lineTo(x, y + size);
153
+ ctx.closePath();
154
+ if (this.model.hoveredEvent.getValue() === event) {
155
+ ctx.fill();
156
+ }
157
+ else {
158
+ ctx.stroke();
159
+ }
160
+ }
161
+ /**
162
+ * This function is responsible for drawing a label on the canvas at a given x coordinate. The label contains a formatted timestamp of a given event. The function takes two parameters: x, which is the x coordinate where the label will be drawn, and event, which is an object containing information about the event, including its timestamp and type.
163
+ * The function first gets the canvas context and the bounds of the x-axis. It then retrieves the font family, font height, and top padding from the configuration object. The y coordinate of the label is calculated based on the font height, top padding, and the y coordinate of the x-axis bounds. The font is set using the retrieved font family and font height.
164
+ * The timestamp of the event is formatted using a formatter provider function. The width of the label is calculated using the canvas context's measureText() method. The function then calls another function, redrawBackgroundArea(), to hide the regular x-axis label that may overlap with the event label.
165
+ * Finally, the function sets the fill style of the canvas context to the color associated with the event type in the configuration object. The label text is then drawn on the canvas context at the calculated x and y coordinates.
166
+ */
167
+ drawLabel(x, event) {
168
+ var _a;
169
+ const ctx = this.canvasModel.ctx;
170
+ const xAxisBounds = this.canvasBoundsContainer.getBounds(CanvasElement.X_AXIS);
171
+ const fontFamily = this.config.components.xAxis.fontFamily;
172
+ const fontHeight = this.config.components.xAxis.fontSize;
173
+ const offsetTop = (_a = this.config.components.xAxis.padding.top) !== null && _a !== void 0 ? _a : 0;
174
+ const y = xAxisBounds.y + fontHeight - 1 + offsetTop;
175
+ ctx.font = `${fontHeight}px ${fontFamily}`;
176
+ const labelText = this.formatterProvider()(event.timestamp);
177
+ const width = ctx.measureText(labelText).width;
178
+ // label can overlap with regular x-axis label, so we need to hide regular x-axis label
179
+ redrawBackgroundArea(this.backgroundCanvas.ctx, ctx, x - width / 2, xAxisBounds.y + 1, width, xAxisBounds.height - 1);
180
+ ctx.fillStyle = this.config.colors.events[event.type].color;
181
+ ctx.fillText(labelText, x - width / 2, y);
182
+ }
183
+ /**
184
+ * Returns an array of canvas IDs.
185
+ *
186
+ * @returns {Array<string>} An array containing the ID of the canvas model.
187
+ */
188
+ getCanvasIds() {
189
+ return [this.canvasModel.canvasId];
190
+ }
191
+ }
192
+ /**
193
+ * Returns the size of an event based on its style
194
+ * @param {EconomicEvent} event - The event to get the size of
195
+ * @returns {number} - The size of the event
196
+
197
+ */
198
+ export function getEventSize(event) {
199
+ return eventsSizesDict[event.style];
200
+ }
@@ -3,4 +3,72 @@
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{BehaviorSubject as n}from"rxjs";import{ChartBaseElement as o}from"../../model/chart-base-element";import{HIT_TEST_ID_RANGE as i}from"../../model/hit-test-canvas.model";export class EventsModel extends o{constructor(t){super(),this.canvasModel=t,this.events=[],this.hoveredEvent=new n(null)}setEvents(t){this.events=this.indexEvents(t)}indexEvents(t){const e=this.getIdRange()[0];return t.map((s,r)=>Object.assign(Object.assign({},s),{id:r+e})).sort((s,r)=>s.timestamp-r.timestamp)}getIdRange(){return i.EVENTS}lookup(t){return this.events.filter(e=>e.id===t)[0]}onHover(t,e){this.hoveredEvent.getValue()!==t&&(t&&(t.point=e),this.hoveredEvent.next(t),this.canvasModel.fireDraw())}onTouchStart(t,e){this.onHover(t,e)}}
6
+ import { BehaviorSubject } from 'rxjs';
7
+ import { ChartBaseElement } from '../../model/chart-base-element';
8
+ import { HIT_TEST_ID_RANGE } from '../../model/hit-test-canvas.model';
9
+ export class EventsModel extends ChartBaseElement {
10
+ constructor(canvasModel) {
11
+ super();
12
+ this.canvasModel = canvasModel;
13
+ this.events = [];
14
+ this.hoveredEvent = new BehaviorSubject(null);
15
+ }
16
+ /**
17
+ * Sets the events array of the object to the provided array of events after indexing them.
18
+ * @param {EconomicEvent[]} events - An array of events to be set as the events array of the object.
19
+ * @returns {void}
20
+ */
21
+ setEvents(events) {
22
+ this.events = this.indexEvents(events);
23
+ }
24
+ /**
25
+ * Private method to index events with unique ids and sort them by timestamp
26
+ * @param {EconomicEvent[]} events - Array of events to be indexed
27
+ * @returns {EventWithId[]} - Array of indexed events with unique ids
28
+ */
29
+ indexEvents(events) {
30
+ const startId = this.getIdRange()[0];
31
+ return events
32
+ .map((event, id) => (Object.assign(Object.assign({}, event), { id: id + startId })))
33
+ .sort((a, b) => a.timestamp - b.timestamp);
34
+ }
35
+ /**
36
+ * Returns an array of two numbers representing the range of IDs for event hit tests.
37
+ * @returns {Array<number>} An array of two numbers representing the range of IDs for event hit tests.
38
+ */
39
+ getIdRange() {
40
+ return HIT_TEST_ID_RANGE.EVENTS;
41
+ }
42
+ /**
43
+ * Returns the event with the specified id.
44
+ * @param {number} id - The id of the event to look up.
45
+ * @returns {EventWithId} - The event with the specified id.
46
+ */
47
+ lookup(id) {
48
+ return this.events.filter(event => event.id === id)[0];
49
+ }
50
+ /**
51
+ * Function that handles the hover event on a canvas element.
52
+ * @param {EventWithId} event - The event that is being hovered.
53
+ * @param {Point} [point] - The point where the event is being hovered.
54
+ * @returns {void}
55
+ */
56
+ onHover(event, point) {
57
+ const currentValue = this.hoveredEvent.getValue();
58
+ if (currentValue !== event) {
59
+ event && (event.point = point);
60
+ this.hoveredEvent.next(event);
61
+ this.canvasModel.fireDraw();
62
+ }
63
+ }
64
+ /**
65
+ * Handles the touch start event.
66
+ *
67
+ * @param {EventWithId} event - The touch start event.
68
+ * @param {Point} [point] - The point where the touch started.
69
+ * @returns {void}
70
+ */
71
+ onTouchStart(event, point) {
72
+ this.onHover(event, point);
73
+ }
74
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { NumericAxisLabel } from '../labels_generator/numeric-axis-labels.generator';
7
7
  import { BoundsProvider } from '../../model/bounds.model';
8
- import { FullChartConfig } from '../../chart.config';
8
+ import { FullChartConfig, YAxisConfig } from '../../chart.config';
9
9
  import { ChartBaseElement } from '../../model/chart-base-element';
10
10
  import { CanvasModel } from '../../model/canvas.model';
11
11
  import { CompositeDrawer } from '../../drawers/composite.drawer';
@@ -15,7 +15,7 @@ export declare class GridComponent extends ChartBaseElement {
15
15
  private drawerName;
16
16
  private drawingManager;
17
17
  private readonly drawer;
18
- constructor(canvasModel: CanvasModel, viewportModel: ViewportModel, config: FullChartConfig, drawerName: string, drawingManager: DrawingManager | CompositeDrawer, xBoundsProvider: BoundsProvider, yBoundsProvider: BoundsProvider, xLabelsProvider: () => NumericAxisLabel[], yLabelsProvider: () => NumericAxisLabel[], getBaseLine?: () => Unit, drawPredicate?: () => boolean);
18
+ constructor(canvasModel: CanvasModel, viewportModel: ViewportModel, config: FullChartConfig, yAxisState: YAxisConfig, drawerName: string, drawingManager: DrawingManager | CompositeDrawer, xBoundsProvider: BoundsProvider, yBoundsProvider: BoundsProvider, xLabelsProvider: () => NumericAxisLabel[], yLabelsProvider: () => NumericAxisLabel[], getBaseline?: () => Unit, drawPredicate?: () => boolean);
19
19
  /**
20
20
  * This method is used to deactivate the drawer and remove it from the drawing manager.
21
21
  * @protected
@@ -3,4 +3,34 @@
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{ChartBaseElement as m}from"../../model/chart-base-element";import{GridDrawer as c}from"./grid.drawer";export class GridComponent extends m{constructor(r,e,a,t,i,d,s,o,n,w,h){super(),this.drawerName=t,this.drawingManager=i,this.drawer=new c(r,e,a,d,s,o,n,h,w)}doDeactivate(){super.doDeactivate(),this.drawingManager.removeDrawer(this.drawer)}doActivate(){super.doActivate(),this.drawingManager.addDrawer(this.drawer,this.drawerName)}}
6
+ import { ChartBaseElement } from '../../model/chart-base-element';
7
+ import { GridDrawer } from './grid.drawer';
8
+ export class GridComponent extends ChartBaseElement {
9
+ constructor(canvasModel, viewportModel, config, yAxisState, drawerName, drawingManager, xBoundsProvider, yBoundsProvider, xLabelsProvider, yLabelsProvider, getBaseline, drawPredicate) {
10
+ super();
11
+ this.drawerName = drawerName;
12
+ this.drawingManager = drawingManager;
13
+ this.drawer = new GridDrawer(canvasModel, viewportModel, config, yAxisState, xBoundsProvider, yBoundsProvider, xLabelsProvider, yLabelsProvider, drawPredicate, getBaseline);
14
+ }
15
+ /**
16
+ * This method is used to deactivate the drawer and remove it from the drawing manager.
17
+ * @protected
18
+ * @function
19
+ * @name doDeactivate
20
+ * @returns {void}
21
+ */
22
+ doDeactivate() {
23
+ super.doDeactivate();
24
+ this.drawingManager.removeDrawer(this.drawer);
25
+ }
26
+ /**
27
+ * This method is used to activate the drawer. It calls the parent class's doActivate method and adds the drawer to the drawing manager.
28
+ * @protected
29
+ * @function
30
+ * @returns {void}
31
+ */
32
+ doActivate() {
33
+ super.doActivate();
34
+ this.drawingManager.addDrawer(this.drawer, this.drawerName);
35
+ }
36
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { NumericAxisLabel } from '../labels_generator/numeric-axis-labels.generator';
7
7
  import { BoundsProvider } from '../../model/bounds.model';
8
- import { FullChartConfig } from '../../chart.config';
8
+ import { FullChartConfig, YAxisConfig } from '../../chart.config';
9
9
  import { CanvasModel } from '../../model/canvas.model';
10
10
  import { Drawer } from '../../drawers/drawing-manager';
11
11
  import { Unit, ViewportModel } from '../../model/scaling/viewport.model';
@@ -20,13 +20,14 @@ export declare class GridDrawer implements Drawer {
20
20
  private canvasModel;
21
21
  private viewportModel;
22
22
  private config;
23
+ private yAxisState;
23
24
  private xBoundsProvider;
24
25
  private yBoundsProvider;
25
26
  private xLabelsProvider;
26
27
  private yLabelsProvider;
27
28
  private drawPredicate;
28
- private getBaseLine?;
29
- constructor(canvasModel: CanvasModel, viewportModel: ViewportModel, config: FullChartConfig, xBoundsProvider: BoundsProvider, yBoundsProvider: BoundsProvider, xLabelsProvider: () => NumericAxisLabel[], yLabelsProvider: () => NumericAxisLabel[], drawPredicate?: () => boolean, getBaseLine?: (() => Unit) | undefined);
29
+ private getBaseline?;
30
+ constructor(canvasModel: CanvasModel, viewportModel: ViewportModel, config: FullChartConfig, yAxisState: YAxisConfig, xBoundsProvider: BoundsProvider, yBoundsProvider: BoundsProvider, xLabelsProvider: () => NumericAxisLabel[], yLabelsProvider: () => NumericAxisLabel[], drawPredicate?: () => boolean, getBaseline?: (() => Unit) | undefined);
30
31
  /**
31
32
  * Draws the chart on the canvas if the drawPredicate is true.
32
33
  * @returns {void}
@@ -3,4 +3,109 @@
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{avoidAntialiasing as r}from"../../utils/canvas/canvas-drawing-functions.utils";import{DEFAULT_PRICE_LABEL_PADDING as c,getLabelYOffset as g}from"../y_axis/y-axis-labels.drawer";import{floor as h}from"../../utils/math.utils";export class GridDrawer{constructor(o,e,i,n,t,s,a,d=()=>!0,l){this.canvasModel=o,this.viewportModel=e,this.config=i,this.xBoundsProvider=n,this.yBoundsProvider=t,this.xLabelsProvider=s,this.yLabelsProvider=a,this.drawPredicate=d,this.getBaseLine=l}draw(){if(this.drawPredicate()){const o=this.canvasModel.ctx;r(o,()=>this.drawVertical(o)),r(o,()=>this.drawHorizontal(o)),r(o,()=>this.drawZeroLine(o))}}drawZeroLine(o){if(this.getBaseLine&&this.config.components.yAxis.type==="percent"&&this.config.components.yAxis.zeroPercentLine){const e=this.xBoundsProvider(),i=h(this.getBaseLine());o.beginPath(),o.strokeStyle=this.config.colors.yAxis.zeroPercentLine,o.setLineDash([]),o.moveTo(e.x,i),o.lineTo(e.x+e.width,i),o.stroke(),o.closePath()}}drawVertical(o){const e=this.xLabelsProvider();if(e.length&&this.config.components.grid.vertical){o.lineWidth=this.config.components.grid.width,o.strokeStyle=this.config.colors.chartAreaTheme.gridColor,o.setLineDash(this.config.components.grid.dash||[]);const i=this.xBoundsProvider(),n=i.x+i.width;for(const t of e){const s=h(this.viewportModel.toX(t.value));s>i.x&&s<n&&(o.beginPath(),o.moveTo(s,i.y),o.lineTo(s,i.y+i.height),o.stroke())}}}drawHorizontal(o){const e=this.yLabelsProvider();if(e.length&&this.config.components.grid.horizontal){o.lineWidth=this.config.components.grid.width,o.strokeStyle=this.config.colors.chartAreaTheme.gridColor,o.setLineDash(this.config.components.grid.dash||[]);const i=this.yBoundsProvider();for(const n of e){const t=h(this.viewportModel.toY(n.value)),s=g(n.text,o,c);t>i.y+s&&t<i.y+i.height-s&&(o.beginPath(),o.moveTo(i.x,t),o.lineTo(i.x+i.width,t),o.stroke())}}}getCanvasIds(){return[this.canvasModel.canvasId]}}
6
+ import { avoidAntialiasing } from '../../utils/canvas/canvas-drawing-functions.utils';
7
+ import { DEFAULT_PRICE_LABEL_PADDING, getLabelYOffset } from '../y_axis/y-axis-labels.drawer';
8
+ import { floor } from '../../utils/math.utils';
9
+ import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
10
+ /**
11
+ * Draws grid lines on chart.
12
+ */
13
+ export class GridDrawer {
14
+ constructor(canvasModel, viewportModel, config, yAxisState, xBoundsProvider, yBoundsProvider, xLabelsProvider, yLabelsProvider, drawPredicate = () => true, getBaseline) {
15
+ this.canvasModel = canvasModel;
16
+ this.viewportModel = viewportModel;
17
+ this.config = config;
18
+ this.yAxisState = yAxisState;
19
+ this.xBoundsProvider = xBoundsProvider;
20
+ this.yBoundsProvider = yBoundsProvider;
21
+ this.xLabelsProvider = xLabelsProvider;
22
+ this.yLabelsProvider = yLabelsProvider;
23
+ this.drawPredicate = drawPredicate;
24
+ this.getBaseline = getBaseline;
25
+ }
26
+ /**
27
+ * Draws the chart on the canvas if the drawPredicate is true.
28
+ * @returns {void}
29
+ */
30
+ draw() {
31
+ if (this.drawPredicate()) {
32
+ const ctx = this.canvasModel.ctx;
33
+ avoidAntialiasing(ctx, () => this.drawVertical(ctx));
34
+ avoidAntialiasing(ctx, () => this.drawHorizontal(ctx));
35
+ avoidAntialiasing(ctx, () => this.drawZeroLine(ctx));
36
+ }
37
+ }
38
+ /**
39
+ * Draws a zero line on the y-axis if the chart is a percentage chart and the zeroPercentLine option is enabled.
40
+ * @param {CanvasRenderingContext2D} ctx - The 2D rendering context of the canvas element.
41
+ */
42
+ drawZeroLine(ctx) {
43
+ if (this.getBaseline &&
44
+ this.yAxisState.type === 'percent' &&
45
+ this.yAxisState.zeroPercentLine) {
46
+ const bounds = this.xBoundsProvider();
47
+ const y = floor(this.getBaseline());
48
+ ctx.beginPath();
49
+ ctx.strokeStyle = this.config.colors.yAxis.zeroPercentLine;
50
+ ctx.setLineDash([]);
51
+ ctx.moveTo(bounds.x, y);
52
+ ctx.lineTo(bounds.x + bounds.width, y);
53
+ ctx.stroke();
54
+ ctx.closePath();
55
+ }
56
+ }
57
+ /**
58
+ * Draws vertical grid lines on the canvas context provided.
59
+ * @param {CanvasRenderingContext2D} ctx - The canvas context to draw on.
60
+ * @returns {void}
61
+ */
62
+ drawVertical(ctx) {
63
+ const xAxisLabels = this.xLabelsProvider();
64
+ if (xAxisLabels.length && this.config.components.grid.vertical) {
65
+ ctx.lineWidth = this.config.components.grid.width;
66
+ ctx.strokeStyle = this.config.colors.chartAreaTheme.gridColor;
67
+ ctx.setLineDash(this.config.components.grid.dash || []);
68
+ const bounds = this.xBoundsProvider();
69
+ const boundsEnd = bounds.x + bounds.width;
70
+ for (const label of xAxisLabels) {
71
+ const x = floorToDPR(this.viewportModel.toX(label.value));
72
+ if (x > bounds.x && x < boundsEnd) {
73
+ ctx.beginPath();
74
+ ctx.moveTo(x, bounds.y);
75
+ ctx.lineTo(x, bounds.y + bounds.height);
76
+ ctx.stroke();
77
+ }
78
+ }
79
+ }
80
+ }
81
+ /**
82
+ * This function is responsible for drawing horizontal grid lines on the chart. It takes a CanvasRenderingContext2D object as a parameter. It first retrieves the y-axis labels using the yLabelsProvider method. If there are any labels and the horizontal grid is enabled in the configuration, it sets the line width, color, and dash style. It then retrieves the y-bounds using the yBoundsProvider method. For each label, it calculates the y-coordinate using the toY method of the viewportModel object. It also calculates the label's y-offset using the getLabelYOffset method. If the y-coordinate is within the bounds of the chart, it draws a horizontal line using the beginPath, moveTo, lineTo, and stroke methods of the CanvasRenderingContext2D object.
83
+ */
84
+ drawHorizontal(ctx) {
85
+ const yAxisLabels = this.yLabelsProvider();
86
+ if (yAxisLabels.length && this.config.components.grid.horizontal) {
87
+ ctx.lineWidth = this.config.components.grid.width;
88
+ ctx.strokeStyle = this.config.colors.chartAreaTheme.gridColor;
89
+ ctx.setLineDash(this.config.components.grid.dash || []);
90
+ const bounds = this.yBoundsProvider();
91
+ for (const label of yAxisLabels) {
92
+ const y = floor(this.viewportModel.toY(label.value));
93
+ const labelYOffset = getLabelYOffset(label.text, ctx, DEFAULT_PRICE_LABEL_PADDING);
94
+ // do not draw, if out of bounds
95
+ if (y > bounds.y + labelYOffset && y < bounds.y + bounds.height - labelYOffset) {
96
+ ctx.beginPath();
97
+ ctx.moveTo(bounds.x, y);
98
+ ctx.lineTo(bounds.x + bounds.width, y);
99
+ ctx.stroke();
100
+ }
101
+ }
102
+ }
103
+ }
104
+ /**
105
+ * Returns an array of strings containing the ID of the canvas model.
106
+ * @returns {Array<string>} An array of strings containing the ID of the canvas model.
107
+ */
108
+ getCanvasIds() {
109
+ return [this.canvasModel.canvasId];
110
+ }
111
+ }
@@ -3,4 +3,15 @@
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{ChartBaseElement as s}from"../../model/chart-base-element";import{HighLowDrawer as w}from"./high-low.drawer";export class HighLowComponent extends s{constructor(r,o,e,t,a){super();const n=new w(o,e,r,t);a.addDrawer(n,"HIGH_LOW")}}
6
+ import { ChartBaseElement } from '../../model/chart-base-element';
7
+ import { HighLowDrawer } from './high-low.drawer';
8
+ /**
9
+ * Shows the highest and lowest prices labels over all candles in chart (not only in viewport).
10
+ */
11
+ export class HighLowComponent extends ChartBaseElement {
12
+ constructor(config, canvasModel, chartModel, canvasBoundsContainer, drawingManager) {
13
+ super();
14
+ const hiLowDrawer = new HighLowDrawer(canvasModel, chartModel, config, canvasBoundsContainer);
15
+ drawingManager.addDrawer(hiLowDrawer, 'HIGH_LOW');
16
+ }
17
+ }
@@ -3,4 +3,129 @@
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 h}from"../../canvas/canvas-bounds-container";import{getTextLineHeight as c}from"../../utils/canvas/canvas-text-functions.utils";export class HighLowDrawer{constructor(t,o,r,e){this.canvasModel=t,this.chartModel=o,this.config=r,this.canvasBoundsContainer=e}draw(){if(this.config.components.highLow.visible&&this.chartModel.isReady()){const{high:t,low:o,highIdx:r,lowIdx:e}=this.chartModel.mainCandleSeries.zippedHighLow,s=this.chartModel.mainCandleSeries.dataIdxStart,i=s+r,n=s+e,a=this.canvasModel.ctx;a.save(),a.font=this.config.components.highLow.font,this.drawMarkerLabel(a,i,t,"high"),this.drawMarkerLabel(a,n,o,"low"),a.restore()}}drawMarkerLabel(t,o,r,e){const s=this.getMarkerY(t,r,e==="low");if(!this.checkMarkerInBounds(s))return;const i=this.getMarkerText(r,e),n=this.getMarkerX(t,o,i);t.fillStyle=e==="high"?this.config.colors.highLowTheme.highColor:this.config.colors.highLowTheme.lowColor,t.fillText(i,n,s)}getMarkerText(t,o){const r=this.chartModel.pane.regularFormatter(t);return`${o==="high"?"H:":"L:"} ${r}`}getMarkerY(t,o,r=!1){const e=this.chartModel.toY(o);if(r){const s=c(t);return e+s}return e}checkMarkerInBounds(t){const o=this.canvasBoundsContainer.getBounds(h.CHART);return t>o.y&&t<o.y+o.height}getMarkerX(t,o,r){let e=this.chartModel.toX(o);const s=this.canvasBoundsContainer.getBounds(h.CHART),i=4,n=t.measureText(r).width;return e+i+n>s.width&&(e=e-(i+n)),e+i}getCanvasIds(){return[this.canvasModel.canvasId]}}
6
+ import { CanvasElement } from '../../canvas/canvas-bounds-container';
7
+ import { getTextLineHeight } from '../../utils/canvas/canvas-text-functions.utils';
8
+ export class HighLowDrawer {
9
+ constructor(canvasModel, chartModel, config, canvasBoundsContainer) {
10
+ this.canvasModel = canvasModel;
11
+ this.chartModel = chartModel;
12
+ this.config = config;
13
+ this.canvasBoundsContainer = canvasBoundsContainer;
14
+ }
15
+ /**
16
+ * This function is responsible for drawing the high and low markers on the chart canvas. It checks if the highLow component is visible and if the chartModel is ready. If so, it retrieves the high, low, highIdx, and lowIdx from the chartModel's mainCandleSeries zippedHighLow property.
17
+ * The function then calculates the global indexes of the high and low candles by adding the viewportStartCandleGlobalIdx to the highIdx and lowIdx respectively. It then saves the canvas context and sets the font to the highLow font specified in the config.
18
+ * Finally, it calls the drawMarkerLabel function twice, passing in the canvas context, the final global index of the high or low candle, the high or low value, and a string indicating whether it is a high or low marker. After both markers have been drawn, the canvas context is restored.
19
+ */
20
+ draw() {
21
+ if (this.config.components.highLow.visible && this.chartModel.isReady()) {
22
+ const { high, low, highIdx, lowIdx } = this.chartModel.mainCandleSeries.zippedHighLow;
23
+ /**
24
+ * the thing is that `highIdx` and `lowIdx` from the `this.chartModel.mainCandleSeries.zippedHighLow`
25
+ * are responsible for indexes in the viewport series array
26
+ * but to draw the high low text in the correct places, we need to know the global indexes of
27
+ * the `high` and `low` candles
28
+ */
29
+ const viewportStartCandleGlobalIdx = this.chartModel.mainCandleSeries.dataIdxStart;
30
+ const finalHighIdx = viewportStartCandleGlobalIdx + highIdx;
31
+ const finalLowIdx = viewportStartCandleGlobalIdx + lowIdx;
32
+ const ctx = this.canvasModel.ctx;
33
+ ctx.save();
34
+ ctx.font = this.config.components.highLow.font;
35
+ this.drawMarkerLabel(ctx, finalHighIdx, high, 'high');
36
+ this.drawMarkerLabel(ctx, finalLowIdx, low, 'low');
37
+ ctx.restore();
38
+ }
39
+ }
40
+ /**
41
+ * Draws a marker label on the canvas context at a specific position.
42
+ * @param {CanvasRenderingContext2D} ctx - The canvas context to draw on.
43
+ * @param {number} candleIdx - The index of the candle.
44
+ * @param {number} yValue - The y value of the marker.
45
+ * @param {MarkerType} type - The type of the marker.
46
+ * @returns {void}
47
+ */
48
+ drawMarkerLabel(ctx, candleIdx, yValue, type) {
49
+ const y = this.getMarkerY(ctx, yValue, type === 'low');
50
+ if (!this.checkMarkerInBounds(y)) {
51
+ return;
52
+ }
53
+ const text = this.getMarkerText(yValue, type);
54
+ const x = this.getMarkerX(ctx, candleIdx, text);
55
+ ctx.fillStyle =
56
+ type === 'high' ? this.config.colors.highLowTheme.highColor : this.config.colors.highLowTheme.lowColor;
57
+ ctx.fillText(text, x, y);
58
+ }
59
+ /**
60
+ * Returns a string that represents a marker text for a given yValue and type.
61
+ *
62
+ * @private
63
+ * @param {number} yValue - The yValue to format.
64
+ * @param {MarkerType} type - The type of the marker ('high' or 'low').
65
+ * @returns {string} - The formatted marker text.
66
+ */
67
+ getMarkerText(yValue, type) {
68
+ const formattedValue = this.chartModel.pane.regularFormatter(yValue);
69
+ const prefix = type === 'high' ? 'H:' : 'L:';
70
+ return `${prefix} ${formattedValue}`;
71
+ }
72
+ /**
73
+ * Returns the y-coordinate of a marker on the chart.
74
+ * @param {CanvasRenderingContext2D} ctx - The rendering context of the canvas.
75
+ * @param {number} yValue - The y-value of the marker.
76
+ * @param {boolean} [offset=false] - Whether to add an offset to the y-coordinate.
77
+ * @returns {number} The y-coordinate of the marker.
78
+ */
79
+ getMarkerY(ctx, yValue, offset = false) {
80
+ const y = this.chartModel.toY(yValue);
81
+ if (offset) {
82
+ const fontSize = getTextLineHeight(ctx);
83
+ return y + fontSize;
84
+ }
85
+ return y;
86
+ }
87
+ /**
88
+ * Checks if the given Y coordinate is within the bounds of the chart.
89
+ * @param {number} y - The Y coordinate to check.
90
+ * @returns {boolean} - Returns true if the Y coordinate is within the bounds of the chart, otherwise returns false.
91
+ */
92
+ checkMarkerInBounds(y) {
93
+ const chartBounds = this.canvasBoundsContainer.getBounds(CanvasElement.CHART);
94
+ if (y > chartBounds.y && y < chartBounds.y + chartBounds.height) {
95
+ return true;
96
+ }
97
+ // if the Y coordinate of the text doesn't fit the viewport -> do not draw it
98
+ return false;
99
+ }
100
+ /**
101
+ * Calculates the x position of the marker for a given candle index and text
102
+ * @param {CanvasRenderingContext2D} ctx - The canvas rendering context
103
+ * @param {number} candleIdx - The index of the candle
104
+ * @param {string} text - The text to be displayed
105
+ * @returns {number} - The x position of the marker
106
+ */
107
+ getMarkerX(ctx, candleIdx, text) {
108
+ let x = this.chartModel.toX(candleIdx);
109
+ const chartBounds = this.canvasBoundsContainer.getBounds(CanvasElement.CHART);
110
+ const shift = 4;
111
+ /**
112
+ * recalculates position of the text if it overexceed the chart bounds
113
+ * it will look like it turns from the right to the left
114
+ * it helps to fix the situation when
115
+ * the candle is still visible, but the text may overflow the bounds
116
+ */
117
+ const textWidth = ctx.measureText(text).width;
118
+ if (x + shift + textWidth > chartBounds.width) {
119
+ x = x - (shift + textWidth);
120
+ }
121
+ return x + shift;
122
+ }
123
+ /**
124
+ * Returns an array of canvas IDs.
125
+ *
126
+ * @returns {Array<string>} An array containing the ID of the canvas model.
127
+ */
128
+ getCanvasIds() {
129
+ return [this.canvasModel.canvasId];
130
+ }
131
+ }