@devexperts/dxcharts-lite 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.js +55 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +10 -5
- package/dist/chart/components/pane/pane-manager.component.js +148 -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.js +95 -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 +9 -17
- package/dist/chart/components/y_axis/y-axis.model.js +33 -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 +2 -1
- package/dist/chart/model/scale.model.js +316 -1
- package/dist/chart/model/scaling/auto-scale.model.js +97 -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,137 @@
|
|
|
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{floorToDPR
|
|
6
|
+
import { floorToDPR, roundToDPR } from '../utils/device/device-pixel-ratio.utils';
|
|
7
|
+
import { VisualSeriesPoint } from './data-series.model';
|
|
8
|
+
/**
|
|
9
|
+
* Candle's visual representation. Candle's coordinates are adjusted by .5 unit to prevent anti-aliasing effect for
|
|
10
|
+
* lines with 1px width
|
|
11
|
+
*
|
|
12
|
+
* @param x wick location on X-axis
|
|
13
|
+
* @param width candle's width
|
|
14
|
+
* @param op open price location on Y axis
|
|
15
|
+
* @param cl close price location on Y axis
|
|
16
|
+
* @param lineStart wick's top location on Y axis
|
|
17
|
+
* @param lineEnd wick's bottom location on Y axis
|
|
18
|
+
* @param name candle's direction: up | down | none
|
|
19
|
+
* @param candle original candle
|
|
20
|
+
* @param hasBorder flag denoting if border should be drawn
|
|
21
|
+
* @constructor
|
|
22
|
+
*/
|
|
23
|
+
export default class VisualCandle extends VisualSeriesPoint {
|
|
24
|
+
constructor(x, width, open, close, high, low, name, candle, hasBorder = false, isActive = false, isHollow = false) {
|
|
25
|
+
super(x, close);
|
|
26
|
+
this.startUnit = x - width / 2;
|
|
27
|
+
this.width = width;
|
|
28
|
+
this.open = open;
|
|
29
|
+
this.high = high;
|
|
30
|
+
this.low = low;
|
|
31
|
+
this.name = name;
|
|
32
|
+
this.candle = candle;
|
|
33
|
+
this.hasBorder = hasBorder;
|
|
34
|
+
this.isActive = isActive;
|
|
35
|
+
this.isHollow = isHollow;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calculates the height of the body of a viewable element.
|
|
39
|
+
* @param {Viewable} viewable - The viewable element.
|
|
40
|
+
* @returns {Pixel} - The height of the body in pixels.
|
|
41
|
+
*/
|
|
42
|
+
bodyHeight(viewable) {
|
|
43
|
+
return floorToDPR(Math.abs(viewable.toY(this.open) - viewable.toY(this.close)));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Calculates the height of a candle in pixels based on the high and low values of the candle and the viewable area.
|
|
47
|
+
*
|
|
48
|
+
* @param {Viewable} viewable - The viewable area object.
|
|
49
|
+
* @returns {Pixel} - The height of the candle in pixels.
|
|
50
|
+
*/
|
|
51
|
+
candleHeight(viewable) {
|
|
52
|
+
return floorToDPR(Math.abs(viewable.toY(this.high) - viewable.toY(this.low)));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Returns coordinates of vertical line used to draw candle's body in case of small candle width
|
|
56
|
+
* @returns {[x,y,x2,y2]}
|
|
57
|
+
*/
|
|
58
|
+
bodyAsVLine(viewable) {
|
|
59
|
+
if (this.width < 2) {
|
|
60
|
+
return [this.centerUnit, this.yLineStart(viewable), this.width, this.candleHeight(viewable)];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns rectangle used to draw candles' body
|
|
65
|
+
* @returns {[x,y,width,height]}
|
|
66
|
+
*/
|
|
67
|
+
bodyRect(viewable) {
|
|
68
|
+
// candle is drawn using wick as center
|
|
69
|
+
return [this.startUnit, this.yBodyStart(viewable), this.width, this.bodyHeight(viewable)];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns the current candle object.
|
|
73
|
+
*
|
|
74
|
+
* @returns {Candle} The current candle object.
|
|
75
|
+
*/
|
|
76
|
+
getCandle() {
|
|
77
|
+
return this.candle;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns candle Y points in ascending order
|
|
81
|
+
*/
|
|
82
|
+
yBodyKeyPoints(viewable) {
|
|
83
|
+
const highY = floorToDPR(viewable.toY(this.high));
|
|
84
|
+
const lowY = floorToDPR(viewable.toY(this.low));
|
|
85
|
+
const openY = floorToDPR(viewable.toY(this.open));
|
|
86
|
+
const closeY = floorToDPR(viewable.toY(this.close));
|
|
87
|
+
const [bodyStart, bodyEnd] = openY > closeY ? [closeY, openY] : [openY, closeY];
|
|
88
|
+
const [lineStart, lineEnd] = highY > lowY ? [lowY, highY] : [highY, lowY];
|
|
89
|
+
return [lineStart, bodyStart, bodyEnd, lineEnd];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Calculates the y-coordinate of the end of a line segment that is within the viewable area.
|
|
93
|
+
* @param {Viewable} viewable - The viewable area object.
|
|
94
|
+
* @returns {Pixel} - The y-coordinate of the end of the line segment in pixels.
|
|
95
|
+
*/
|
|
96
|
+
yLineEnd(viewable) {
|
|
97
|
+
return floorToDPR(Math.max(viewable.toY(this.high), viewable.toY(this.low)));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Returns the pixel value of the starting point of the y-axis line on the given viewable area.
|
|
101
|
+
* @param {Viewable} viewable - The viewable area to calculate the pixel value on.
|
|
102
|
+
* @returns {Pixel} - The pixel value of the starting point of the y-axis line.
|
|
103
|
+
*/
|
|
104
|
+
yLineStart(viewable) {
|
|
105
|
+
return floorToDPR(Math.min(viewable.toY(this.high), viewable.toY(this.low)));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Calculates the starting y-coordinate of the body of a viewable object.
|
|
109
|
+
* @param {Viewable} viewable - The viewable object for which the starting y-coordinate of the body is to be calculated.
|
|
110
|
+
* @returns {Pixel} - The starting y-coordinate of the body of the viewable object.
|
|
111
|
+
*/
|
|
112
|
+
yBodyStart(viewable) {
|
|
113
|
+
return floorToDPR(Math.min(viewable.toY(this.open), viewable.toY(this.close)));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Calculates the maximum pixel value of the y-coordinate of the viewable object's end point and the open and close values of the current object.
|
|
117
|
+
* @param {Viewable} viewable - The viewable object whose end point is to be compared with the open and close values of the current object.
|
|
118
|
+
* @returns {Pixel} - The maximum pixel value of the y-coordinate of the viewable object's end point and the open and close values of the current object.
|
|
119
|
+
*/
|
|
120
|
+
yBodyEnd(viewable) {
|
|
121
|
+
return floorToDPR(Math.max(viewable.toY(this.open), viewable.toY(this.close)));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Calculates the x-coordinate of the center of a viewable object in pixels.
|
|
125
|
+
* @param {Viewable} viewable - The viewable object whose center is to be calculated.
|
|
126
|
+
* @returns {Pixel} - The x-coordinate of the center of the viewable object in pixels.
|
|
127
|
+
*/
|
|
128
|
+
xCenter(viewable) {
|
|
129
|
+
return this.x(viewable);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Returns the starting pixel position of a viewable object
|
|
133
|
+
* @param {Viewable} viewable - The viewable object to get the starting pixel position from
|
|
134
|
+
* @returns {Pixel} - The starting pixel position of the viewable object
|
|
135
|
+
*/
|
|
136
|
+
xStart(viewable) {
|
|
137
|
+
return roundToDPR(viewable.toX(this.startUnit));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -3,4 +3,138 @@
|
|
|
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
|
|
6
|
+
import { moveInArrayMutable, reorderArray, slice2DArray, arrayIntersect, eqeqeq } from '../array.utils';
|
|
7
|
+
describe('array functions', () => {
|
|
8
|
+
describe('Intersection of arrays', () => {
|
|
9
|
+
it('Intersection of [1, 2, 3, 1] and [1, 2, 4, 5, 6] should be [1, 2]', () => {
|
|
10
|
+
const source = [1, 2, 3, 1];
|
|
11
|
+
const target = [1, 2, 4, 5, 6];
|
|
12
|
+
const result = arrayIntersect(source, target);
|
|
13
|
+
expect(result).toEqual([1, 2]);
|
|
14
|
+
});
|
|
15
|
+
it('Intersection of [1, 2, 3] and [4, 5, 6] should be an empty array', () => {
|
|
16
|
+
const source = [1, 2, 3];
|
|
17
|
+
const target = [4, 5, 6];
|
|
18
|
+
const result = arrayIntersect(source, target);
|
|
19
|
+
expect(result).toEqual([]);
|
|
20
|
+
});
|
|
21
|
+
it('Intersection of [1, 2, 2, 3] and [1, 1, 2, 2, 4, 5] with duplicates should be [1, 2, 2]', () => {
|
|
22
|
+
const source = [1, 2, 2, 3];
|
|
23
|
+
const target = [1, 1, 2, 2, 4, 5];
|
|
24
|
+
const result = arrayIntersect(source, target, eqeqeq, false);
|
|
25
|
+
expect(result).toEqual([1, 2, 2]);
|
|
26
|
+
});
|
|
27
|
+
it('Intersection of [] and [1, 1, 2] should be []', () => {
|
|
28
|
+
const source = [];
|
|
29
|
+
const target = [1, 1, 2];
|
|
30
|
+
const result = arrayIntersect(source, target);
|
|
31
|
+
expect(result).toEqual([]);
|
|
32
|
+
});
|
|
33
|
+
it('Intersection of [1, 1, 2] and [] should be []', () => {
|
|
34
|
+
const source = [1, 1, 2];
|
|
35
|
+
const target = [];
|
|
36
|
+
const result = arrayIntersect(source, target);
|
|
37
|
+
expect(result).toEqual([]);
|
|
38
|
+
});
|
|
39
|
+
it('Intersection with custom comparison function', () => {
|
|
40
|
+
const source = [{ id: 1 }, { id: 2 }, { id: 3 }];
|
|
41
|
+
const target = [{ id: 2 }, { id: 4 }, { id: 6 }];
|
|
42
|
+
const compareFn = (a, b) => a.id === b.id;
|
|
43
|
+
const result = arrayIntersect(source, target, compareFn);
|
|
44
|
+
expect(result).toEqual([{ id: 2 }]);
|
|
45
|
+
});
|
|
46
|
+
it('Intersection of arrays of strings', () => {
|
|
47
|
+
const source = ['apple', 'banana', 'orange', 'pear'];
|
|
48
|
+
const target = ['banana', 'orange', 'grape', 'kiwi'];
|
|
49
|
+
const result = arrayIntersect(source, target);
|
|
50
|
+
expect(result).toEqual(['banana', 'orange']);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe('slice 2D array', () => {
|
|
54
|
+
it('should correctly slice arrays with correct indexes', () => {
|
|
55
|
+
const array = [
|
|
56
|
+
[1, 2],
|
|
57
|
+
[3, 4],
|
|
58
|
+
];
|
|
59
|
+
const result = slice2DArray(array, 1, 2);
|
|
60
|
+
expect(result.toString()).toBe([[2], [3]].toString());
|
|
61
|
+
const result2 = slice2DArray(array, 0, 1);
|
|
62
|
+
expect(result2.toString()).toBe([[1, 2]].toString());
|
|
63
|
+
const result3 = slice2DArray(array, 2, 3);
|
|
64
|
+
expect(result3.toString()).toBe([[3, 4]].toString());
|
|
65
|
+
const result4 = slice2DArray(array, 0, 3);
|
|
66
|
+
expect(result4.toString()).toBe([
|
|
67
|
+
[1, 2],
|
|
68
|
+
[3, 4],
|
|
69
|
+
].toString());
|
|
70
|
+
});
|
|
71
|
+
it('should corrercly slice arrays with exceeding indexes', () => {
|
|
72
|
+
const array = [
|
|
73
|
+
[1, 2],
|
|
74
|
+
[3, 4],
|
|
75
|
+
];
|
|
76
|
+
const result = slice2DArray(array, -2, 0);
|
|
77
|
+
expect(result.toString()).toBe([[1]].toString());
|
|
78
|
+
const result2 = slice2DArray(array, 3, 4);
|
|
79
|
+
expect(result2.toString()).toBe([[4]].toString());
|
|
80
|
+
const result3 = slice2DArray(array, -2, 4);
|
|
81
|
+
expect(result3.toString()).toBe([
|
|
82
|
+
[1, 2],
|
|
83
|
+
[3, 4],
|
|
84
|
+
].toString());
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
describe('reorder array', () => {
|
|
88
|
+
it('Reorders source array according to newOrder', () => {
|
|
89
|
+
const array = ['1', '2', '3'];
|
|
90
|
+
const result1 = reorderArray(array, ['3', '1']);
|
|
91
|
+
expect(result1.toString()).toBe(['3', '2', '1'].toString());
|
|
92
|
+
const result2 = reorderArray(array, ['3', '1', '2']);
|
|
93
|
+
expect(result2.toString()).toBe(['3', '1', '2'].toString());
|
|
94
|
+
const result3 = reorderArray(array, ['3']);
|
|
95
|
+
expect(result3.toString()).toBe(['1', '2', '3'].toString());
|
|
96
|
+
});
|
|
97
|
+
it('should return the reordered array even if newOrder contains duplicates', () => {
|
|
98
|
+
const source = ['1', '2', '3'];
|
|
99
|
+
const newOrder = ['2', '1', '2'];
|
|
100
|
+
expect(reorderArray(source, newOrder)).toEqual(['2', '1', '3']);
|
|
101
|
+
});
|
|
102
|
+
it('should return the reordered array even if newOrder contains extra elements', () => {
|
|
103
|
+
const source = ['1', '2', '3'];
|
|
104
|
+
const newOrder = ['6', '2', '1', '5'];
|
|
105
|
+
expect(reorderArray(source, newOrder)).toEqual(['2', '1', '3']);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('moveInArrayMutable', () => {
|
|
109
|
+
it('should move an item from start to end', () => {
|
|
110
|
+
const arr = [1, 2, 3, 4, 5];
|
|
111
|
+
const result = moveInArrayMutable(arr, 1, 3);
|
|
112
|
+
expect(result).toEqual([1, 3, 4, 2, 5]);
|
|
113
|
+
});
|
|
114
|
+
it('should move an item from end to start', () => {
|
|
115
|
+
const arr = [1, 2, 3, 4, 5];
|
|
116
|
+
const result = moveInArrayMutable(arr, 4, 1);
|
|
117
|
+
expect(result).toEqual([1, 5, 2, 3, 4]);
|
|
118
|
+
});
|
|
119
|
+
it('should move an item to the same position', () => {
|
|
120
|
+
const arr = [1, 2, 3, 4, 5];
|
|
121
|
+
const result = moveInArrayMutable(arr, 2, 2);
|
|
122
|
+
expect(result).toEqual([1, 2, 3, 4, 5]);
|
|
123
|
+
});
|
|
124
|
+
it('should clamp from and to if start and end are out of bounds', () => {
|
|
125
|
+
const arr = [1, 2, 3, 4, 5];
|
|
126
|
+
const result = moveInArrayMutable(arr, -1, 6);
|
|
127
|
+
expect(result).toEqual([2, 3, 4, 5, 1]);
|
|
128
|
+
});
|
|
129
|
+
it('should return the same array if start and end are the same', () => {
|
|
130
|
+
const arr = [1, 2, 3, 4, 5];
|
|
131
|
+
const result = moveInArrayMutable(arr, 2, 2);
|
|
132
|
+
expect(result).toEqual([1, 2, 3, 4, 5]);
|
|
133
|
+
});
|
|
134
|
+
it('should return the same array if we try to move first element outside left bound', () => {
|
|
135
|
+
const arr = [1, 2, 3, 4, 5];
|
|
136
|
+
const result = moveInArrayMutable(arr, 0, -1);
|
|
137
|
+
expect(result).toEqual([1, 2, 3, 4, 5]);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -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
|
-
import{clamp
|
|
6
|
+
import { clamp } from '../math.utils';
|
|
7
|
+
describe('math.utils', () => {
|
|
8
|
+
describe('clamp', () => {
|
|
9
|
+
it('should return the value if it is within the range', () => {
|
|
10
|
+
expect(clamp(5, 0, 10)).toEqual(5);
|
|
11
|
+
});
|
|
12
|
+
it('should return the min value if the value is less than the min', () => {
|
|
13
|
+
expect(clamp(-5, 0, 10)).toEqual(0);
|
|
14
|
+
});
|
|
15
|
+
it('should return the max value if the value is more than the max', () => {
|
|
16
|
+
expect(clamp(15, 0, 10)).toEqual(10);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -3,4 +3,14 @@
|
|
|
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{deepEqual
|
|
6
|
+
import { deepEqual } from '../object.utils';
|
|
7
|
+
describe('object', () => {
|
|
8
|
+
describe('deepEqual', () => {
|
|
9
|
+
it('should deeply compare objects', () => {
|
|
10
|
+
expect(deepEqual({}, {})).toBeTruthy();
|
|
11
|
+
expect(deepEqual({ a: { foo: 1 } }, { a: { foo: 1 } })).toBeTruthy(); //eslint-disable-line
|
|
12
|
+
expect(deepEqual({ a: { foo: 1 } }, { a: { foo: 2 } })).toBeFalsy(); //eslint-disable-line
|
|
13
|
+
expect(deepEqual({ a: { foo: 1 } }, { a: { bar: 1 } })).toBeFalsy(); //eslint-disable-line
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -3,4 +3,32 @@
|
|
|
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{PriceIncrementsUtils
|
|
6
|
+
import { PriceIncrementsUtils } from '../price-increments.utils';
|
|
7
|
+
describe('PriceIncrementsUtils', () => {
|
|
8
|
+
describe('autoDetectIncrementOfValueRange', () => {
|
|
9
|
+
it('should return increment=0.01 for range=0', () => {
|
|
10
|
+
const result = PriceIncrementsUtils.autoDetectIncrementOfValueRange(0);
|
|
11
|
+
expect(result).toBeCloseTo(0.01, 10);
|
|
12
|
+
});
|
|
13
|
+
it('should return increment=10 for range=6300.02931', () => {
|
|
14
|
+
const result = PriceIncrementsUtils.autoDetectIncrementOfValueRange(6300.02931);
|
|
15
|
+
expect(result).toBeCloseTo(10, 10);
|
|
16
|
+
});
|
|
17
|
+
it('should return increment=1 for range=124.14', () => {
|
|
18
|
+
const result = PriceIncrementsUtils.autoDetectIncrementOfValueRange(124.14);
|
|
19
|
+
expect(result).toBeCloseTo(1, 10);
|
|
20
|
+
});
|
|
21
|
+
it('should return increment=0.01 for range=5', () => {
|
|
22
|
+
const result = PriceIncrementsUtils.autoDetectIncrementOfValueRange(5);
|
|
23
|
+
expect(result).toBeCloseTo(0.01, 10);
|
|
24
|
+
});
|
|
25
|
+
it('should return increment=0.001 for range=0.5', () => {
|
|
26
|
+
const result = PriceIncrementsUtils.autoDetectIncrementOfValueRange(0.5);
|
|
27
|
+
expect(result).toBeCloseTo(0.001, 10);
|
|
28
|
+
});
|
|
29
|
+
it('should return increment=0.00001 for range=0.0018', () => {
|
|
30
|
+
const result = PriceIncrementsUtils.autoDetectIncrementOfValueRange(0.0018);
|
|
31
|
+
expect(result).toBeCloseTo(0.00001, 10);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -50,7 +50,7 @@ type ItemFinder<T> = (item: T) => boolean;
|
|
|
50
50
|
*/
|
|
51
51
|
export declare function replaceInArray<T>(arr: Array<T>, itemFinder: ItemFinder<T>, replace: T): T[];
|
|
52
52
|
export declare const uniqueArray: <T extends string | number>(arr: T[]) => T[];
|
|
53
|
-
export declare const groupBy: <T,
|
|
53
|
+
export declare const groupBy: <T, K extends keyof T, KV extends T[K] extends string | number ? T[K] : never>(array: T[], key: K) => Record<KV, T[]>;
|
|
54
54
|
/**
|
|
55
55
|
* Inserts *something* between every two elements in the source array
|
|
56
56
|
* Example: interleave(['first', 'second', 'third'], 'bar') => ['first', 'bar', 'second', 'bar', 'third']
|
|
@@ -3,4 +3,272 @@
|
|
|
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{identity
|
|
6
|
+
import { identity } from './function.utils';
|
|
7
|
+
import { clamp, shiftRight } from './math.utils';
|
|
8
|
+
/**
|
|
9
|
+
* Intersects 2 arrays.
|
|
10
|
+
* Example:
|
|
11
|
+
* source: [1, 2, 3, 1]
|
|
12
|
+
* target: [1, 2, 4, 5, 6]
|
|
13
|
+
* result: [1, 2]
|
|
14
|
+
* result (with duplicates): [1, 1, 2]
|
|
15
|
+
* @param source
|
|
16
|
+
* @param target
|
|
17
|
+
* @param compareFn
|
|
18
|
+
* @param removeDuplicates
|
|
19
|
+
* @doc-tags fp,utility
|
|
20
|
+
*/
|
|
21
|
+
export function arrayIntersect(source, target, compareFn = eqeqeq, removeDuplicates = true) {
|
|
22
|
+
const intersection = source.filter(a => target.some(b => compareFn(a, b)));
|
|
23
|
+
if (removeDuplicates) {
|
|
24
|
+
return intersection.filter((value, index, self) => self.indexOf(value) === index);
|
|
25
|
+
}
|
|
26
|
+
return intersection;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Reorders source array according to newOrder.
|
|
30
|
+
* Returns a reorder copy of the source array.
|
|
31
|
+
* Example:
|
|
32
|
+
* source: ['1', '2', '3']
|
|
33
|
+
* newOrder: ['3', '1']
|
|
34
|
+
* result: ['3', '2', '1']
|
|
35
|
+
*/
|
|
36
|
+
export const reorderArray = (source, newOrder) => {
|
|
37
|
+
// filter out elements which are not presented in the source array
|
|
38
|
+
const order = newOrder.slice().filter(i => source.find(s => s === i));
|
|
39
|
+
return source.map(el => {
|
|
40
|
+
var _a;
|
|
41
|
+
if (newOrder.indexOf(el) >= 0) {
|
|
42
|
+
return (_a = order.shift()) !== null && _a !== void 0 ? _a : el;
|
|
43
|
+
}
|
|
44
|
+
return el;
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
export const eqeqeq = (a, b) => a === b;
|
|
48
|
+
/**
|
|
49
|
+
* Subtracts target from source array.
|
|
50
|
+
* Example:
|
|
51
|
+
* source: [1, 2, 3, 4]
|
|
52
|
+
* target: [2, 4, 6]
|
|
53
|
+
* result: [1, 3]
|
|
54
|
+
* @param source
|
|
55
|
+
* @param target
|
|
56
|
+
* @param compareFn
|
|
57
|
+
*/
|
|
58
|
+
export const arraySubtract = (source, target, compareFn) => {
|
|
59
|
+
return source.filter(a => target.filter(b => compareFn(a, b)).length === 0);
|
|
60
|
+
};
|
|
61
|
+
const eqStrict = (a, b) => a === b;
|
|
62
|
+
export const arrayCompare = (source, target, compareFn = eqStrict) => {
|
|
63
|
+
return source.length === target.length && source.every((w, i) => compareFn(w, target[i]));
|
|
64
|
+
};
|
|
65
|
+
export function moveInArray(arr, from, to) {
|
|
66
|
+
const result = arr.slice();
|
|
67
|
+
const item = result[from];
|
|
68
|
+
result.splice(from, 1);
|
|
69
|
+
result.splice(to, 0, item);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
export function moveInArrayMutable(arr, _from, _to) {
|
|
73
|
+
const n = arr.length;
|
|
74
|
+
const from = clamp(_from, 0, n - 1);
|
|
75
|
+
const to = clamp(_to, 0, n - 1);
|
|
76
|
+
const item = arr[from];
|
|
77
|
+
arr.splice(from, 1);
|
|
78
|
+
arr.splice(to, 0, item);
|
|
79
|
+
return arr;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Replaces item in array with another one.
|
|
83
|
+
* @param arr
|
|
84
|
+
* @param itemFinder - predicate to find item
|
|
85
|
+
* @param replace - item to replace
|
|
86
|
+
*/
|
|
87
|
+
export function replaceInArray(arr, itemFinder, replace) {
|
|
88
|
+
const result = arr.slice();
|
|
89
|
+
const idx = result.findIndex(itemFinder);
|
|
90
|
+
if (idx !== -1) {
|
|
91
|
+
result.splice(idx, 1);
|
|
92
|
+
result.splice(idx, 0, replace);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
export const uniqueArray = (arr) => {
|
|
97
|
+
const hashTable = {};
|
|
98
|
+
return arr.filter(item => (hashTable[item] ? false : (hashTable[item] = true)));
|
|
99
|
+
};
|
|
100
|
+
export const groupBy = (array, key) => {
|
|
101
|
+
return array.reduce((result, currentValue) => {
|
|
102
|
+
// If an array already present for key, push it to the array. Else create an array and push the object
|
|
103
|
+
(result[currentValue[key]] = result[currentValue[key]] || []).push(currentValue);
|
|
104
|
+
// Return the current iteration `result` value, this will be taken as next iteration `result` value and accumulate
|
|
105
|
+
return result;
|
|
106
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
107
|
+
}, {}); // empty object is the initial value for result object
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Inserts *something* between every two elements in the source array
|
|
111
|
+
* Example: interleave(['first', 'second', 'third'], 'bar') => ['first', 'bar', 'second', 'bar', 'third']
|
|
112
|
+
* @param arr
|
|
113
|
+
* @param something
|
|
114
|
+
*/
|
|
115
|
+
export const interleave = (arr, something) =>
|
|
116
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
117
|
+
[].concat(...arr.map(n => [n, something])).slice(0, -1);
|
|
118
|
+
export const isTwoDimArray = (arr) => Array.isArray(arr[0]);
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
export const create2DArray = (arr) => (Array.isArray(arr[0]) ? arr : [arr]);
|
|
121
|
+
export const slice2DArray = (arr, startIdx, endIdx) => {
|
|
122
|
+
const result = [];
|
|
123
|
+
let pointsCurrentIdx = 0;
|
|
124
|
+
for (const arr1D of arr) {
|
|
125
|
+
const localIdxStart = Math.max(startIdx - pointsCurrentIdx, 0);
|
|
126
|
+
const localEndIdx = Math.max(endIdx - pointsCurrentIdx, -1);
|
|
127
|
+
const newPoints = arr1D.slice(localIdxStart, localEndIdx + 1);
|
|
128
|
+
newPoints.length > 0 && result.push(newPoints);
|
|
129
|
+
pointsCurrentIdx += arr1D.length;
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
};
|
|
133
|
+
// Array.at() polyfill (as of December 2022 method is not supported on iOS <= v15)
|
|
134
|
+
export const at = (idx, arr) => (idx >= 0 ? arr[idx] : arr[arr.length + idx]);
|
|
135
|
+
// Array.flat() polyfill (support for chrome 66)
|
|
136
|
+
export const flat = (arr) => {
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
if (Array.prototype.flat) {
|
|
139
|
+
return arr.flat();
|
|
140
|
+
}
|
|
141
|
+
return flatMap(arr, identity);
|
|
142
|
+
};
|
|
143
|
+
// Array.flatMap() polyfill (support for chrome 66)
|
|
144
|
+
export const flatMap = (arr, callback) => {
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
if (Array.prototype.flatMap) {
|
|
147
|
+
return arr.flatMap(callback);
|
|
148
|
+
}
|
|
149
|
+
const result = [];
|
|
150
|
+
for (let i = 0; i < arr.length; i++) {
|
|
151
|
+
const item = arr[i];
|
|
152
|
+
result.push(...callback(item, i, arr));
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
};
|
|
156
|
+
// eslint-disable-next-line no-redeclare
|
|
157
|
+
export function binarySearch(array, what, transform) {
|
|
158
|
+
// @ts-ignore
|
|
159
|
+
const applyTransform = transform !== null && transform !== void 0 ? transform : identity;
|
|
160
|
+
if (!array.length || what !== what) {
|
|
161
|
+
return {
|
|
162
|
+
index: -1,
|
|
163
|
+
exact: true,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return binarySearchFn(array, what, 0, array.length, applyTransform);
|
|
167
|
+
}
|
|
168
|
+
function binarySearchFn(array, what, from, to, transform) {
|
|
169
|
+
const center = shiftRight(from + to, 1);
|
|
170
|
+
const centerValue = transform(array[center]);
|
|
171
|
+
if (what === centerValue) {
|
|
172
|
+
return {
|
|
173
|
+
index: center,
|
|
174
|
+
exact: true,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
if (from === center) {
|
|
179
|
+
return {
|
|
180
|
+
index: from,
|
|
181
|
+
exact: false,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
if (what < centerValue) {
|
|
186
|
+
return binarySearchFn(array, what, from, center, transform);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
return binarySearchFn(array, what, center, to, transform);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
export function lastOf(arr) {
|
|
195
|
+
if (arr && arr.length) {
|
|
196
|
+
return arr[arr.length - 1];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export function arrayRemove(element) {
|
|
200
|
+
const idx = this.indexOf(element);
|
|
201
|
+
if (idx !== -1) {
|
|
202
|
+
this.splice(idx, 1);
|
|
203
|
+
}
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
// ... and this is how a normal person would write "arrayRemove" function
|
|
207
|
+
export function arrayRemove2(array, element) {
|
|
208
|
+
if (!array) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const idx = array.indexOf(element);
|
|
212
|
+
if (idx !== -1) {
|
|
213
|
+
array.splice(idx, 1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
export function firstOf(arr) {
|
|
217
|
+
if (arr) {
|
|
218
|
+
return arr[0];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
@param {Function} gather - get the comparing value from the array
|
|
223
|
+
*/
|
|
224
|
+
export function maxMin(gather) {
|
|
225
|
+
function reducer(a, b) {
|
|
226
|
+
const v = gather(b);
|
|
227
|
+
if (v === null || v === undefined || !isFinite(v)) {
|
|
228
|
+
return a;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return [Math.max(a[0], v), Math.min(a[1], v)];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return function (arr) {
|
|
235
|
+
const defaultResult = [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY];
|
|
236
|
+
if (arr) {
|
|
237
|
+
return arr.reduce(reducer, defaultResult);
|
|
238
|
+
}
|
|
239
|
+
return defaultResult;
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
export function getElementsInRange(array, leftBound, rightBound, transform = () => 0) {
|
|
243
|
+
const upperIndex = (arr, bound) => {
|
|
244
|
+
let l = 0;
|
|
245
|
+
let h = arr.length - 1;
|
|
246
|
+
while (h >= l) {
|
|
247
|
+
const midIndex = Math.ceil((l + h) / 2);
|
|
248
|
+
const mid = transform(arr[midIndex]);
|
|
249
|
+
if (mid <= bound) {
|
|
250
|
+
l = midIndex + 1;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
h = midIndex - 1;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return h;
|
|
257
|
+
};
|
|
258
|
+
const lowerIndex = (arr, bound) => {
|
|
259
|
+
let l = 0;
|
|
260
|
+
let h = arr.length - 1;
|
|
261
|
+
while (h >= l) {
|
|
262
|
+
const midIndex = Math.ceil((l + h) / 2);
|
|
263
|
+
const mid = transform(arr[midIndex]);
|
|
264
|
+
if (mid >= bound) {
|
|
265
|
+
h = midIndex - 1;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
l = midIndex + 1;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return l;
|
|
272
|
+
};
|
|
273
|
+
return array.slice(lowerIndex(array, leftBound), upperIndex(array, rightBound) + 1);
|
|
274
|
+
}
|