@devexperts/dxcharts-lite 2.2.0 → 2.4.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/dist/chart/bootstrap.js +4 -3
- package/dist/chart/canvas/canvas-bounds-container.d.ts +2 -2
- package/dist/chart/canvas/canvas-bounds-container.js +7 -5
- package/dist/chart/canvas/cursor.handler.js +2 -2
- package/dist/chart/chart.config.d.ts +17 -4
- package/dist/chart/chart.config.js +6 -2
- package/dist/chart/components/chart/chart-area-pan.handler.js +13 -8
- package/dist/chart/components/chart/chart.component.d.ts +6 -3
- package/dist/chart/components/chart/chart.component.js +18 -7
- package/dist/chart/components/chart/chart.model.d.ts +1 -2
- package/dist/chart/components/chart/chart.model.js +2 -3
- package/dist/chart/components/cross_tool/cross-tool.model.js +1 -1
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +4 -2
- package/dist/chart/components/high_low/high-low.drawer.js +9 -2
- package/dist/chart/components/highlights/highlights.drawer.js +1 -1
- package/dist/chart/components/pane/pane.component.js +6 -3
- package/dist/chart/components/snapshot/snapshot.component.js +1 -0
- package/dist/chart/components/volumes/separate-volumes.component.js +2 -1
- package/dist/chart/components/volumes/volumes.drawer.js +1 -1
- package/dist/chart/components/volumes/volumes.formatter.d.ts +1 -1
- package/dist/chart/components/volumes/volumes.formatter.js +28 -25
- package/dist/chart/components/x_axis/time/parser/time-formats-matchers.functions.js +1 -1
- package/dist/chart/components/x_axis/time/parser/time-formats.model.d.ts +1 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.functions.js +2 -2
- package/dist/chart/components/x_axis/time/x-axis-weights.generator.js +6 -7
- package/dist/chart/components/x_axis/x-axis-labels.generator.d.ts +11 -3
- package/dist/chart/components/x_axis/x-axis-labels.generator.js +47 -19
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +0 -4
- package/dist/chart/components/x_axis/x-axis.component.js +7 -11
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +5 -5
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +21 -22
- package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +18 -6
- package/dist/chart/components/y_axis/y-axis-labels.drawer.js +23 -12
- package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +9 -4
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +22 -15
- package/dist/chart/components/y_axis/y-axis.component.js +1 -0
- package/dist/chart/components/y_axis/y-axis.drawer.js +1 -1
- package/dist/chart/drawers/chart-background.drawer.d.ts +2 -3
- package/dist/chart/drawers/chart-background.drawer.js +16 -22
- package/dist/chart/drawers/data-series-drawers/candle-series-wrapper.js +1 -1
- package/dist/chart/drawers/data-series.drawer.d.ts +0 -2
- package/dist/chart/drawers/data-series.drawer.js +2 -7
- package/dist/chart/drawers/ht-data-series.drawer.js +1 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +1 -1
- package/dist/chart/inputlisteners/canvas-input-listener.component.d.ts +9 -0
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +38 -1
- package/dist/chart/model/compare-series-hover.d.ts +1 -1
- package/dist/chart/model/compare-series-hover.js +5 -0
- package/dist/chart/model/data-series.model.js +1 -1
- package/dist/chart/model/hit-test-canvas.model.js +2 -2
- package/dist/chart/model/scale.model.d.ts +6 -3
- package/dist/chart/model/scale.model.js +46 -9
- package/dist/chart/model/scaling/constrait.functions.d.ts +1 -1
- package/dist/chart/model/scaling/constrait.functions.js +1 -2
- package/dist/chart/model/scaling/lock-ratio.model.d.ts +8 -2
- package/dist/chart/model/scaling/lock-ratio.model.js +18 -3
- package/dist/chart/model/scaling/viewport.model.d.ts +2 -0
- package/dist/chart/model/scaling/viewport.model.js +13 -4
- package/dist/chart/model/time-zone.model.d.ts +0 -14
- package/dist/chart/model/time-zone.model.js +13 -33
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.d.ts +12 -1
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +16 -1
- package/dist/chart/utils/canvas/canvas-text-functions.utils.d.ts +3 -2
- package/dist/chart/utils/canvas/canvas-text-functions.utils.js +8 -3
- package/dist/chart/utils/device/touchpad.utils.d.ts +3 -3
- package/dist/chart/utils/device/touchpad.utils.js +3 -5
- package/dist/chart/utils/math.utils.d.ts +1 -1
- package/dist/chart/utils/math.utils.js +4 -1
- package/dist/chart/utils/timezone.utils.d.ts +13 -0
- package/dist/chart/utils/timezone.utils.js +48 -0
- package/dist/dxchart.min.js +6 -6
- package/package.json +1 -2
package/dist/chart/bootstrap.js
CHANGED
|
@@ -106,8 +106,9 @@ export default class ChartBootstrap {
|
|
|
106
106
|
// canvas animation container
|
|
107
107
|
const canvasAnimation = new CanvasAnimation(eventBus);
|
|
108
108
|
this.canvasAnimation = canvasAnimation;
|
|
109
|
+
const chartPaneId = CanvasElement.PANE_UUID(CHART_UUID);
|
|
109
110
|
//#region ScaleModel init
|
|
110
|
-
const scaleModel = new ScaleModel(config, () => canvasBoundsContainer.getBounds(
|
|
111
|
+
const scaleModel = new ScaleModel(config, () => canvasBoundsContainer.getBounds(chartPaneId), canvasAnimation);
|
|
111
112
|
this.scaleModel = scaleModel;
|
|
112
113
|
//#endregion
|
|
113
114
|
const backgroundCanvasModel = createCanvasModel(eventBus, elements.backgroundCanvas, config, drawingManager, this.canvasModels, elements.chartResizer, {
|
|
@@ -135,7 +136,7 @@ export default class ChartBootstrap {
|
|
|
135
136
|
this.chartComponents.push(this.dynamicObjects);
|
|
136
137
|
this.chartModel = new ChartModel(chartBaseModel, paneManager, eventBus, this.dynamicObjectsCanvasModel, config, scaleModel, formatterFactory, mainCanvasParent, canvasBoundsContainer, chartResizeHandler);
|
|
137
138
|
//#region main chart component init
|
|
138
|
-
const chartComponent = new ChartComponent(this.chartModel, this.dynamicObjectsCanvasModel, config, scaleModel, canvasBoundsContainer, drawingManager, hitTestCanvasModel, canvasInputListener, backgroundCanvasModel, chartPanComponent, paneManager, this.cursorHandler, this.dynamicObjects);
|
|
139
|
+
const chartComponent = new ChartComponent(this.chartModel, this.dynamicObjectsCanvasModel, config, scaleModel, canvasBoundsContainer, drawingManager, hitTestCanvasModel, canvasInputListener, backgroundCanvasModel, chartPanComponent, paneManager, this.cursorHandler, this.dynamicObjects, this.chartResizeHandler);
|
|
139
140
|
this.chartComponents.push(chartComponent);
|
|
140
141
|
this.chartComponent = chartComponent;
|
|
141
142
|
const chartModel = this.chartComponent.chartModel;
|
|
@@ -175,7 +176,7 @@ export default class ChartBootstrap {
|
|
|
175
176
|
this.volumesComponent = new VolumesComponent(this.dynamicObjectsCanvasModel, chartComponent, scaleModel, canvasBoundsContainer, drawingManager, config, paneManager, this.dynamicObjects);
|
|
176
177
|
this.chartComponents.push(this.volumesComponent);
|
|
177
178
|
// grid component
|
|
178
|
-
const mainChartGridComponent = new GridComponent(mainCanvasModel, scaleModel, config, this.yAxisComponent.state, 'GRID', drawingManager, () => this.canvasBoundsContainer.getBounds(CanvasElement.ALL_PANES), () => this.canvasBoundsContainer.getBounds(
|
|
179
|
+
const mainChartGridComponent = new GridComponent(mainCanvasModel, scaleModel, config, this.yAxisComponent.state, 'GRID', drawingManager, () => this.canvasBoundsContainer.getBounds(CanvasElement.ALL_PANES), () => this.canvasBoundsContainer.getBounds(chartPaneId), () => this.xAxisComponent.xAxisLabelsGenerator.labels, () => this.yAxisComponent.model.baseLabelsModel.labels, () => mainPane.mainExtent.toY(mainPane.mainExtent.getBaseline()), () => config.components.grid.visible);
|
|
179
180
|
this.chartComponents.push(mainChartGridComponent);
|
|
180
181
|
this.hoverProducer = new HoverProducerComponent(this.crossEventProducer, scaleModel, config, chartModel, canvasInputListener, this.canvasBoundsContainer, this.paneManager, timeZoneModel, formatterFactory);
|
|
181
182
|
this.chartComponents.push(this.hoverProducer);
|
|
@@ -35,11 +35,11 @@ export declare class CanvasElement {
|
|
|
35
35
|
static CHART_WITH_Y_AXIS: string;
|
|
36
36
|
static EVENTS: string;
|
|
37
37
|
/**
|
|
38
|
-
* @
|
|
38
|
+
* @returns pane bounds for the main chart
|
|
39
39
|
*/
|
|
40
40
|
static CHART: string;
|
|
41
41
|
/**
|
|
42
|
-
* @
|
|
42
|
+
* @returns y-axis bounds for the main chart
|
|
43
43
|
*/
|
|
44
44
|
static Y_AXIS: string;
|
|
45
45
|
}
|
|
@@ -31,11 +31,11 @@ CanvasElement.ALL_PANES = 'ALL_PANES';
|
|
|
31
31
|
CanvasElement.CHART_WITH_Y_AXIS = 'CHART_WITH_Y_AXIS';
|
|
32
32
|
CanvasElement.EVENTS = 'EVENTS';
|
|
33
33
|
/**
|
|
34
|
-
* @
|
|
34
|
+
* @returns pane bounds for the main chart
|
|
35
35
|
*/
|
|
36
36
|
CanvasElement.CHART = CanvasElement.PANE_UUID(CHART_UUID);
|
|
37
37
|
/**
|
|
38
|
-
* @
|
|
38
|
+
* @returns y-axis bounds for the main chart
|
|
39
39
|
*/
|
|
40
40
|
CanvasElement.Y_AXIS = CanvasElement.PANE_UUID_Y_AXIS(CHART_UUID);
|
|
41
41
|
export { CanvasElement };
|
|
@@ -565,10 +565,12 @@ export class CanvasBoundsContainer {
|
|
|
565
565
|
* @return {Bounds} bounds of element
|
|
566
566
|
*/
|
|
567
567
|
getBounds(el) {
|
|
568
|
-
|
|
569
|
-
|
|
568
|
+
let bounds = this.bounds[el];
|
|
569
|
+
if (bounds === undefined) {
|
|
570
|
+
bounds = this.copyOf(DEFAULT_BOUNDS);
|
|
571
|
+
this.bounds[el] = bounds;
|
|
570
572
|
}
|
|
571
|
-
return
|
|
573
|
+
return bounds;
|
|
572
574
|
}
|
|
573
575
|
/**
|
|
574
576
|
* Returns the position of CANVAS on whole page.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
|
-
import { Subject } from 'rxjs';
|
|
6
|
+
import { Subject, animationFrameScheduler } from 'rxjs';
|
|
7
7
|
import { distinctUntilChanged, throttleTime } from 'rxjs/operators';
|
|
8
8
|
import { ChartBaseElement } from '../model/chart-base-element';
|
|
9
9
|
import { CanvasBoundsContainer } from './canvas-bounds-container';
|
|
@@ -29,7 +29,7 @@ export class CursorHandler extends ChartBaseElement {
|
|
|
29
29
|
super.doActivate();
|
|
30
30
|
this.canvasInputListener
|
|
31
31
|
.observeMouseMoveNoDrag()
|
|
32
|
-
.pipe(throttleTime(100,
|
|
32
|
+
.pipe(throttleTime(100, animationFrameScheduler, { trailing: true }))
|
|
33
33
|
.subscribe(point => {
|
|
34
34
|
const cursorFromHT = this.hitTestCanvasModel.resolveCursor(point);
|
|
35
35
|
if (cursorFromHT !== undefined) {
|
|
@@ -233,10 +233,23 @@ export interface ChartScale {
|
|
|
233
233
|
* When dragging chart under specific angle - will automatically disable auto-scale.
|
|
234
234
|
*/
|
|
235
235
|
autoScaleDisableOnDrag: AutoScaleDisableOnDrag;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
236
|
+
zoomSensitivity: {
|
|
237
|
+
/**
|
|
238
|
+
* Value is related to zoom event (zooming chart via mouse wheel)
|
|
239
|
+
* 0..1 ratio of full viewport; 0.5 = middle, 0.75 = 3/4 of viewport
|
|
240
|
+
*/
|
|
241
|
+
wheel: number;
|
|
242
|
+
/**
|
|
243
|
+
* Value is related to pinch touchpad event (zooming chart via touchpad)
|
|
244
|
+
* 0..1 ratio of full viewport; 0.5 = middle, 0.75 = 3/4 of viewport
|
|
245
|
+
*/
|
|
246
|
+
pinch: number;
|
|
247
|
+
/**
|
|
248
|
+
* Value is related to glide touchpad event (scrolling chart via touchpad)
|
|
249
|
+
* 0..1 ratio of full viewport; 0.5 = middle, 0.75 = 3/4 of viewport
|
|
250
|
+
*/
|
|
251
|
+
glide: number;
|
|
252
|
+
};
|
|
240
253
|
/**
|
|
241
254
|
* Defines how much items (candles) will be in viewport when chart applies basic scale
|
|
242
255
|
*/
|
|
@@ -41,9 +41,13 @@ export const getDefaultConfig = () => ({
|
|
|
41
41
|
yDiff: 80,
|
|
42
42
|
},
|
|
43
43
|
inverse: false,
|
|
44
|
-
zoomSensitivity:
|
|
44
|
+
zoomSensitivity: {
|
|
45
|
+
wheel: 0.25,
|
|
46
|
+
pinch: 0.05,
|
|
47
|
+
glide: 0.05,
|
|
48
|
+
},
|
|
45
49
|
defaultViewportItems: 100,
|
|
46
|
-
disableAnimations: false
|
|
50
|
+
disableAnimations: false,
|
|
47
51
|
},
|
|
48
52
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
49
53
|
components: {
|
|
@@ -3,7 +3,7 @@
|
|
|
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 { merge } from 'rxjs';
|
|
6
|
+
import { merge, animationFrameScheduler } from 'rxjs';
|
|
7
7
|
import { throttleTime } from 'rxjs/operators';
|
|
8
8
|
import { VIEWPORT_ANIMATION_ID } from '../../animation/canvas-animation';
|
|
9
9
|
import { CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
@@ -60,10 +60,8 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
60
60
|
* @param {WheelEvent} e - Wheel event
|
|
61
61
|
* @returns {void}
|
|
62
62
|
*/
|
|
63
|
-
this.zoomXHandler = (e) => {
|
|
64
|
-
const isTouchpad = touchpadDetector(e);
|
|
63
|
+
this.zoomXHandler = (e, zoomSensitivity) => {
|
|
65
64
|
const zoomIn = e.deltaY < 0;
|
|
66
|
-
const zoomSensitivity = isTouchpad ? getTouchpadSensitivity(this.config) : this.config.scale.zoomSensitivity;
|
|
67
65
|
if (this.config.scale.zoomToCursor) {
|
|
68
66
|
const b = this.canvasBoundsContainer.getBounds(CanvasElement.CANVAS);
|
|
69
67
|
const canvasW = b.width;
|
|
@@ -114,11 +112,17 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
114
112
|
const allPanesHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
|
|
115
113
|
//#endregion
|
|
116
114
|
this.addRxSubscription(merge(this.canvasInputListener.observeWheel(allPanesHitTest), this.canvasInputListener.observePinch(allPanesHitTest))
|
|
117
|
-
.pipe(throttleTime(this.wheelTrottleTime,
|
|
118
|
-
.subscribe(
|
|
115
|
+
.pipe(throttleTime(this.wheelTrottleTime, animationFrameScheduler, { trailing: true, leading: true }))
|
|
116
|
+
.subscribe(e => {
|
|
117
|
+
const isTouchpad = touchpadDetector(e);
|
|
118
|
+
const zoomSensitivity = isTouchpad
|
|
119
|
+
? getTouchpadSensitivity(this.config.components.yAxis.type, this.config.scale.zoomSensitivity.pinch)
|
|
120
|
+
: this.config.scale.zoomSensitivity.wheel;
|
|
121
|
+
this.zoomXHandler(e, zoomSensitivity);
|
|
122
|
+
}));
|
|
119
123
|
this.addRxSubscription(this.canvasInputListener
|
|
120
124
|
.observeScrollGesture()
|
|
121
|
-
.pipe(throttleTime(this.wheelTrottleTime,
|
|
125
|
+
.pipe(throttleTime(this.wheelTrottleTime, animationFrameScheduler, { trailing: true, leading: true }))
|
|
122
126
|
.subscribe((e) => {
|
|
123
127
|
let direction = -1;
|
|
124
128
|
const device = deviceDetector();
|
|
@@ -134,7 +138,8 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
134
138
|
this.scale.moveXStart(this.scale.xStart - unitsDelta);
|
|
135
139
|
}
|
|
136
140
|
else if (deltaY !== 0 && Math.abs(deltaY) > Math.abs(deltaX)) {
|
|
137
|
-
this.
|
|
141
|
+
const zoomSensitivity = getTouchpadSensitivity(this.config.components.yAxis.type, this.config.scale.zoomSensitivity.glide);
|
|
142
|
+
this.zoomXHandler(e, zoomSensitivity);
|
|
138
143
|
}
|
|
139
144
|
this.bus.fireDraw();
|
|
140
145
|
}));
|
|
@@ -24,6 +24,7 @@ import { PaneManager } from '../pane/pane-manager.component';
|
|
|
24
24
|
import { CandleWidthCalculator, ChartModel, LastCandleLabelHandler, VisualCandleCalculator } from './chart.model';
|
|
25
25
|
import { PrependedCandlesData } from './chart-base.model';
|
|
26
26
|
import { DynamicObjectsComponent } from '../dynamic-objects/dynamic-objects.component';
|
|
27
|
+
import { ChartResizeHandler } from '../../inputhandlers/chart-resize.handler';
|
|
27
28
|
/**
|
|
28
29
|
* Represents a financial instrument to be displayed on a chart
|
|
29
30
|
* @class
|
|
@@ -59,11 +60,13 @@ export declare class ChartComponent extends ChartBaseElement {
|
|
|
59
60
|
private canvasInputListener;
|
|
60
61
|
private paneManager;
|
|
61
62
|
private dynamicObjects;
|
|
63
|
+
private chartResizeHandler;
|
|
62
64
|
readonly baselineModel: BaselineModel;
|
|
63
65
|
private readonly backgroundDrawer;
|
|
64
66
|
private readonly _dataSeriesDrawers;
|
|
65
67
|
private readonly dataSeriesDrawer;
|
|
66
|
-
|
|
68
|
+
private backgroundDrawPredicateSubj;
|
|
69
|
+
constructor(chartModel: ChartModel, canvasModel: CanvasModel, config: FullChartConfig, scale: ScaleModel, canvasBoundsContainer: CanvasBoundsContainer, drawingManager: DrawingManager, hitTestCanvasModel: HitTestCanvasModel, canvasInputListener: CanvasInputListenerComponent, backgroundCanvasModel: CanvasModel, chartPanComponent: ChartPanComponent, paneManager: PaneManager, cursorHandler: CursorHandler, dynamicObjects: DynamicObjectsComponent, chartResizeHandler: ChartResizeHandler);
|
|
67
70
|
/**
|
|
68
71
|
* This method overrides the doActivate method of the parent class and calls it.
|
|
69
72
|
* It does not take any parameters and does not return anything.
|
|
@@ -118,13 +121,13 @@ export declare class ChartComponent extends ChartBaseElement {
|
|
|
118
121
|
* @param {Timestamp} end - The end timestamp of the range.
|
|
119
122
|
* @returns {void}
|
|
120
123
|
*/
|
|
121
|
-
setTimestampRange(start: Timestamp, end: Timestamp): void;
|
|
124
|
+
setTimestampRange(start: Timestamp, end: Timestamp, forceNoAnimation?: boolean): void;
|
|
122
125
|
/**
|
|
123
126
|
* Moves the viewport to exactly xStart..xEnd place.
|
|
124
127
|
* @param xStart - viewport start in units
|
|
125
128
|
* @param xEnd - viewport end in units
|
|
126
129
|
*/
|
|
127
|
-
setXScale(xStart: Unit, xEnd: Unit): void;
|
|
130
|
+
setXScale(xStart: Unit, xEnd: Unit, forceNoAnimation?: boolean): void;
|
|
128
131
|
/**
|
|
129
132
|
* Sets the visibility of the wicks in the chart.
|
|
130
133
|
* @param {boolean} isShow - A boolean value indicating whether to show or hide the wicks.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
|
+
import { BehaviorSubject } from 'rxjs';
|
|
6
7
|
import { CHART_UUID, CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
7
8
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
8
9
|
import { BackgroundDrawer } from '../../drawers/chart-background.drawer';
|
|
@@ -48,7 +49,7 @@ export class ChartInstrument {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
export class ChartComponent extends ChartBaseElement {
|
|
51
|
-
constructor(chartModel, canvasModel, config, scale, canvasBoundsContainer, drawingManager, hitTestCanvasModel, canvasInputListener, backgroundCanvasModel, chartPanComponent, paneManager, cursorHandler, dynamicObjects) {
|
|
52
|
+
constructor(chartModel, canvasModel, config, scale, canvasBoundsContainer, drawingManager, hitTestCanvasModel, canvasInputListener, backgroundCanvasModel, chartPanComponent, paneManager, cursorHandler, dynamicObjects, chartResizeHandler) {
|
|
52
53
|
super();
|
|
53
54
|
this.chartModel = chartModel;
|
|
54
55
|
this.canvasModel = canvasModel;
|
|
@@ -60,7 +61,9 @@ export class ChartComponent extends ChartBaseElement {
|
|
|
60
61
|
this.canvasInputListener = canvasInputListener;
|
|
61
62
|
this.paneManager = paneManager;
|
|
62
63
|
this.dynamicObjects = dynamicObjects;
|
|
64
|
+
this.chartResizeHandler = chartResizeHandler;
|
|
63
65
|
this._dataSeriesDrawers = {};
|
|
66
|
+
this.backgroundDrawPredicateSubj = new BehaviorSubject(true);
|
|
64
67
|
this.strToBarType = (str) => { var _a; return (_a = this.barTypeValues.find(t => t === str)) !== null && _a !== void 0 ? _a : 'candle'; };
|
|
65
68
|
this.addChildEntity(this.chartModel);
|
|
66
69
|
this.registerDefaultCandlesTransformers();
|
|
@@ -73,7 +76,7 @@ export class ChartComponent extends ChartBaseElement {
|
|
|
73
76
|
//#region data series drawers
|
|
74
77
|
this.registerDefaultDataSeriesDrawers();
|
|
75
78
|
//#endregion
|
|
76
|
-
this.backgroundDrawer = new BackgroundDrawer(backgroundCanvasModel, this.config);
|
|
79
|
+
this.backgroundDrawer = new BackgroundDrawer(backgroundCanvasModel, this.config, () => this.backgroundDrawPredicateSubj.getValue());
|
|
77
80
|
drawingManager.addDrawer(this.backgroundDrawer, 'MAIN_BACKGROUND');
|
|
78
81
|
cursorHandler.setCursorForCanvasEl(CanvasElement.PANE_UUID(CHART_UUID), config.components.chart.cursor);
|
|
79
82
|
this.dataSeriesDrawer = new DataSeriesDrawer(paneManager, this.dataSeriesDrawers);
|
|
@@ -104,6 +107,13 @@ export class ChartComponent extends ChartBaseElement {
|
|
|
104
107
|
this.addRxSubscription(this.paneManager.dataSeriesRemovedSubject.subscribe(series => {
|
|
105
108
|
this.dynamicObjects.model.removeObject(series.id);
|
|
106
109
|
}));
|
|
110
|
+
// redraw background only when chart is resized
|
|
111
|
+
this.addRxSubscription(this.canvasBoundsContainer.observeAnyBoundsChanged().subscribe(() => {
|
|
112
|
+
this.backgroundDrawPredicateSubj.next(false);
|
|
113
|
+
}));
|
|
114
|
+
this.addRxSubscription(this.chartResizeHandler.canvasResized.subscribe(() => {
|
|
115
|
+
this.backgroundDrawPredicateSubj.next(true);
|
|
116
|
+
}));
|
|
107
117
|
}
|
|
108
118
|
/**
|
|
109
119
|
* Registers default candle transformers.
|
|
@@ -162,7 +172,8 @@ export class ChartComponent extends ChartBaseElement {
|
|
|
162
172
|
this.registerDataSeriesTypeDrawer('area', new AreaDrawer(this.config.components.chart));
|
|
163
173
|
this.registerDataSeriesTypeDrawer('baseline', new BaselineDrawer(this.baselineModel, this.canvasBoundsContainer));
|
|
164
174
|
this.registerDataSeriesTypeDrawer('histogram', new MainChartHistogramDrawer(this.config.components.chart.histogram));
|
|
165
|
-
const
|
|
175
|
+
const chartPaneId = CanvasElement.PANE_UUID(CHART_UUID);
|
|
176
|
+
const mainChartBoundsProvider = () => this.canvasBoundsContainer.getBounds(chartPaneId);
|
|
166
177
|
this.registerDataSeriesTypeDrawer('LINEAR', new LinearDrawer());
|
|
167
178
|
this.registerDataSeriesTypeDrawer('HISTOGRAM', new HistogramDrawer());
|
|
168
179
|
this.registerDataSeriesTypeDrawer('TREND_HISTOGRAM', new TrendHistogramDrawer());
|
|
@@ -196,16 +207,16 @@ export class ChartComponent extends ChartBaseElement {
|
|
|
196
207
|
* @param {Timestamp} end - The end timestamp of the range.
|
|
197
208
|
* @returns {void}
|
|
198
209
|
*/
|
|
199
|
-
setTimestampRange(start, end) {
|
|
200
|
-
return this.chartModel.setTimestampRange(start, end);
|
|
210
|
+
setTimestampRange(start, end, forceNoAnimation = true) {
|
|
211
|
+
return this.chartModel.setTimestampRange(start, end, forceNoAnimation);
|
|
201
212
|
}
|
|
202
213
|
/**
|
|
203
214
|
* Moves the viewport to exactly xStart..xEnd place.
|
|
204
215
|
* @param xStart - viewport start in units
|
|
205
216
|
* @param xEnd - viewport end in units
|
|
206
217
|
*/
|
|
207
|
-
setXScale(xStart, xEnd) {
|
|
208
|
-
return this.scale.setXScale(xStart, xEnd);
|
|
218
|
+
setXScale(xStart, xEnd, forceNoAnimation = true) {
|
|
219
|
+
return this.scale.setXScale(xStart, xEnd, forceNoAnimation);
|
|
209
220
|
}
|
|
210
221
|
/**
|
|
211
222
|
* Sets the visibility of the wicks in the chart.
|
|
@@ -49,7 +49,6 @@ export declare class ChartModel extends ChartBaseElement {
|
|
|
49
49
|
readonly nextCandleTimeStampSubject: Subject<void>;
|
|
50
50
|
readonly chartTypeChanged: Subject<BarType>;
|
|
51
51
|
readonly mainInstrumentChangedSubject: Subject<ChartInstrument>;
|
|
52
|
-
readonly scaleInversedSubject: Subject<void>;
|
|
53
52
|
readonly offsetsChanged: Subject<void>;
|
|
54
53
|
private candlesTransformersByChartType;
|
|
55
54
|
lastCandleLabelsByChartType: Partial<Record<BarType, LastCandleLabelHandler>>;
|
|
@@ -319,7 +318,7 @@ export declare class ChartModel extends ChartBaseElement {
|
|
|
319
318
|
* @param {Timestamp} end - The end timestamp of the range.
|
|
320
319
|
* @returns {void}
|
|
321
320
|
*/
|
|
322
|
-
setTimestampRange(start: Timestamp, end: Timestamp): void;
|
|
321
|
+
setTimestampRange(start: Timestamp, end: Timestamp, forceNoAnimation?: boolean): void;
|
|
323
322
|
/**
|
|
324
323
|
* Returns the last candle of the main candle series.
|
|
325
324
|
* @returns {Candle | undefined} The last candle of the main candle series or undefined if the series is empty.
|
|
@@ -50,7 +50,6 @@ export class ChartModel extends ChartBaseElement {
|
|
|
50
50
|
this.nextCandleTimeStampSubject = new Subject();
|
|
51
51
|
this.chartTypeChanged = new Subject();
|
|
52
52
|
this.mainInstrumentChangedSubject = new Subject();
|
|
53
|
-
this.scaleInversedSubject = new Subject();
|
|
54
53
|
this.offsetsChanged = new Subject();
|
|
55
54
|
this.candlesTransformersByChartType = {};
|
|
56
55
|
this.lastCandleLabelsByChartType = {};
|
|
@@ -656,11 +655,11 @@ export class ChartModel extends ChartBaseElement {
|
|
|
656
655
|
* @param {Timestamp} end - The end timestamp of the range.
|
|
657
656
|
* @returns {void}
|
|
658
657
|
*/
|
|
659
|
-
setTimestampRange(start, end) {
|
|
658
|
+
setTimestampRange(start, end, forceNoAnimation = true) {
|
|
660
659
|
const startUnit = this.candleFromTimestamp(start).startUnit;
|
|
661
660
|
const endCandle = this.candleFromTimestamp(end);
|
|
662
661
|
const endUnit = endCandle.startUnit + endCandle.width;
|
|
663
|
-
return this.scale.setXScale(startUnit, endUnit);
|
|
662
|
+
return this.scale.setXScale(startUnit, endUnit, forceNoAnimation);
|
|
664
663
|
}
|
|
665
664
|
/**
|
|
666
665
|
* Returns the last candle of the main candle series.
|
|
@@ -107,7 +107,7 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
107
107
|
else {
|
|
108
108
|
this.currentHover.y = hover.y;
|
|
109
109
|
}
|
|
110
|
-
this.currentHover.paneId =
|
|
110
|
+
this.currentHover.paneId = hover.paneId;
|
|
111
111
|
this.currentHoverSubject.next(this.currentHover);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -122,6 +122,7 @@ export class CrossAndLabelsDrawerType {
|
|
|
122
122
|
if (this.config.components.yAxis.visible) {
|
|
123
123
|
const pane = this.paneManager.panes[point.paneId];
|
|
124
124
|
const y = point.y;
|
|
125
|
+
const type = this.config.components.crossTool.yLabel.type;
|
|
125
126
|
if (!pane) {
|
|
126
127
|
return;
|
|
127
128
|
}
|
|
@@ -129,9 +130,10 @@ export class CrossAndLabelsDrawerType {
|
|
|
129
130
|
const price = extent.regularValueFromY(y);
|
|
130
131
|
const label = extent.valueFormatter(price);
|
|
131
132
|
const bounds = this.canvasBoundsContainer.getBounds(CanvasElement.PANE_UUID_Y_AXIS(pane.uuid, extent.idx));
|
|
132
|
-
const drawYLabel = priceLabelDrawersMap[
|
|
133
|
+
const drawYLabel = priceLabelDrawersMap[type];
|
|
134
|
+
const textColor = type === 'plain' ? crossToolColors.lineColor : crossToolColors.labelTextColor;
|
|
133
135
|
drawYLabel(ctx, bounds, label, y, {
|
|
134
|
-
textColor
|
|
136
|
+
textColor,
|
|
135
137
|
bgColor: crossToolColors.labelBoxColor,
|
|
136
138
|
paddingBottom: yLabelPadding === null || yLabelPadding === void 0 ? void 0 : yLabelPadding.bottom,
|
|
137
139
|
paddingEnd: yLabelPadding === null || yLabelPadding === void 0 ? void 0 : yLabelPadding.end,
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
7
7
|
import { getTextLineHeight } from '../../utils/canvas/canvas-text-functions.utils';
|
|
8
|
+
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
|
|
8
9
|
export class HighLowDrawer {
|
|
9
10
|
constructor(canvasModel, chartModel, config, canvasBoundsContainer) {
|
|
10
11
|
this.canvasModel = canvasModel;
|
|
@@ -34,7 +35,10 @@ export class HighLowDrawer {
|
|
|
34
35
|
ctx.font = this.config.components.highLow.font;
|
|
35
36
|
this.drawMarkerLabel(ctx, finalHighIdx, high, 'high');
|
|
36
37
|
this.drawMarkerLabel(ctx, finalLowIdx, low, 'low');
|
|
38
|
+
const chartBounds = this.canvasBoundsContainer.getBounds('PANE_CHART');
|
|
37
39
|
ctx.restore();
|
|
40
|
+
// We need clip here so lowLabel won't overlap other panes
|
|
41
|
+
clipToBounds(ctx, chartBounds);
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
/**
|
|
@@ -47,7 +51,10 @@ export class HighLowDrawer {
|
|
|
47
51
|
*/
|
|
48
52
|
drawMarkerLabel(ctx, candleIdx, yValue, type) {
|
|
49
53
|
const y = this.getMarkerY(ctx, yValue, type === 'low');
|
|
50
|
-
|
|
54
|
+
const fontSize = getTextLineHeight(ctx, false);
|
|
55
|
+
// we need to measure fit into the bounds for low label by its top point
|
|
56
|
+
const yForBoundsTrack = type === 'low' ? y - fontSize : y;
|
|
57
|
+
if (!this.checkMarkerInBounds(yForBoundsTrack)) {
|
|
51
58
|
return;
|
|
52
59
|
}
|
|
53
60
|
const text = this.getMarkerText(yValue, type);
|
|
@@ -79,7 +86,7 @@ export class HighLowDrawer {
|
|
|
79
86
|
getMarkerY(ctx, yValue, offset = false) {
|
|
80
87
|
const y = this.chartModel.toY(yValue);
|
|
81
88
|
if (offset) {
|
|
82
|
-
const fontSize = getTextLineHeight(ctx);
|
|
89
|
+
const fontSize = getTextLineHeight(ctx, false);
|
|
83
90
|
return y + fontSize;
|
|
84
91
|
}
|
|
85
92
|
return y;
|
|
@@ -7,7 +7,7 @@ import { calculateTextWidth } from '../../utils/canvas/canvas-font-measure-tool.
|
|
|
7
7
|
import { HIGHLIGHTS_TYPES } from './highlights.model';
|
|
8
8
|
import { CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
9
9
|
import { unitToPixels } from '../../model/scaling/viewport.model';
|
|
10
|
-
import { clipToBounds } from '../../
|
|
10
|
+
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
|
|
11
11
|
const LABEL_PADDINGS = [20, 10];
|
|
12
12
|
export class HighlightsDrawer {
|
|
13
13
|
constructor(highlightsModel, chartModel, canvasModel, canvasBoundsContainer, config) {
|
|
@@ -85,7 +85,8 @@ export class PaneComponent extends ChartBaseElement {
|
|
|
85
85
|
* @returns {GridComponent} - The newly created GridComponent instance.
|
|
86
86
|
*/
|
|
87
87
|
createGridComponent(uuid, scale, yAxisLabelsGenerator, yAxisState) {
|
|
88
|
-
const
|
|
88
|
+
const chartPaneId = CanvasElement.PANE_UUID(uuid);
|
|
89
|
+
const gridComponent = new GridComponent(this.mainCanvasModel, scale, this.config, yAxisState, `PANE_${uuid}_grid_drawer`, this.drawingManager, () => this.canvasBoundsContainer.getBounds(chartPaneId), () => this.canvasBoundsContainer.getBounds(chartPaneId), () => [], () => yAxisLabelsGenerator.generateNumericLabels());
|
|
89
90
|
return gridComponent;
|
|
90
91
|
}
|
|
91
92
|
/**
|
|
@@ -96,7 +97,8 @@ export class PaneComponent extends ChartBaseElement {
|
|
|
96
97
|
* @returns {Unsubscriber}
|
|
97
98
|
*/
|
|
98
99
|
createYPanHandler(uuid, scale) {
|
|
99
|
-
const
|
|
100
|
+
const chartPaneId = CanvasElement.PANE_UUID(uuid);
|
|
101
|
+
const dragNDropComponent = this.chartPanComponent.chartAreaPanHandler.registerChartYPanHandler(scale, this.canvasBoundsContainer.getBoundsHitTest(chartPaneId));
|
|
100
102
|
return [
|
|
101
103
|
() => {
|
|
102
104
|
this.chartPanComponent.chartAreaPanHandler.removeChildEntity(dragNDropComponent);
|
|
@@ -113,7 +115,8 @@ export class PaneComponent extends ChartBaseElement {
|
|
|
113
115
|
createExtentComponent(options) {
|
|
114
116
|
var _a, _b;
|
|
115
117
|
const extentIdx = this.yExtentComponents.length;
|
|
116
|
-
const
|
|
118
|
+
const chartPaneId = CanvasElement.PANE_UUID(this.uuid);
|
|
119
|
+
const getBounds = () => this.canvasBoundsContainer.getBounds(chartPaneId);
|
|
117
120
|
const scaleModel = (_a = options === null || options === void 0 ? void 0 : options.scale) !== null && _a !== void 0 ? _a : new SyncedByXScaleModel(this.mainScale, this.config, getBounds, this.canvasAnimation);
|
|
118
121
|
const [unsub, dragNDrop] = this.createYPanHandler(this.uuid, scaleModel);
|
|
119
122
|
// creating partially resolved constructor except formatter & dataSeriesProvider - bcs it's not possible to provide formatter
|
|
@@ -40,6 +40,7 @@ export class SnapshotComponent extends ChartBaseElement {
|
|
|
40
40
|
ctx.drawImage(this.elements.mainCanvas, 0, 0, width, height);
|
|
41
41
|
ctx.drawImage(this.elements.dynamicObjectsCanvas, 0, 0, width, height);
|
|
42
42
|
ctx.drawImage(this.elements.crossToolCanvas, 0, 0, width, height);
|
|
43
|
+
ctx.drawImage(this.elements.yAxisLabelsCanvas, 0, 0, width, height);
|
|
43
44
|
userDrawCallback && userDrawCallback(ctx);
|
|
44
45
|
return new Promise((resolve, fail) => this.elements.snapshotCanvas.toBlob(blob => {
|
|
45
46
|
return blob ? resolve(blob) : fail('Blob is null');
|
|
@@ -31,9 +31,10 @@ class SeparateVolumesComponent extends ChartBaseElement {
|
|
|
31
31
|
*/
|
|
32
32
|
activateSeparateVolumes() {
|
|
33
33
|
if (this.paneManager.panes[SeparateVolumesComponent.UUID] === undefined) {
|
|
34
|
+
const precision = 1;
|
|
34
35
|
const volumePane = this.paneManager.createPane(SeparateVolumesComponent.UUID, {
|
|
35
36
|
paneFormatters: {
|
|
36
|
-
regular: volumeFormatter,
|
|
37
|
+
regular: (value) => volumeFormatter(value, precision),
|
|
37
38
|
},
|
|
38
39
|
useDefaultHighLow: false,
|
|
39
40
|
increment: 1,
|
|
@@ -3,7 +3,7 @@
|
|
|
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 } from '../../
|
|
6
|
+
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
|
|
7
7
|
import { unitToPixels } from '../../model/scaling/viewport.model';
|
|
8
8
|
import { flat } from '../../utils/array.utils';
|
|
9
9
|
import { ceilToDPR, floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
|
|
@@ -3,4 +3,4 @@
|
|
|
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 declare const volumeFormatter: (value: number) => string;
|
|
6
|
+
export declare const volumeFormatter: (value: number, precision?: number) => string;
|
|
@@ -3,34 +3,37 @@
|
|
|
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
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const roundedValue = Math.round(value * rounder) / rounder;
|
|
14
|
-
if (roundedValue < 1 && roundedValue >= MIN_VALUE) {
|
|
15
|
-
return roundedValue
|
|
16
|
-
.toFixed(DEFAULT_PRECISION)
|
|
17
|
-
.replace(TRAILLING_ZEROES_REGEXP, '')
|
|
18
|
-
.replace(TRAILLING_FRACTION_WITH_ZEROES_REGEXP, '');
|
|
6
|
+
export const volumeFormatter = (value, precision = 1) => {
|
|
7
|
+
function formatNumber(value) {
|
|
8
|
+
let formattedResult;
|
|
9
|
+
const priceScale = Math.pow(10, precision);
|
|
10
|
+
value = Math.round(value * priceScale) / priceScale;
|
|
11
|
+
if (value >= 1e-15 && value < 1) {
|
|
12
|
+
formattedResult = value.toFixed(precision).replace(/\.?0+$/, ''); // regex removes trailing zeroes
|
|
19
13
|
}
|
|
20
14
|
else {
|
|
21
|
-
|
|
15
|
+
formattedResult = String(value);
|
|
22
16
|
}
|
|
23
|
-
|
|
24
|
-
if (Math.abs(value) > 999999999) {
|
|
25
|
-
value = Math.round(value / 1000000) * 1000000;
|
|
26
|
-
return formatValue(value / 1000000000, 'B');
|
|
17
|
+
return formattedResult.replace(/(\.[1-9]*)0+$/, (e, p1) => p1);
|
|
27
18
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
function format(value) {
|
|
20
|
+
let sign = '';
|
|
21
|
+
if (value < 0) {
|
|
22
|
+
sign = '-';
|
|
23
|
+
value = -value;
|
|
24
|
+
}
|
|
25
|
+
if (value < 995) {
|
|
26
|
+
return sign + formatNumber(value);
|
|
27
|
+
}
|
|
28
|
+
if (value < 999995) {
|
|
29
|
+
return sign + formatNumber(value / 1000) + 'K';
|
|
30
|
+
}
|
|
31
|
+
if (value < 999999995) {
|
|
32
|
+
value = 1000 * Math.round(value / 1000);
|
|
33
|
+
return sign + formatNumber(value / 1000000) + 'M';
|
|
34
|
+
}
|
|
35
|
+
value = 1000000 * Math.round(value / 1000000);
|
|
36
|
+
return sign + formatNumber(value / 1000000000) + 'B';
|
|
34
37
|
}
|
|
35
|
-
return
|
|
38
|
+
return format(value);
|
|
36
39
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
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 { eachDayOfInterval, isSameDay, isMonday, isTuesday, isWednesday, isThursday, isFriday, isSaturday, isSunday, startOfMonth, endOfMonth, } from 'date-fns
|
|
6
|
+
import { eachDayOfInterval, isSameDay, isMonday, isTuesday, isWednesday, isThursday, isFriday, isSaturday, isSunday, startOfMonth, endOfMonth, } from 'date-fns';
|
|
7
7
|
/**
|
|
8
8
|
* Factory that return a {@link TimeFormatMatcher} function for a given {@link ParsedTimeFormats}
|
|
9
9
|
* @see
|
|
@@ -27,7 +27,7 @@ export interface ParsedNCTimeFormat {
|
|
|
27
27
|
}
|
|
28
28
|
export type ParsedTimeFormat = ParsedCTimeFormat | ParsedWeekFormat | ParsedNCTimeFormat;
|
|
29
29
|
export type SpecialSymbol = '!' | '$';
|
|
30
|
-
export declare const timeFormatConfirugableGuard: (key: string) => key is "
|
|
30
|
+
export declare const timeFormatConfirugableGuard: (key: string) => key is "year" | "month" | "day" | "hour" | "minute" | "second";
|
|
31
31
|
export declare const weekWeekdayGuard: (key: string) => key is "week-weekday";
|
|
32
32
|
export declare const timeFormatNoNConfirugableGuard: (key: string) => key is "lessThanSecond";
|
|
33
33
|
export {};
|
|
@@ -51,7 +51,7 @@ export const getWeightFromTimeFormat = (format) => {
|
|
|
51
51
|
*/
|
|
52
52
|
export const groupLabelsByWeight = (weightedLabels) => {
|
|
53
53
|
const labelsGroupedByWeight = {};
|
|
54
|
-
|
|
54
|
+
for (const weightedLabel of weightedLabels) {
|
|
55
55
|
const labelsByWeight = labelsGroupedByWeight[weightedLabel.weight];
|
|
56
56
|
if (labelsByWeight === undefined) {
|
|
57
57
|
labelsGroupedByWeight[weightedLabel.weight] = [weightedLabel];
|
|
@@ -59,7 +59,7 @@ export const groupLabelsByWeight = (weightedLabels) => {
|
|
|
59
59
|
else {
|
|
60
60
|
labelsByWeight.push(weightedLabel);
|
|
61
61
|
}
|
|
62
|
-
}
|
|
62
|
+
}
|
|
63
63
|
return labelsGroupedByWeight;
|
|
64
64
|
};
|
|
65
65
|
/**
|