@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.
- package/README.md +2 -2
- package/dist/chart/animation/canvas-animation.js +134 -1
- package/dist/chart/animation/types/animation.js +43 -1
- package/dist/chart/animation/types/color-alpha-animation.d.ts +1 -1
- package/dist/chart/animation/types/color-alpha-animation.js +60 -1
- package/dist/chart/animation/types/color-transition-animation.d.ts +1 -1
- package/dist/chart/animation/types/color-transition-animation.js +86 -1
- package/dist/chart/animation/types/viewport-movement-animation.js +63 -1
- package/dist/chart/animation/viewport-model-animation.js +20 -1
- package/dist/chart/bootstrap.d.ts +51 -48
- package/dist/chart/bootstrap.js +449 -1
- package/dist/chart/canvas/canvas-bounds-container.d.ts +0 -5
- package/dist/chart/canvas/canvas-bounds-container.js +815 -1
- package/dist/chart/canvas/canvas-chart-html.js +16 -18
- package/dist/chart/canvas/chart-elements.d.ts +1 -4
- package/dist/chart/canvas/chart-elements.js +22 -1
- package/dist/chart/canvas/cursor.handler.js +122 -1
- package/dist/chart/canvas/layout-creator.js +34 -1
- package/dist/chart/canvas/y-axis-bounds.container.d.ts +2 -2
- package/dist/chart/canvas/y-axis-bounds.container.js +67 -1
- package/dist/chart/chart-container.js +1 -1
- package/dist/chart/chart.config.d.ts +4 -5
- package/dist/chart/chart.config.js +645 -1
- package/dist/chart/chart.d.ts +62 -0
- package/dist/chart/chart.js +106 -0
- package/dist/chart/components/chart/basic-scale.d.ts +2 -2
- package/dist/chart/components/chart/basic-scale.js +31 -1
- package/dist/chart/components/chart/candle-transformer.functions.js +15 -1
- package/dist/chart/components/chart/candle-width-calculator.functions.js +2 -1
- package/dist/chart/components/chart/candle.functions.js +44 -1
- package/dist/chart/components/chart/chart-area-pan.handler.d.ts +3 -3
- package/dist/chart/components/chart/chart-area-pan.handler.js +197 -1
- package/dist/chart/components/chart/chart-base.model.js +66 -1
- package/dist/chart/components/chart/chart.component.d.ts +7 -3
- package/dist/chart/components/chart/chart.component.js +408 -1
- package/dist/chart/components/chart/chart.model.d.ts +4 -11
- package/dist/chart/components/chart/chart.model.js +954 -1
- package/dist/chart/components/chart/data-series.high-low-provider.js +34 -1
- package/dist/chart/components/chart/fake-candles.js +97 -1
- package/dist/chart/components/chart/price.formatter.js +35 -1
- package/dist/chart/components/chart/secondary-chart-colors-pool.js +68 -1
- package/dist/chart/components/cross_tool/cross-tool.component.js +85 -1
- package/dist/chart/components/cross_tool/cross-tool.drawer.js +32 -1
- package/dist/chart/components/cross_tool/cross-tool.model.js +107 -1
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +137 -1
- package/dist/chart/components/cross_tool/types/none.drawer.js +3 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-x.component.js +28 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-y.component.js +24 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop.component.js +53 -1
- package/dist/chart/components/dynamic-objects/dynamic-objects.component.d.ts +13 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.component.js +20 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.drawer.d.ts +18 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.drawer.js +23 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.d.ts +63 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.js +136 -0
- package/dist/chart/components/events/events-hit-test.drawer.js +63 -1
- package/dist/chart/components/events/events.component.js +61 -1
- package/dist/chart/components/events/events.drawer.js +195 -1
- package/dist/chart/components/events/events.model.js +69 -1
- package/dist/chart/components/grid/grid.component.d.ts +2 -2
- package/dist/chart/components/grid/grid.component.js +31 -1
- package/dist/chart/components/grid/grid.drawer.d.ts +4 -3
- package/dist/chart/components/grid/grid.drawer.js +106 -1
- package/dist/chart/components/high_low/high-low.component.js +12 -1
- package/dist/chart/components/high_low/high-low.drawer.js +126 -1
- package/dist/chart/components/highlights/highlights.component.js +46 -1
- package/dist/chart/components/highlights/highlights.drawer.js +154 -1
- package/dist/chart/components/highlights/highlights.model.js +75 -1
- package/dist/chart/components/labels_generator/numeric-axis-labels.generator.d.ts +1 -1
- package/dist/chart/components/labels_generator/numeric-axis-labels.generator.js +199 -1
- package/dist/chart/components/navigation_map/navigation-map-move.handler.d.ts +2 -2
- package/dist/chart/components/navigation_map/navigation-map-move.handler.js +108 -1
- package/dist/chart/components/navigation_map/navigation-map.component.js +112 -1
- package/dist/chart/components/navigation_map/navigation-map.drawer.js +244 -1
- package/dist/chart/components/navigation_map/navigation-map.model.js +33 -2
- package/dist/chart/components/pan/chart-pan.component.d.ts +2 -2
- package/dist/chart/components/pan/chart-pan.component.js +51 -1
- package/dist/chart/components/pane/extent/y-extent-component.d.ts +12 -18
- package/dist/chart/components/pane/extent/y-extent-component.js +120 -1
- package/dist/chart/components/pane/pane-hit-test.controller.d.ts +2 -2
- package/dist/chart/components/pane/pane-hit-test.controller.js +55 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +12 -6
- package/dist/chart/components/pane/pane-manager.component.js +149 -1
- package/dist/chart/components/pane/pane.component.d.ts +16 -32
- package/dist/chart/components/pane/pane.component.js +278 -1
- package/dist/chart/components/resizer/bar-resizer.component.js +139 -1
- package/dist/chart/components/resizer/bar-resizer.drawer.js +46 -1
- package/dist/chart/components/snapshot/snapshot.component.js +48 -1
- package/dist/chart/components/volumes/separate-volumes.component.d.ts +6 -10
- package/dist/chart/components/volumes/separate-volumes.component.js +63 -1
- package/dist/chart/components/volumes/volume-color-resolvers.functions.js +18 -1
- package/dist/chart/components/volumes/volumes.component.d.ts +6 -7
- package/dist/chart/components/volumes/volumes.component.js +94 -1
- package/dist/chart/components/volumes/volumes.drawer.d.ts +5 -12
- package/dist/chart/components/volumes/volumes.drawer.js +140 -1
- package/dist/chart/components/volumes/volumes.formatter.js +31 -1
- package/dist/chart/components/volumes/volumes.model.d.ts +2 -2
- package/dist/chart/components/volumes/volumes.model.js +43 -1
- package/dist/chart/components/watermark/water-mark.component.js +103 -1
- package/dist/chart/components/watermark/water-mark.drawer.js +187 -1
- package/dist/chart/components/x_axis/numeric-x-axis-labels.generator.js +27 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-matchers.functions.js +187 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-parser.functions.js +76 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-validators.functions.js +79 -1
- package/dist/chart/components/x_axis/time/parser/time-formats.model.js +14 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.functions.d.ts +1 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.functions.js +143 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.generator.js +73 -1
- package/dist/chart/components/x_axis/x-axis-draw.functions.js +49 -1
- package/dist/chart/components/x_axis/x-axis-labels.drawer.js +70 -1
- package/dist/chart/components/x_axis/x-axis-labels.generator.d.ts +2 -2
- package/dist/chart/components/x_axis/x-axis-labels.generator.js +332 -1
- package/dist/chart/components/x_axis/x-axis-labels.model.js +35 -1
- package/dist/chart/components/x_axis/x-axis-scale.handler.d.ts +2 -2
- package/dist/chart/components/x_axis/x-axis-scale.handler.js +60 -1
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +82 -1
- package/dist/chart/components/x_axis/x-axis.component.d.ts +2 -2
- package/dist/chart/components/x_axis/x-axis.component.js +119 -1
- package/dist/chart/components/y_axis/label-color.functions.js +53 -1
- package/dist/chart/components/y_axis/numeric-y-axis-labels.generator.d.ts +4 -4
- package/dist/chart/components/y_axis/numeric-y-axis-labels.generator.js +33 -1
- package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.d.ts +3 -3
- package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.js +67 -1
- package/dist/chart/components/y_axis/price_labels/labels-positions-calculator.js +56 -1
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.d.ts +4 -3
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +96 -1
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.d.ts +2 -2
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +119 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.d.ts +9 -8
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +201 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.d.ts +6 -7
- package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.js +58 -1
- package/dist/chart/components/y_axis/y-axis-base-labels.model.d.ts +6 -4
- package/dist/chart/components/y_axis/y-axis-base-labels.model.js +47 -1
- package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +4 -4
- package/dist/chart/components/y_axis/y-axis-labels.drawer.js +161 -1
- package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +2 -2
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +72 -1
- package/dist/chart/components/y_axis/y-axis.component.d.ts +32 -41
- package/dist/chart/components/y_axis/y-axis.component.js +220 -1
- package/dist/chart/components/y_axis/y-axis.drawer.d.ts +9 -12
- package/dist/chart/components/y_axis/y-axis.drawer.js +96 -1
- package/dist/chart/components/y_axis/y-axis.model.d.ts +10 -17
- package/dist/chart/components/y_axis/y-axis.model.js +34 -1
- package/dist/chart/drawers/chart-background.drawer.js +69 -1
- package/dist/chart/drawers/chart-type-drawers/area.drawer.js +69 -1
- package/dist/chart/drawers/chart-type-drawers/bar.drawer.js +57 -1
- package/dist/chart/drawers/chart-type-drawers/baseline.drawer.js +84 -1
- package/dist/chart/drawers/chart-type-drawers/candle.drawer.js +162 -1
- package/dist/chart/drawers/chart-type-drawers/histogram.drawer.js +57 -1
- package/dist/chart/drawers/chart-type-drawers/line.drawer.js +38 -1
- package/dist/chart/drawers/chart-type-drawers/scatter-plot.drawer.js +19 -1
- package/dist/chart/drawers/clear-canvas.drawer.js +14 -1
- package/dist/chart/drawers/composite.drawer.js +67 -1
- package/dist/chart/drawers/data-series-drawers/candle-series-wrapper.js +50 -1
- package/dist/chart/drawers/data-series-drawers/color-candle.drawer.js +35 -1
- package/dist/chart/drawers/data-series-drawers/data-series-drawers.utils.js +16 -1
- package/dist/chart/drawers/data-series-drawers/difference-cloud.drawer.js +106 -1
- package/dist/chart/drawers/data-series-drawers/histogram.drawer.js +23 -1
- package/dist/chart/drawers/data-series-drawers/linear.drawer.js +19 -1
- package/dist/chart/drawers/data-series-drawers/points.drawer.js +19 -1
- package/dist/chart/drawers/data-series-drawers/rectangular-tool.drawer.js +7 -1
- package/dist/chart/drawers/data-series-drawers/text.drawer.js +25 -1
- package/dist/chart/drawers/data-series-drawers/trend-histogram.drawer.js +35 -1
- package/dist/chart/drawers/data-series-drawers/triangle.drawer.js +22 -1
- package/dist/chart/drawers/data-series.drawer.d.ts +5 -7
- package/dist/chart/drawers/data-series.drawer.js +56 -1
- package/dist/chart/drawers/drawing-manager.d.ts +1 -1
- package/dist/chart/drawers/drawing-manager.js +177 -1
- package/dist/chart/drawers/ht-data-series.drawer.js +37 -1
- package/dist/chart/events/event-bus.js +73 -1
- package/dist/chart/events/events.js +3 -1
- package/dist/chart/inputhandlers/candle-tap.handler.js +46 -1
- package/dist/chart/inputhandlers/chart-resize.handler.js +98 -1
- package/dist/chart/inputhandlers/cross-event-producer.component.js +67 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +2 -2
- package/dist/chart/inputhandlers/hover-producer.component.js +228 -1
- package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +2 -2
- package/dist/chart/inputhandlers/main-canvas-touch.handler.js +80 -1
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +629 -1
- package/dist/chart/model/baseline.model.js +88 -1
- package/dist/chart/model/bounds.model.js +1 -1
- package/dist/chart/model/candle-hover.js +70 -1
- package/dist/chart/model/candle-series-high-low.provider.js +45 -1
- package/dist/chart/model/candle-series.model.d.ts +3 -3
- package/dist/chart/model/candle-series.model.js +245 -1
- package/dist/chart/model/candle.model.js +69 -1
- package/dist/chart/model/canvas.model.js +228 -1
- package/dist/chart/model/chart-base-element.js +129 -1
- package/dist/chart/model/compare-series-hover.js +25 -1
- package/dist/chart/model/data-series-view.d.ts +5 -5
- package/dist/chart/model/data-series-view.js +111 -1
- package/dist/chart/model/data-series.config.js +14 -1
- package/dist/chart/model/data-series.model.d.ts +4 -4
- package/dist/chart/model/data-series.model.js +281 -1
- package/dist/chart/model/date-time.formatter.js +151 -1
- package/dist/chart/model/hit-test-canvas.model.d.ts +1 -1
- package/dist/chart/model/hit-test-canvas.model.js +256 -1
- package/dist/chart/model/main-candle-series.model.d.ts +1 -1
- package/dist/chart/model/main-candle-series.model.js +29 -1
- package/dist/chart/model/scale.model.d.ts +3 -2
- package/dist/chart/model/scale.model.js +316 -1
- package/dist/chart/model/scaling/auto-scale.model.d.ts +2 -4
- package/dist/chart/model/scaling/auto-scale.model.js +91 -1
- package/dist/chart/model/scaling/constrait.functions.js +61 -1
- package/dist/chart/model/scaling/lock-ratio.model.js +17 -1
- package/dist/chart/model/scaling/move-chart.functions.js +22 -1
- package/dist/chart/model/scaling/viewport.model.d.ts +2 -2
- package/dist/chart/model/scaling/viewport.model.js +279 -1
- package/dist/chart/model/scaling/x-zooming.functions.js +35 -1
- package/dist/chart/model/time-zone.model.js +109 -1
- package/dist/chart/model/visual-candle.js +134 -1
- package/dist/chart/utils/__tests__/array.utils.test.js +135 -1
- package/dist/chart/utils/__tests__/math.utils.test.js +14 -1
- package/dist/chart/utils/__tests__/object.utils.test.js +11 -1
- package/dist/chart/utils/__tests__/priceIncrementsUtils.test.js +29 -1
- package/dist/chart/utils/array.utils.d.ts +1 -1
- package/dist/chart/utils/array.utils.js +269 -1
- package/dist/chart/utils/auto-period-detector.utils.js +39 -1
- package/dist/chart/utils/candles-generator-ts.utils.js +20 -1
- package/dist/chart/utils/candles-generator.utils.js +161 -1
- package/dist/chart/utils/candles.utils.js +42 -1
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +144 -1
- package/dist/chart/utils/canvas/canvas-font-measure-tool.utils.js +51 -1
- package/dist/chart/utils/canvas/canvas-text-functions.utils.js +156 -1
- package/dist/chart/utils/color.utils.js +31 -1
- package/dist/chart/utils/device/browser.utils.js +10 -1
- package/dist/chart/utils/device/device-detector.utils.js +24 -1
- package/dist/chart/utils/device/device-pixel-ratio.utils.js +21 -1
- package/dist/chart/utils/device/touchpad.utils.js +91 -1
- package/dist/chart/utils/dom.utils.js +15 -1
- package/dist/chart/utils/function.utils.js +16 -1
- package/dist/chart/utils/linkedList.utils.d.ts +28 -0
- package/dist/chart/utils/linkedList.utils.js +138 -0
- package/dist/chart/utils/math.utils.js +115 -1
- package/dist/chart/utils/merge.utils.js +56 -1
- package/dist/chart/utils/object.utils.js +43 -1
- package/dist/chart/utils/performance/animation-frame-cache.utils.js +77 -0
- package/dist/chart/utils/{perfomance → performance}/debounce.utils.js +7 -1
- package/dist/chart/utils/performance/memoize.utils.js +74 -0
- package/dist/chart/utils/performance/request-animation-frame-throttle.utils.js +43 -0
- package/dist/chart/utils/performance/throttle.utils.js +26 -0
- package/dist/chart/utils/price-increments.utils.d.ts +1 -0
- package/dist/chart/utils/price-increments.utils.js +127 -1
- package/dist/chart/utils/uuid.utils.js +4 -1
- package/dist/dxchart.min.js +9 -12
- package/dist/index.d.ts +3 -3
- package/dist/index.js +20 -1
- package/package.json +4 -4
- package/dist/chart/utils/perfomance/animation-frame-cache.utils.js +0 -6
- package/dist/chart/utils/perfomance/memoize.utils.js +0 -6
- package/dist/chart/utils/perfomance/request-animation-frame-throttle.utils.js +0 -6
- package/dist/chart/utils/perfomance/throttle.utils.js +0 -6
- /package/dist/chart/utils/{perfomance → performance}/animation-frame-cache.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/debounce.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/memoize.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/request-animation-frame-throttle.utils.d.ts +0 -0
- /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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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=(
|
|
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
|
|
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
|
|
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
|
+
}
|