@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,165 @@
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{CandleSeriesModel as $}from"../../model/candle-series.model";import{avoidAntialiasing as X}from"../../utils/canvas/canvas-drawing-functions.utils";import{dpr as P,floorToDPR as m}from"../../utils/device/device-pixel-ratio.utils";import{setLineWidth as A}from"../data-series.drawer";import{flat as E}from"../../utils/array.utils";export class CandleDrawer{constructor(i){this.config=i,this.pixelLength=1,this.lineWidthCU=1,this.halfLineWidthCU=1}draw(i,e,t,o){if(t instanceof $){const r=E(e);A(i,this.config.candleLineWidth,t,o,this.config.candleLineWidth),X(i,()=>{this.pixelLength=1/P,this.halfLineWidthCU=i.lineWidth/2,this.lineWidthCU=i.lineWidth;for(const f of r){const{candleTheme:h,activeCandleTheme:l}=t.colors;h&&l&&this.drawCandle(i,o,t,f)}})}}drawCandle(i,e,t,o){const{candleTheme:r,activeCandleTheme:f}=t.colors,h=o.name,l=o.isActive?f:r,d=o.isHollow;e.singleColor?i.fillStyle=e.singleColor:d?i.fillStyle=l[`${h}WickColor`]:i.fillStyle=l[`${h}Color`];const s=m(t.view.toX(o.startUnit)),a=m(t.view.xPixels(o.width)),w=o.bodyHeight(t.view),[W,n,y,T]=o.yBodyKeyPoints(t.view),c=n===y?n+1:y,g=W===T?W+1:T,p=l[`${h}Color`],B=h==="none"?p:l[`${h}WickColor`];i.fillStyle=p,e.singleColor?i.strokeStyle=e.singleColor:i.strokeStyle=B;const v=d||(o.hasBorder&&o.isActive?this.config.showActiveCandlesBorder:this.config.showCandlesBorder),k=this.config.showWicks;if(a<2)i.beginPath(),i.moveTo(s,k?W:n),i.lineTo(s,k?g:c),i.stroke();else if(a<3)i.beginPath(),i.moveTo(s,k?W:n),i.lineTo(s,k?g:c),i.moveTo(s+1,n),i.lineTo(s+1,c),i.stroke();else if(a===3){const C=a/P;this.drawCandlesWicks(i,s+C,W,g,n,c),d||(i.beginPath(),i.moveTo(s+C,n),i.lineTo(s+C,c),i.stroke()),this.drawCandleBorder(i,e,l,o,s+this.halfLineWidthCU,n+this.halfLineWidthCU,a-this.lineWidthCU,w-this.lineWidthCU)}else{const C=m(t.view.toX(o.centerUnit));this.drawCandlesWicks(i,C,W,g,n,c-1);const S=this.config.candlePaddingPercent,U=Math.max(m(a*S/2),this.pixelLength),L=s+U,b=a-U*2;d||(e.singleColor&&(i.fillStyle=e.singleColor),i.fillRect(L,n,b,w)),v&&this.drawCandleBorder(i,e,l,o,L+this.halfLineWidthCU,n+this.halfLineWidthCU,b-this.lineWidthCU,w-this.lineWidthCU)}}drawCandlesWicks(i,e,t,o,r,f){this.config.showWicks&&(i.beginPath(),i.moveTo(e,t),i.lineTo(e,r),i.moveTo(e,f),i.lineTo(e,o),i.stroke())}drawCandleBorder(i,e,t,o,r,f,h,l){if(e.singleColor)i.strokeStyle=e.singleColor;else{const d=o.name;i.strokeStyle=d==="none"?t[`${d}Color`]:t[`${d}WickColor`]}i.strokeRect(r,f,h,l)}}
6
+ import { CandleSeriesModel } from '../../model/candle-series.model';
7
+ import { avoidAntialiasing } from '../../utils/canvas/canvas-drawing-functions.utils';
8
+ import { dpr, floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
9
+ import { setLineWidth } from '../data-series.drawer';
10
+ import { flat } from '../../utils/array.utils';
11
+ export class CandleDrawer {
12
+ constructor(config) {
13
+ this.config = config;
14
+ //#region
15
+ // These properties are some kind of optimization hack
16
+ // we can calculate them inside drawCandle method, but it can affect performance since there are a lot of candles - lots of recalculations
17
+ // this value is calculate in following way: 1 / devicePixelRatio
18
+ // pixelLength is a length of one pixel in canvas units (CU), for example if dpr is 1 when in 1 CU we have 1 pixel
19
+ // for dpr 2 we have pixel length equal 0.5 CU, so when you draw a line with width 2, the actual width in pixels will be equal 4
20
+ this.pixelLength = 1;
21
+ // lineWidth and halfLineWidth are calculated using ctx.lineWidth (CU - canvas unit)
22
+ // why do we need half line width and line width? - to correctly draw candle border
23
+ // Canvas stroke draws outline border - for example, if we have a rectangle with height=10, width=20
24
+ // and we try to draw a border for this square like this: ctx.strokeRect(0, 0, 10, 20), lineWidth=2
25
+ // as a result on the canvas we have a rectangle which edge points are (-1, -1), (21, 11);
26
+ // for lineWidth=4 we get this edge points as a result: (-2, -2), (22, 12).
27
+ // However the border should not exceed candle width, so we add halfLine width to start point for rectangle
28
+ // and subtract lineWidth from width/height. As a result, candle border on canvas won't exceed candle width
29
+ this.lineWidthCU = 1;
30
+ this.halfLineWidthCU = 1;
31
+ }
32
+ //#endregion
33
+ draw(ctx,
34
+ /**
35
+ * You can pass two-dimension array to divide series into multiple parts
36
+ */
37
+ points, model, drawerConfig) {
38
+ if (model instanceof CandleSeriesModel) {
39
+ // @ts-ignore
40
+ const visualCandles = flat(points);
41
+ // TODO FIXME draw called 3-4 times on single candle update even if multichart is off
42
+ setLineWidth(ctx, this.config.candleLineWidth, model, drawerConfig, this.config.candleLineWidth);
43
+ avoidAntialiasing(ctx, () => {
44
+ this.pixelLength = 1 / dpr;
45
+ this.halfLineWidthCU = ctx.lineWidth / 2;
46
+ this.lineWidthCU = ctx.lineWidth;
47
+ for (const visualCandle of visualCandles) {
48
+ const { candleTheme, activeCandleTheme } = model.colors;
49
+ if (candleTheme && activeCandleTheme) {
50
+ this.drawCandle(ctx, drawerConfig, model, visualCandle);
51
+ }
52
+ }
53
+ });
54
+ }
55
+ }
56
+ drawCandle(ctx, drawerConfig, candleSeries, visualCandle) {
57
+ const { candleTheme, activeCandleTheme } = candleSeries.colors;
58
+ const direction = visualCandle.name;
59
+ const currentCandleTheme = visualCandle.isActive ? activeCandleTheme : candleTheme;
60
+ const isHollow = visualCandle.isHollow;
61
+ // choose candle filling color
62
+ if (drawerConfig.singleColor) {
63
+ ctx.fillStyle = drawerConfig.singleColor;
64
+ }
65
+ else if (isHollow) {
66
+ ctx.fillStyle = currentCandleTheme[`${direction}WickColor`];
67
+ }
68
+ else {
69
+ ctx.fillStyle = currentCandleTheme[`${direction}Color`];
70
+ }
71
+ const baseX = floorToDPR(candleSeries.view.toX(visualCandle.startUnit));
72
+ const width = floorToDPR(candleSeries.view.xPixels(visualCandle.width));
73
+ const bodyH = visualCandle.bodyHeight(candleSeries.view);
74
+ const [lineStart, bodyStart, _bodyEnd, _lineEnd] = visualCandle.yBodyKeyPoints(candleSeries.view);
75
+ const bodyEnd = bodyStart === _bodyEnd ? bodyStart + 1 : _bodyEnd;
76
+ const lineEnd = lineStart === _lineEnd ? lineStart + 1 : _lineEnd;
77
+ const candleColor = currentCandleTheme[`${direction}Color`];
78
+ const wickColor = direction === 'none' ? candleColor : currentCandleTheme[`${direction}WickColor`];
79
+ ctx.fillStyle = candleColor;
80
+ // wick style, borders are drawn after the wicks, so style for borders will be changed in drawBorder method
81
+ if (drawerConfig.singleColor) {
82
+ ctx.strokeStyle = drawerConfig.singleColor;
83
+ }
84
+ else {
85
+ ctx.strokeStyle = wickColor;
86
+ }
87
+ const showCandleBorder = isHollow ||
88
+ (visualCandle.hasBorder && visualCandle.isActive
89
+ ? this.config.showActiveCandlesBorder
90
+ : this.config.showCandlesBorder);
91
+ // just draw a vertical line
92
+ const showWicks = this.config.showWicks;
93
+ // separate logic for each candle width in pixels
94
+ if (width < 2) {
95
+ ctx.beginPath();
96
+ ctx.moveTo(baseX, showWicks ? lineStart : bodyStart);
97
+ ctx.lineTo(baseX, showWicks ? lineEnd : bodyEnd);
98
+ ctx.stroke();
99
+ }
100
+ else if (width < 3) {
101
+ // draw 2 vertical lines for each px width
102
+ ctx.beginPath();
103
+ ctx.moveTo(baseX, showWicks ? lineStart : bodyStart);
104
+ ctx.lineTo(baseX, showWicks ? lineEnd : bodyEnd);
105
+ ctx.moveTo(baseX + 1, bodyStart);
106
+ ctx.lineTo(baseX + 1, bodyEnd);
107
+ ctx.stroke();
108
+ }
109
+ else if (width === 3) {
110
+ const offset = width / dpr;
111
+ this.drawCandlesWicks(ctx, baseX + offset, lineStart, lineEnd, bodyStart, bodyEnd);
112
+ // border = 2px + 1px line
113
+ if (!isHollow) {
114
+ ctx.beginPath();
115
+ ctx.moveTo(baseX + offset, bodyStart);
116
+ ctx.lineTo(baseX + offset, bodyEnd);
117
+ ctx.stroke();
118
+ }
119
+ this.drawCandleBorder(ctx, drawerConfig, currentCandleTheme, visualCandle, baseX + this.halfLineWidthCU, bodyStart + this.halfLineWidthCU, width - this.lineWidthCU, bodyH - this.lineWidthCU);
120
+ }
121
+ else {
122
+ // add paddings if exist
123
+ const wickX = visualCandle.x(candleSeries.view);
124
+ // candles' wick doesn't touch body end, so subtract 1
125
+ // we will rework the drawer in future, so let's keep it this way for now
126
+ this.drawCandlesWicks(ctx, wickX, lineStart, lineEnd, bodyStart, bodyEnd - 1);
127
+ const paddingPercent = this.config.candlePaddingPercent;
128
+ const paddingWidthOffset = Math.max(floorToDPR((width * paddingPercent) / 2), this.pixelLength);
129
+ const paddingBaseX = baseX + paddingWidthOffset;
130
+ const paddingWidth = width - paddingWidthOffset * 2;
131
+ if (!isHollow) {
132
+ if (drawerConfig.singleColor) {
133
+ ctx.fillStyle = drawerConfig.singleColor;
134
+ }
135
+ ctx.fillRect(paddingBaseX, bodyStart, paddingWidth, bodyH);
136
+ }
137
+ // choose border color around candle and draw candle
138
+ if (showCandleBorder) {
139
+ this.drawCandleBorder(ctx, drawerConfig, currentCandleTheme, visualCandle, paddingBaseX + this.halfLineWidthCU, bodyStart + this.halfLineWidthCU, paddingWidth - this.lineWidthCU, bodyH - this.lineWidthCU);
140
+ }
141
+ }
142
+ }
143
+ drawCandlesWicks(ctx, x, lineStart, lineEnd, bodyStart, bodyEnd) {
144
+ // draw wick vertical line
145
+ if (this.config.showWicks) {
146
+ ctx.beginPath();
147
+ // upper wick
148
+ ctx.moveTo(x, lineStart);
149
+ ctx.lineTo(x, bodyStart);
150
+ // lower wick
151
+ ctx.moveTo(x, bodyEnd);
152
+ ctx.lineTo(x, lineEnd);
153
+ ctx.stroke();
154
+ }
155
+ }
156
+ drawCandleBorder(ctx, drawerConfig, candleTheme, visualCandle, x, y, w, h) {
157
+ if (drawerConfig.singleColor) {
158
+ ctx.strokeStyle = drawerConfig.singleColor;
159
+ }
160
+ else {
161
+ const direction = visualCandle.name;
162
+ ctx.strokeStyle =
163
+ direction === 'none' ? candleTheme[`${direction}Color`] : candleTheme[`${direction}WickColor`];
164
+ }
165
+ ctx.strokeRect(x, y, w, h);
166
+ }
167
+ }
@@ -3,4 +3,60 @@
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{CandleSeriesModel as p}from"../../model/candle-series.model";import{floorToDPR as d}from"../../utils/device/device-pixel-ratio.utils";export class HistogramDrawer{constructor(o){this.config=o}draw(o,S,e,s){if(e instanceof p){const C=S.flat(),h=e.scaleModel.getBounds(),f=h.y+h.height;for(const t of C){o.beginPath();const c=t.name,i=this.config.barCapSize,n=e.colors.histogram;if(n===void 0)return;s.singleColor?o.fillStyle=s.singleColor:o.fillStyle=n[`${c}Bright`];const r=t.xStart(e.view),l=d(e.view.toY(t.close)),g=d(e.view.xPixels(t.width));o.fillRect(r,l,g,i);const a=o.createLinearGradient(0,l+i,0,f);s.singleColor?o.fillStyle=s.singleColor:(a.addColorStop(0,n[`${c}Cap`]),a.addColorStop(1,n[`${c}Bottom`]),o.fillStyle=a),g===0?(o.beginPath(),o.strokeStyle=a,o.moveTo(r,l+i),o.lineTo(r,f),o.stroke(),o.closePath()):o.fillRect(r,l+i,g,f-l-i)}}}}
6
+ import { CandleSeriesModel } from '../../model/candle-series.model';
7
+ import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
8
+ export class HistogramDrawer {
9
+ constructor(config) {
10
+ this.config = config;
11
+ }
12
+ draw(ctx, points, model, drawerConfig) {
13
+ if (model instanceof CandleSeriesModel) {
14
+ // @ts-ignore
15
+ const visualCandles = points.flat();
16
+ const bounds = model.scale.getBounds();
17
+ const bottomY = bounds.y + bounds.height;
18
+ for (const visualCandle of visualCandles) {
19
+ ctx.beginPath();
20
+ const direction = visualCandle.name;
21
+ const capHeight = this.config.barCapSize;
22
+ const histogramColors = model.colors.histogram;
23
+ if (histogramColors === undefined) {
24
+ return;
25
+ }
26
+ if (drawerConfig.singleColor) {
27
+ ctx.fillStyle = drawerConfig.singleColor;
28
+ }
29
+ else {
30
+ ctx.fillStyle = histogramColors[`${direction}Bright`];
31
+ }
32
+ // histogram cap
33
+ const baseX = visualCandle.xStart(model.view);
34
+ const closeY = floorToDPR(model.view.toY(visualCandle.close));
35
+ const width = floorToDPR(model.view.xPixels(visualCandle.width));
36
+ ctx.fillRect(baseX, closeY, width, capHeight);
37
+ // the bar itself
38
+ const gradient = ctx.createLinearGradient(0, closeY + capHeight, 0, bottomY);
39
+ if (drawerConfig.singleColor) {
40
+ ctx.fillStyle = drawerConfig.singleColor;
41
+ }
42
+ else {
43
+ gradient.addColorStop(0, histogramColors[`${direction}Cap`]);
44
+ gradient.addColorStop(1, histogramColors[`${direction}Bottom`]);
45
+ ctx.fillStyle = gradient;
46
+ }
47
+ if (width === 0) {
48
+ // just draw a vertical line
49
+ ctx.beginPath();
50
+ ctx.strokeStyle = gradient;
51
+ ctx.moveTo(baseX, closeY + capHeight);
52
+ ctx.lineTo(baseX, bottomY);
53
+ ctx.stroke();
54
+ ctx.closePath();
55
+ }
56
+ else {
57
+ ctx.fillRect(baseX, closeY + capHeight, width, bottomY - closeY - capHeight);
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
@@ -3,4 +3,41 @@
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{CandleSeriesModel as g}from"../../model/candle-series.model";import{setLineWidth as C}from"../data-series.drawer";import{flat as T}from"../../utils/array.utils";export class LineDrawer{constructor(o){this.config=o}draw(o,r,t,e){if(t instanceof g){const n=T(r);C(o,this.config.lineWidth,t,e,this.config.selectedWidth);const c=t.colors.lineTheme;o.lineCap="round",e.singleColor&&(o.strokeStyle=e.singleColor);for(let i=1;i<n.length;i++){const l=n[i-1],s=n[i],h=s.name;e.singleColor||(o.strokeStyle=c[`${h}Color`]);const m=t.view.toX(l.centerUnit),v=t.view.toY(l.close),f=t.view.toX(s.centerUnit),p=t.view.toY(s.close);o.beginPath(),o.moveTo(m,v),o.lineTo(f,p),o.stroke()}}}}
6
+ import { CandleSeriesModel } from '../../model/candle-series.model';
7
+ import { setLineWidth } from '../data-series.drawer';
8
+ import { flat } from '../../utils/array.utils';
9
+ export class LineDrawer {
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ draw(ctx, points, candleSeries, drawerConfig) {
14
+ if (candleSeries instanceof CandleSeriesModel) {
15
+ // @ts-ignore
16
+ const visualCandles = flat(points);
17
+ // TODO rework, make sure drawing is precise
18
+ setLineWidth(ctx, this.config.lineWidth, candleSeries, drawerConfig, this.config.selectedWidth);
19
+ const lineTheme = candleSeries.colors.lineTheme;
20
+ // make style changes outside loop to improve performance
21
+ ctx.lineCap = 'round';
22
+ if (drawerConfig.singleColor) {
23
+ ctx.strokeStyle = drawerConfig.singleColor;
24
+ }
25
+ for (let i = 1; i < visualCandles.length; i++) {
26
+ const prev = visualCandles[i - 1];
27
+ const vc = visualCandles[i];
28
+ const direction = vc.name;
29
+ if (!drawerConfig.singleColor) {
30
+ ctx.strokeStyle = lineTheme[`${direction}Color`];
31
+ }
32
+ const prevX = candleSeries.view.toX(prev.centerUnit);
33
+ const prevY = candleSeries.view.toY(prev.close);
34
+ const x = candleSeries.view.toX(vc.centerUnit);
35
+ const y = candleSeries.view.toY(vc.close);
36
+ ctx.beginPath();
37
+ ctx.moveTo(prevX, prevY);
38
+ ctx.lineTo(x, y);
39
+ ctx.stroke();
40
+ }
41
+ }
42
+ }
43
+ }
@@ -3,4 +3,22 @@
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{flat as c}from"../../utils/array.utils";import{floorToDPR as i}from"../../utils/device/device-pixel-ratio.utils";const f=1.5;export class ScatterPlotDrawer{constructor(o){this.config=o}draw(o,n,r,e){var t;o.fillStyle=(t=e.singleColor)!==null&&t!==void 0?t:this.config.mainColor;for(const l of c(n)){o.beginPath();const a=i(r.view.toX(l.centerUnit)),s=i(r.view.toY(l.close));o.arc(a,s,f,0,Math.PI*2,!0),o.fill()}}}
6
+ import { flat } from '../../utils/array.utils';
7
+ import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
8
+ const SCATTER_PLOT_RADIUS = 1.5;
9
+ export class ScatterPlotDrawer {
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ draw(ctx, points, model, drawerConfig) {
14
+ var _a;
15
+ ctx.fillStyle = (_a = drawerConfig.singleColor) !== null && _a !== void 0 ? _a : this.config.mainColor;
16
+ for (const visualCandle of flat(points)) {
17
+ ctx.beginPath();
18
+ const lineX = floorToDPR(model.view.toX(visualCandle.centerUnit));
19
+ const closeY = floorToDPR(model.view.toY(visualCandle.close));
20
+ ctx.arc(lineX, closeY, SCATTER_PLOT_RADIUS, 0, Math.PI * 2, true);
21
+ ctx.fill();
22
+ }
23
+ }
24
+ }
@@ -3,4 +3,17 @@
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
- export class ClearCanvasDrawer{constructor(a){this.canvasModel=a}draw(){this.canvasModel.clear()}getCanvasIds(){return[this.canvasModel.canvasId]}}
6
+ /**
7
+ * Clears the canvas.
8
+ */
9
+ export class ClearCanvasDrawer {
10
+ constructor(canvasModel) {
11
+ this.canvasModel = canvasModel;
12
+ }
13
+ draw() {
14
+ this.canvasModel.clear();
15
+ }
16
+ getCanvasIds() {
17
+ return [this.canvasModel.canvasId];
18
+ }
19
+ }
@@ -3,4 +3,70 @@
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{findKeyFromValue as t}from"../utils/object.utils";import{flat as a}from"../utils/array.utils";export class CompositeDrawer{constructor(r){this.drawers=r!=null?r:new Map}draw(){this.drawers.forEach(r=>r.draw())}addDrawer(r,e){const s=e!=null?e:"drawer"+this.drawers.size;this.drawers.set(s,r)}drawLastBar(){this.drawers.forEach(r=>r.drawLastBar&&r.drawLastBar())}removeDrawer(r){const e=t(this.drawers,r);e?this.drawers.delete(e):console.warn("Couldn't find drawer type")}removeDrawerByName(r){this.drawers.delete(r)}getDrawer(r){return this.drawers.get(r)}moveTop(r){const e=t(this.drawers,r);e?this.moveTopByName(e):console.warn("Couldn't find drawer type")}moveTopByName(r){if(this.drawers.size===1)return;const e=this.drawers.get(r);this.drawers.delete(r),e&&this.drawers.set(r,e)}getSize(){return this.drawers.size}getAll(){return this.drawers}getCanvasIds(){const r=a(Array.from(this.drawers).map(([,s])=>s.getCanvasIds())),e=new Set([...r]);return Array.from(e)}}
6
+ import { findKeyFromValue } from '../utils/object.utils';
7
+ import { flat } from '../utils/array.utils';
8
+ /**
9
+ * Container for grouping multiple drawers.
10
+ * Try to keep simple, not overkill with sorting.
11
+ */
12
+ export class CompositeDrawer {
13
+ constructor(drawers) {
14
+ this.drawers = drawers !== null && drawers !== void 0 ? drawers : new Map();
15
+ }
16
+ draw() {
17
+ this.drawers.forEach(d => d.draw());
18
+ }
19
+ addDrawer(drawer, drawerName) {
20
+ const name = drawerName !== null && drawerName !== void 0 ? drawerName : 'drawer' + this.drawers.size;
21
+ this.drawers.set(name, drawer);
22
+ }
23
+ // TODO rework, move to specific candle composite drawer maybe
24
+ drawLastBar() {
25
+ this.drawers.forEach(d => d.drawLastBar && d.drawLastBar());
26
+ }
27
+ removeDrawer(drawer) {
28
+ const name = findKeyFromValue(this.drawers, drawer);
29
+ if (name) {
30
+ this.drawers.delete(name);
31
+ }
32
+ else {
33
+ console.warn(`Couldn't find drawer type`);
34
+ }
35
+ }
36
+ removeDrawerByName(drawerName) {
37
+ this.drawers.delete(drawerName);
38
+ }
39
+ getDrawer(drawerName) {
40
+ return this.drawers.get(drawerName);
41
+ }
42
+ moveTop(drawer) {
43
+ const name = findKeyFromValue(this.drawers, drawer);
44
+ if (name) {
45
+ this.moveTopByName(name);
46
+ }
47
+ else {
48
+ console.warn(`Couldn't find drawer type`);
49
+ }
50
+ }
51
+ moveTopByName(drawerName) {
52
+ if (this.drawers.size === 1) {
53
+ return;
54
+ }
55
+ const drawerInMap = this.drawers.get(drawerName);
56
+ this.drawers.delete(drawerName);
57
+ if (drawerInMap) {
58
+ this.drawers.set(drawerName, drawerInMap);
59
+ }
60
+ }
61
+ getSize() {
62
+ return this.drawers.size;
63
+ }
64
+ getAll() {
65
+ return this.drawers;
66
+ }
67
+ getCanvasIds() {
68
+ const canvasIds = flat(Array.from(this.drawers).map(([, d]) => d.getCanvasIds()));
69
+ const distinctedCanvasIds = new Set([...canvasIds]);
70
+ return Array.from(distinctedCanvasIds);
71
+ }
72
+ }
@@ -3,4 +3,53 @@
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{clipToBounds as a}from"../data-series.drawer";export const candleTypesList=["candle","bar","line","area","scatterPlot","hollow","histogram","baseline","trend"];export class CandleSeriesWrapper{constructor(e,r,s){this.drawer=e,this.config=r,this.chartBounds=s}draw(e,r,s,t){this.isChartTypeAllowed()&&(this.beforeDraw(e),this.drawer.draw(e,r,s,t),this.afterDraw(e,s))}beforeDraw(e){e.restore(),e.save(),a(e,this.chartBounds())}isChartTypeAllowed(){return candleTypesList.includes(this.config.components.chart.type)}afterDraw(e,r){e.restore(),e.save(),a(e,r.scaleModel.getBounds())}}
6
+ import { clipToBounds } from '../data-series.drawer';
7
+ export const candleTypesList = [
8
+ 'candle',
9
+ 'bar',
10
+ 'line',
11
+ 'area',
12
+ 'scatterPlot',
13
+ 'hollow',
14
+ 'histogram',
15
+ 'baseline',
16
+ 'trend',
17
+ ];
18
+ /**
19
+ * A decorator for drawers, that draw something depending on visual candles
20
+ */
21
+ export class CandleSeriesWrapper {
22
+ constructor(drawer, config, chartBounds) {
23
+ this.drawer = drawer;
24
+ this.config = config;
25
+ this.chartBounds = chartBounds;
26
+ }
27
+ draw(ctx, allPoints, model, config) {
28
+ if (this.isChartTypeAllowed()) {
29
+ this.beforeDraw(ctx);
30
+ this.drawer.draw(ctx, allPoints, model, config);
31
+ this.afterDraw(ctx, model);
32
+ }
33
+ }
34
+ beforeDraw(ctx) {
35
+ // by default we have clip to study underlay area if study is underlying
36
+ // remove clip if study is underlying, because we need to color candles on main chart
37
+ // in the end we have to restore original clip
38
+ // if (!studySeries.overlaying) {
39
+ ctx.restore();
40
+ ctx.save();
41
+ clipToBounds(ctx, this.chartBounds());
42
+ // }
43
+ }
44
+ isChartTypeAllowed() {
45
+ return candleTypesList.includes(this.config.components.chart.type);
46
+ }
47
+ afterDraw(ctx, model) {
48
+ // restore previous clip
49
+ // if (!studySeries.overlaying) {
50
+ ctx.restore();
51
+ ctx.save();
52
+ clipToBounds(ctx, model.scale.getBounds());
53
+ // }
54
+ }
55
+ }
@@ -3,4 +3,38 @@
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{unitToPixels as b}from"../../model/scaling/viewport.model";import{floorToDPR as l}from"../../utils/device/device-pixel-ratio.utils";import{round as v}from"../../utils/math.utils";export class ColorCandleDrawer{constructor(t){this.chartModel=t}draw(t,d,s,i){d.forEach((r,h)=>{var e;const f=s.getPaintConfig(h);t.fillStyle=(e=i.singleColor)!==null&&e!==void 0?e:f.color,r.forEach(n=>{const o=this.chartModel.getVisualCandle(v(n.centerUnit)),g=n.close;if(o&&g===1){const M=this.chartModel.scaleModel.zoomX,c=l(b(o.width,M)),m=l(o.bodyHeight(this.chartModel.scaleModel)),p=o.xCenter(this.chartModel.scaleModel)-c/2,u=o.yBodyStart(this.chartModel.scaleModel),C=this.chartModel.config.components.chart.candlePaddingPercent,a=l(c*C/2),y=p+a,P=c-a*2;t.fillRect(y,u,P,m)}})})}}
6
+ import { unitToPixels } from '../../model/scaling/viewport.model';
7
+ import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
8
+ import { round } from '../../utils/math.utils';
9
+ /**
10
+ * Some series have candles which are highlighted.
11
+ * This drawer draws the candle box on top of original candles.
12
+ */
13
+ export class ColorCandleDrawer {
14
+ constructor(chartModel) {
15
+ this.chartModel = chartModel;
16
+ }
17
+ draw(ctx, allPoints, model, drawerConfig) {
18
+ allPoints.forEach((points, idx) => {
19
+ var _a;
20
+ const config = model.getPaintConfig(idx);
21
+ ctx.fillStyle = (_a = drawerConfig.singleColor) !== null && _a !== void 0 ? _a : config.color;
22
+ points.forEach(p => {
23
+ const visualCandle = this.chartModel.getVisualCandle(round(p.centerUnit));
24
+ const value = p.close;
25
+ if (visualCandle && value === 1) {
26
+ const zoomX = this.chartModel.scale.zoomX;
27
+ const width = floorToDPR(unitToPixels(visualCandle.width, zoomX));
28
+ const bodyH = floorToDPR(visualCandle.bodyHeight(this.chartModel.scale));
29
+ const baseX = visualCandle.xCenter(this.chartModel.scale) - width / 2;
30
+ const bodyStart = visualCandle.yBodyStart(this.chartModel.scale);
31
+ const paddingPercent = this.chartModel.config.components.chart.candlePaddingPercent;
32
+ const paddingWidthOffset = floorToDPR((width * paddingPercent) / 2);
33
+ const paddingBaseX = baseX + paddingWidthOffset;
34
+ const paddingWidth = width - paddingWidthOffset * 2;
35
+ ctx.fillRect(paddingBaseX, bodyStart, paddingWidth, bodyH);
36
+ }
37
+ });
38
+ });
39
+ }
40
+ }
@@ -3,4 +3,19 @@
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
- export const buildLinePath=(o,e,t)=>{o.length!==0&&o.forEach((l,s)=>{const{centerUnit:i,close:f}=l,n=t.toX(i),c=t.toY(f);s===0?e.moveTo(n,c):e.lineTo(n,c)})};
6
+ export const buildLinePath = (points, ctx, view) => {
7
+ if (points.length !== 0) {
8
+ // Recognizing line gaps by candles idx.
9
+ points.forEach((p, idx) => {
10
+ const { centerUnit, close } = p;
11
+ const x = view.toX(centerUnit);
12
+ const y = view.toY(close);
13
+ if (idx === 0) {
14
+ ctx.moveTo(x, y);
15
+ }
16
+ else {
17
+ ctx.lineTo(x, y);
18
+ }
19
+ });
20
+ }
21
+ };
@@ -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{setLineWidth as C}from"../data-series.drawer";import{buildLinePath as y}from"./data-series-drawers.utils";import{firstOf as D,lastOf as b}from"../../utils/array.utils";import{toRGBA as m}from"../../utils/color.utils";export class DifferenceCloudDrawer{constructor(){}draw(o,r,e,a){e.config.visible&&(r.forEach((i,l)=>{var s;const n=e.getPaintConfig(l);C(o,n.lineWidth,e,a,n.hoveredLineWidth);const f=(s=a.singleColor)!==null&&s!==void 0?s:n.color;o.strokeStyle=f,this.drawLine(o,i,e.view)}),e.linkedDataSeriesModels.forEach((i,l)=>{if(isDifferenceTool(i.config.type)&&isDifferenceTool(e.config.type)&&i.config.visible){const s=[],n=e,f=n.getSeriesInViewport(n.scaleModel.xStart-1,n.scaleModel.xEnd+1),c=i.getSeriesInViewport(i.scaleModel.xStart-1,i.scaleModel.xEnd+1);f.forEach((h,t)=>{const u=Math.min(h.length,c[t].length);for(let g=0;g<u;g++){const p=[h[g].clone(),c[t][g].clone()];s.push({diffPoints:p})}const v=n.getPaintConfig(t).color,E=i.getPaintConfig(l).color;this.drawDifference(o,v,E,s,n,i,a)})}}))}drawLine(o,r,e){o.beginPath(),y(r,o,e),o.stroke()}drawDifference(o,r,e,a,i,l,s){const[n,f]=[[],[]];a.forEach(t=>{const[u,v]=t.diffPoints;n.push(u),f.push(v)});const c=d(n,i.view),h=d(f,l.view);this.fillCloud(o,e,c,h,s),this.fillCloud(o,r,h,c,s)}fillCloud(o,r,e,a,i){var l,s,n,f;o.save(),o.beginPath();const c=(s=(l=D(e))===null||l===void 0?void 0:l.x)!==null&&s!==void 0?s:0,h=(f=(n=b(e))===null||n===void 0?void 0:n.x)!==null&&f!==void 0?f:0;o.lineTo(c,0),e.forEach(t=>{o.lineTo(t.x,t.y)}),o.lineTo(h,0),o.closePath(),o.clip(),o.beginPath(),e.forEach((t,u)=>{u===0?o.moveTo(t.x,t.y):o.lineTo(t.x,t.y)}),a.slice().reverse().forEach(t=>{o.lineTo(t.x,t.y)}),o.closePath(),o.fillStyle=i.singleColor?i.singleColor:m(r||"#383838",.3),o.fill(),o.restore()}}const d=(P,o)=>P.map(r=>{const{centerUnit:e,close:a}=r,i=o.toX(e),l=o.toY(a);return{x:i,y:l}});export const isDifferenceTool=P=>P==="DIFFERENCE";
6
+ import { setLineWidth } from '../data-series.drawer';
7
+ import { buildLinePath } from './data-series-drawers.utils';
8
+ import { firstOf, lastOf } from '../../utils/array.utils';
9
+ import { toRGBA } from '../../utils/color.utils';
10
+ export class DifferenceCloudDrawer {
11
+ constructor() { }
12
+ draw(ctx, allPoints, model, drawerConfig) {
13
+ if (model.config.visible) {
14
+ // draw main line
15
+ allPoints.forEach((points, idx) => {
16
+ var _a;
17
+ const config = model.getPaintConfig(idx);
18
+ setLineWidth(ctx, config.lineWidth, model, drawerConfig, config.hoveredLineWidth);
19
+ const lineColor = (_a = drawerConfig.singleColor) !== null && _a !== void 0 ? _a : config.color;
20
+ ctx.strokeStyle = lineColor;
21
+ this.drawLine(ctx, points, model.view);
22
+ });
23
+ // draw difference cloud
24
+ model.linkedDataSeriesModels.forEach((linkedSeries, linkedSeriesIdx) => {
25
+ if (isDifferenceTool(linkedSeries.config.type) &&
26
+ isDifferenceTool(model.config.type) &&
27
+ linkedSeries.config.visible) {
28
+ const differencePoints = [];
29
+ const mainSeries = model;
30
+ const allPointsMain = mainSeries.getSeriesInViewport(mainSeries.scale.xStart - 1, mainSeries.scale.xEnd + 1);
31
+ const allPointsLinked = linkedSeries.getSeriesInViewport(linkedSeries.scale.xStart - 1, linkedSeries.scale.xEnd + 1);
32
+ allPointsMain.forEach((points, idx) => {
33
+ const to = Math.min(points.length, allPointsLinked[idx].length);
34
+ for (let k = 0; k < to; k++) {
35
+ const diffPoints = [
36
+ points[k].clone(),
37
+ allPointsLinked[idx][k].clone(),
38
+ ];
39
+ differencePoints.push({
40
+ diffPoints,
41
+ });
42
+ }
43
+ const curSeriesColor = mainSeries.getPaintConfig(idx).color;
44
+ const nextSeriesColor = linkedSeries.getPaintConfig(linkedSeriesIdx).color;
45
+ this.drawDifference(ctx, curSeriesColor, nextSeriesColor, differencePoints, mainSeries, linkedSeries, drawerConfig);
46
+ });
47
+ }
48
+ });
49
+ }
50
+ }
51
+ drawLine(ctx, points, view) {
52
+ ctx.beginPath();
53
+ buildLinePath(points, ctx, view);
54
+ ctx.stroke();
55
+ }
56
+ drawDifference(ctx, lineColor, nextLineColor, diffPoints, curSeries, nextSeries, drawerConfig) {
57
+ const [linePoints, nextLinePoints] = [[], []];
58
+ diffPoints.forEach(points => {
59
+ const [point, nextPoint] = points.diffPoints;
60
+ linePoints.push(point);
61
+ nextLinePoints.push(nextPoint);
62
+ });
63
+ const curSeriesPoints = mapDataSeriesDiffPointsIntoPoints(linePoints, curSeries.view);
64
+ const nextSeriesPoints = mapDataSeriesDiffPointsIntoPoints(nextLinePoints, nextSeries.view);
65
+ this.fillCloud(ctx, nextLineColor, curSeriesPoints, nextSeriesPoints, drawerConfig);
66
+ this.fillCloud(ctx, lineColor, nextSeriesPoints, curSeriesPoints, drawerConfig);
67
+ }
68
+ fillCloud(ctx, color, linePoints, nextLinePoints, drawerConfig) {
69
+ var _a, _b, _c, _d;
70
+ ctx.save();
71
+ // clip above lowerLine
72
+ ctx.beginPath();
73
+ const firstX = (_b = (_a = firstOf(linePoints)) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0;
74
+ const lastX = (_d = (_c = lastOf(linePoints)) === null || _c === void 0 ? void 0 : _c.x) !== null && _d !== void 0 ? _d : 0;
75
+ ctx.lineTo(firstX, 0);
76
+ linePoints.forEach(p => {
77
+ ctx.lineTo(p.x, p.y);
78
+ });
79
+ ctx.lineTo(lastX, 0);
80
+ ctx.closePath();
81
+ ctx.clip();
82
+ ctx.beginPath();
83
+ linePoints.forEach((p, idx) => {
84
+ if (idx === 0) {
85
+ ctx.moveTo(p.x, p.y);
86
+ }
87
+ else {
88
+ ctx.lineTo(p.x, p.y);
89
+ }
90
+ });
91
+ nextLinePoints
92
+ .slice()
93
+ .reverse()
94
+ .forEach(p => {
95
+ ctx.lineTo(p.x, p.y);
96
+ });
97
+ ctx.closePath();
98
+ ctx.fillStyle = drawerConfig.singleColor ? drawerConfig.singleColor : toRGBA(color ? color : '#383838', 0.3);
99
+ ctx.fill();
100
+ ctx.restore();
101
+ }
102
+ }
103
+ const mapDataSeriesDiffPointsIntoPoints = (points, view) => {
104
+ return points.map(p => {
105
+ const { centerUnit, close } = p;
106
+ const x = view.toX(centerUnit);
107
+ const y = view.toY(close);
108
+ return { x, y };
109
+ });
110
+ };
111
+ export const isDifferenceTool = (type) => type === 'DIFFERENCE';
@@ -3,4 +3,26 @@
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{floor as a}from"../../utils/math.utils";import{setLineWidth as g}from"../data-series.drawer";export class HistogramDrawer{constructor(){}draw(o,c,r,e){const h=r.view.toY(0);c.forEach((l,v)=>{var t;const i=r.getPaintConfig(v);g(o,i.lineWidth,r,e,i.hoveredLineWidth),o.strokeStyle=(t=e.singleColor)!==null&&t!==void 0?t:i.color,o.beginPath(),l.forEach(n=>{const s=r.view.toX(n.centerUnit),f=r.view.toY(n.close);o.moveTo(s,a(h)),o.lineTo(s,a(f))}),o.stroke()})}}
6
+ import { floor } from '../../utils/math.utils';
7
+ import { setLineWidth } from '../data-series.drawer';
8
+ export class HistogramDrawer {
9
+ constructor() { }
10
+ draw(ctx, allPoints, model, drawerConfig) {
11
+ const zero = model.view.toY(0);
12
+ allPoints.forEach((points, idx) => {
13
+ var _a;
14
+ // odd width is crucial to draw histogram without antialiasing
15
+ const config = model.getPaintConfig(idx);
16
+ setLineWidth(ctx, config.lineWidth, model, drawerConfig, config.hoveredLineWidth);
17
+ ctx.strokeStyle = (_a = drawerConfig.singleColor) !== null && _a !== void 0 ? _a : config.color;
18
+ ctx.beginPath();
19
+ points.forEach(p => {
20
+ const x = model.view.toX(p.centerUnit);
21
+ const y = model.view.toY(p.close);
22
+ ctx.moveTo(x, floor(zero));
23
+ ctx.lineTo(x, floor(y));
24
+ });
25
+ ctx.stroke();
26
+ });
27
+ }
28
+ }