@devexperts/dxcharts-lite 2.6.0 → 2.6.2
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 +1 -1
- package/dist/chart/canvas/canvas-bounds-container.d.ts +5 -4
- package/dist/chart/canvas/canvas-bounds-container.js +8 -5
- package/dist/chart/chart.config.d.ts +48 -12
- package/dist/chart/chart.config.js +27 -6
- package/dist/chart/components/chart/chart-area-pan.handler.d.ts +3 -2
- package/dist/chart/components/chart/chart-area-pan.handler.js +5 -4
- package/dist/chart/components/cross_tool/cross-tool.component.js +2 -2
- package/dist/chart/components/cross_tool/cross-tool.drawer.d.ts +3 -1
- package/dist/chart/components/cross_tool/cross-tool.drawer.js +4 -3
- package/dist/chart/components/cross_tool/cross-tool.model.d.ts +6 -6
- package/dist/chart/components/cross_tool/cross-tool.model.js +42 -11
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +3 -3
- package/dist/chart/components/events/events-custom-icons.d.ts +33 -0
- package/dist/chart/components/events/events-custom-icons.js +52 -0
- package/dist/chart/components/events/events.drawer.d.ts +5 -30
- package/dist/chart/components/events/events.drawer.js +33 -69
- package/dist/chart/components/high_low/high-low.drawer.js +1 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +6 -0
- package/dist/chart/components/pane/pane-manager.component.js +24 -3
- package/dist/chart/components/pane/pane.component.d.ts +16 -5
- package/dist/chart/components/pane/pane.component.js +27 -4
- package/dist/chart/components/resizer/bar-resizer.component.d.ts +1 -0
- package/dist/chart/components/resizer/bar-resizer.component.js +1 -0
- package/dist/chart/components/x_axis/x-axis-draw.functions.js +2 -2
- package/dist/chart/components/x_axis/x-axis-scale.handler.d.ts +1 -0
- package/dist/chart/components/x_axis/x-axis-scale.handler.js +37 -8
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +2 -2
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.d.ts +3 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +4 -1
- package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +2 -0
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +12 -0
- package/dist/chart/inputhandlers/cross-event-producer.component.d.ts +22 -0
- package/dist/chart/inputhandlers/cross-event-producer.component.js +11 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +5 -3
- package/dist/chart/inputhandlers/hover-producer.component.js +70 -16
- package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +10 -0
- package/dist/chart/inputhandlers/main-canvas-touch.handler.js +18 -0
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +2 -7
- package/dist/chart/model/candle-series.model.js +1 -1
- package/dist/chart/model/data-series.model.js +18 -0
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
package/dist/chart/bootstrap.js
CHANGED
|
@@ -182,7 +182,7 @@ export default class ChartBootstrap {
|
|
|
182
182
|
// grid component
|
|
183
183
|
const verticalGridComponent = new GridComponent(mainCanvasModel, scaleModel, config, this.yAxisComponent.state, 'GRID', drawingManager, () => this.canvasBoundsContainer.getBounds(CanvasElement.ALL_PANES), () => this.canvasBoundsContainer.getBounds(chartPaneId), () => this.xAxisComponent.xAxisLabelsGenerator.labels, () => [], undefined, () => config.components.grid.visible);
|
|
184
184
|
this.chartComponents.push(verticalGridComponent);
|
|
185
|
-
this.hoverProducer = new HoverProducerComponent(this.crossEventProducer, scaleModel, config, chartModel, canvasInputListener, this.canvasBoundsContainer, this.paneManager, timeZoneModel, formatterFactory);
|
|
185
|
+
this.hoverProducer = new HoverProducerComponent(this.crossEventProducer, scaleModel, config, chartModel, canvasInputListener, this.canvasBoundsContainer, this.paneManager, timeZoneModel, chartPanComponent.mainCanvasTouchHandler, formatterFactory);
|
|
186
186
|
this.chartComponents.push(this.hoverProducer);
|
|
187
187
|
this.crossToolComponent = new CrossToolComponent(config, crossToolCanvasModel, canvasBoundsContainer, drawingManager, paneManager, this.crossEventProducer, this.hoverProducer);
|
|
188
188
|
this.chartComponents.push(this.crossToolComponent);
|
|
@@ -45,6 +45,7 @@ export declare class CanvasElement {
|
|
|
45
45
|
}
|
|
46
46
|
export declare const DEFAULT_BOUNDS: Bounds;
|
|
47
47
|
export declare const DEFAULT_MIN_PANE_HEIGHT = 20;
|
|
48
|
+
export declare const X_AXIS_MOBILE_PADDING: number;
|
|
48
49
|
/**
|
|
49
50
|
* This component listens EVENT_DRAW and recalculates bounds of canvas chart elements.
|
|
50
51
|
* {@link getBounds} method will always give actual placement of element you want.
|
|
@@ -240,10 +241,10 @@ export declare class CanvasBoundsContainer {
|
|
|
240
241
|
/**
|
|
241
242
|
* Gets hit-test fn for canvas element.
|
|
242
243
|
* @param {string} el - CanvasElement.ELEMENT_NAME
|
|
243
|
-
* @param {
|
|
244
|
-
* @param {number} extensionX -
|
|
245
|
-
* @param {number} extensionY -
|
|
246
|
-
* @param wholePage
|
|
244
|
+
* @param {Object} options - An object containing options for the hit test.
|
|
245
|
+
* @param {number} [options.extensionX=0] - The amount of extension in the x-axis.
|
|
246
|
+
* @param {number} [options.extensionY=0] - The amount of extension in the y-axis.
|
|
247
|
+
* @param {boolean} [options.wholePage=false] - Whether to test against the whole page or just the bounds object.
|
|
247
248
|
* @return {HitBoundsTest} hit-test fn
|
|
248
249
|
*/
|
|
249
250
|
getBoundsHitTest(el: string, options?: AtLeastOne<HitBoundsTestOptions>): HitBoundsTest;
|
|
@@ -45,6 +45,8 @@ const N_MAP_H = 35;
|
|
|
45
45
|
const N_MAP_BUTTON_W = 15;
|
|
46
46
|
const KNOTS_W_MOBILE_MULTIPLIER = 1.5;
|
|
47
47
|
const N_MAP_KNOT_W = isMobile() ? 8 * KNOTS_W_MOBILE_MULTIPLIER : 8;
|
|
48
|
+
// additional x axis height padding for mobiles, used for better usability on mobile devices
|
|
49
|
+
export const X_AXIS_MOBILE_PADDING = isMobile() ? 5 : 0;
|
|
48
50
|
/**
|
|
49
51
|
* we need to check that: heightRatios - 1 < 0.000001 after calculations between decimals
|
|
50
52
|
*/
|
|
@@ -390,7 +392,8 @@ export class CanvasBoundsContainer {
|
|
|
390
392
|
this.xAxisHeight =
|
|
391
393
|
fontHeight +
|
|
392
394
|
((_a = this.config.components.xAxis.padding.top) !== null && _a !== void 0 ? _a : 0) +
|
|
393
|
-
((_b = this.config.components.xAxis.padding.bottom) !== null && _b !== void 0 ? _b : 0)
|
|
395
|
+
((_b = this.config.components.xAxis.padding.bottom) !== null && _b !== void 0 ? _b : 0) +
|
|
396
|
+
X_AXIS_MOBILE_PADDING;
|
|
394
397
|
}
|
|
395
398
|
return this.xAxisHeight;
|
|
396
399
|
}
|
|
@@ -652,10 +655,10 @@ export class CanvasBoundsContainer {
|
|
|
652
655
|
/**
|
|
653
656
|
* Gets hit-test fn for canvas element.
|
|
654
657
|
* @param {string} el - CanvasElement.ELEMENT_NAME
|
|
655
|
-
* @param {
|
|
656
|
-
* @param {number} extensionX -
|
|
657
|
-
* @param {number} extensionY -
|
|
658
|
-
* @param wholePage
|
|
658
|
+
* @param {Object} options - An object containing options for the hit test.
|
|
659
|
+
* @param {number} [options.extensionX=0] - The amount of extension in the x-axis.
|
|
660
|
+
* @param {number} [options.extensionY=0] - The amount of extension in the y-axis.
|
|
661
|
+
* @param {boolean} [options.wholePage=false] - Whether to test against the whole page or just the bounds object.
|
|
659
662
|
* @return {HitBoundsTest} hit-test fn
|
|
660
663
|
*/
|
|
661
664
|
getBoundsHitTest(el, options = DEFAULT_HIT_TEST_OPTIONS) {
|
|
@@ -15,6 +15,7 @@ import { DateTimeFormatter, TimeFormatterConfig } from './model/date-time.format
|
|
|
15
15
|
import { MergeOptions } from './utils/merge.utils';
|
|
16
16
|
import { DeepPartial } from './utils/object.utils';
|
|
17
17
|
import { Candle } from './model/candle.model';
|
|
18
|
+
import { CustomIcon } from './components/events/events-custom-icons';
|
|
18
19
|
export declare const MAIN_FONT = "Open Sans Semibold, sans-serif";
|
|
19
20
|
export interface DateTimeFormatConfig {
|
|
20
21
|
format: string;
|
|
@@ -123,12 +124,7 @@ export interface FullChartColors {
|
|
|
123
124
|
labelBoxColor: string;
|
|
124
125
|
labelTextColor: string;
|
|
125
126
|
};
|
|
126
|
-
events:
|
|
127
|
-
earnings: EventColors;
|
|
128
|
-
dividends: EventColors;
|
|
129
|
-
splits: EventColors;
|
|
130
|
-
'conference-calls': EventColors;
|
|
131
|
-
};
|
|
127
|
+
events: ChartConfigComponentsEventsColors;
|
|
132
128
|
navigationMap: {
|
|
133
129
|
buttonColor: string;
|
|
134
130
|
knotColor: string;
|
|
@@ -322,6 +318,10 @@ export interface ChartConfigComponentsChart {
|
|
|
322
318
|
selectedWidth: number;
|
|
323
319
|
minCandlesOffset: number;
|
|
324
320
|
histogram: ChartConfigComponentsHistogram;
|
|
321
|
+
/**
|
|
322
|
+
* The maximum amount of Y axis scales on a single chart
|
|
323
|
+
*/
|
|
324
|
+
maxYAxisScalesAmount: number;
|
|
325
325
|
sortCandles?: (candles: Candle[]) => Candle[];
|
|
326
326
|
}
|
|
327
327
|
export interface ChartConfigComponentsEvents {
|
|
@@ -352,6 +352,16 @@ export interface ChartConfigComponentsEvents {
|
|
|
352
352
|
* </svg>'
|
|
353
353
|
*/
|
|
354
354
|
icons?: ChartConfigComponentsEventsIcons;
|
|
355
|
+
/**
|
|
356
|
+
* Configure the event type vertical line appearance
|
|
357
|
+
*/
|
|
358
|
+
line?: ChartConfigComponentsEventsLine;
|
|
359
|
+
}
|
|
360
|
+
export interface ChartConfigComponentsEventsColors {
|
|
361
|
+
earnings: EventColors;
|
|
362
|
+
dividends: EventColors;
|
|
363
|
+
splits: EventColors;
|
|
364
|
+
'conference-calls': EventColors;
|
|
355
365
|
}
|
|
356
366
|
export interface DateTimeFormatConfig {
|
|
357
367
|
format: string;
|
|
@@ -482,6 +492,10 @@ export interface ChartConfigComponentsHighLow {
|
|
|
482
492
|
* Font config of high/low labels.
|
|
483
493
|
*/
|
|
484
494
|
font: string;
|
|
495
|
+
prefix: {
|
|
496
|
+
high: string;
|
|
497
|
+
low: string;
|
|
498
|
+
};
|
|
485
499
|
}
|
|
486
500
|
export interface ChartConfigComponentsCrossTool {
|
|
487
501
|
/**
|
|
@@ -660,9 +674,17 @@ export interface HighlightsColors {
|
|
|
660
674
|
background: string;
|
|
661
675
|
label: string;
|
|
662
676
|
}
|
|
663
|
-
|
|
677
|
+
/**
|
|
678
|
+
* @deprecated use {normal}, {hover} instead, will be removed in v6
|
|
679
|
+
*/
|
|
680
|
+
export interface EventColorsOld {
|
|
664
681
|
color: string;
|
|
665
682
|
}
|
|
683
|
+
export interface EventColors extends EventColorsOld {
|
|
684
|
+
line?: string;
|
|
685
|
+
normal?: string;
|
|
686
|
+
hover?: string;
|
|
687
|
+
}
|
|
666
688
|
export interface HistogramColors {
|
|
667
689
|
upCap: string;
|
|
668
690
|
upBottom: string;
|
|
@@ -771,15 +793,29 @@ export interface YAxisLabelsColors extends Record<YAxisLabelType, Record<string,
|
|
|
771
793
|
prePostMarket: YAxisPrePostMarketLabelColorConfig;
|
|
772
794
|
prevDayClose: YAxisLabelColorConfig;
|
|
773
795
|
}
|
|
774
|
-
export interface CustomIcon {
|
|
775
|
-
normal: string;
|
|
776
|
-
hover: string;
|
|
777
|
-
}
|
|
778
796
|
export interface ChartConfigComponentsEventsIcons {
|
|
779
797
|
earnings?: CustomIcon;
|
|
780
798
|
dividends?: CustomIcon;
|
|
781
799
|
splits?: CustomIcon;
|
|
782
|
-
|
|
800
|
+
'conference-calls'?: CustomIcon;
|
|
801
|
+
}
|
|
802
|
+
export interface ChartConfigComponentsEventsLine {
|
|
803
|
+
earnings?: {
|
|
804
|
+
width: number;
|
|
805
|
+
dash: Array<number>;
|
|
806
|
+
};
|
|
807
|
+
dividends?: {
|
|
808
|
+
width: number;
|
|
809
|
+
dash: Array<number>;
|
|
810
|
+
};
|
|
811
|
+
splits?: {
|
|
812
|
+
width: number;
|
|
813
|
+
dash: Array<number>;
|
|
814
|
+
};
|
|
815
|
+
'conference-calls'?: {
|
|
816
|
+
width: number;
|
|
817
|
+
dash: Array<number>;
|
|
818
|
+
};
|
|
783
819
|
}
|
|
784
820
|
export type CursorType = string;
|
|
785
821
|
export declare const getFontFromConfig: (config: YAxisConfig) => string;
|
|
@@ -71,6 +71,7 @@ export const getDefaultConfig = () => ({
|
|
|
71
71
|
histogram: {
|
|
72
72
|
barCapSize: 1,
|
|
73
73
|
},
|
|
74
|
+
maxYAxisScalesAmount: 10,
|
|
74
75
|
sortCandles: defaultSortCandles,
|
|
75
76
|
},
|
|
76
77
|
yAxis: {
|
|
@@ -192,7 +193,7 @@ export const getDefaultConfig = () => ({
|
|
|
192
193
|
logoWidth: 20,
|
|
193
194
|
logoHeight: 20,
|
|
194
195
|
},
|
|
195
|
-
highLow: { visible: false, font: '12px sans-serif' },
|
|
196
|
+
highLow: { visible: false, font: '12px sans-serif', prefix: { high: 'H: ', low: 'L: ' } },
|
|
196
197
|
highlights: {
|
|
197
198
|
visible: false,
|
|
198
199
|
fontFamily: 'Open Sans',
|
|
@@ -386,15 +387,35 @@ export const getDefaultConfig = () => ({
|
|
|
386
387
|
highLowTheme: { highColor: 'rgba(223,222,223,1)', lowColor: 'rgba(223,222,223,1)' },
|
|
387
388
|
instrumentInfo: { textColor: '#aeb1b3' },
|
|
388
389
|
paneResizer: {
|
|
389
|
-
lineColor: 'rgba(
|
|
390
|
+
lineColor: 'rgba(61,61,61,1)',
|
|
390
391
|
bgColor: 'rgba(20,20,19,1)',
|
|
391
392
|
bgHoverColor: 'rgba(55,55,54,0.6)',
|
|
392
393
|
},
|
|
393
394
|
events: {
|
|
394
|
-
earnings: {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
395
|
+
earnings: {
|
|
396
|
+
color: 'rgba(217,44,64,1)',
|
|
397
|
+
normal: 'rgba(217,44,64,1)',
|
|
398
|
+
hover: 'rgba(217,44,64,1)',
|
|
399
|
+
line: 'rgba(217,44,64,1)',
|
|
400
|
+
},
|
|
401
|
+
dividends: {
|
|
402
|
+
color: 'rgba(169,38,251,1)',
|
|
403
|
+
normal: 'rgba(169,38,251,1)',
|
|
404
|
+
hover: 'rgba(169,38,251,1)',
|
|
405
|
+
line: 'rgba(169,38,251,1)',
|
|
406
|
+
},
|
|
407
|
+
splits: {
|
|
408
|
+
color: 'rgba(244,187,63,1)',
|
|
409
|
+
normal: 'rgba(244,187,63,1)',
|
|
410
|
+
hover: 'rgba(244,187,63,1)',
|
|
411
|
+
line: 'rgba(244,187,63,1)',
|
|
412
|
+
},
|
|
413
|
+
'conference-calls': {
|
|
414
|
+
color: 'rgba(48,194,97,1)',
|
|
415
|
+
normal: 'rgba(48,194,97,1)',
|
|
416
|
+
hover: 'rgba(48,194,97,1)',
|
|
417
|
+
line: 'rgba(48,194,97,1)',
|
|
418
|
+
},
|
|
398
419
|
},
|
|
399
420
|
secondaryChartTheme: [
|
|
400
421
|
{
|
|
@@ -37,7 +37,7 @@ interface ChartPanningOptions {
|
|
|
37
37
|
* @param {CanvasBoundsContainer} canvasBoundsContainer - An instance of the CanvasBoundsContainer class.
|
|
38
38
|
* @param {CanvasAnimation} canvasAnimation - An instance of the CanvasAnimation class.
|
|
39
39
|
* @param {ChartPanComponent} chartPanComponent - An instance of the ChartPanComponent class.
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
*/
|
|
42
42
|
export declare class ChartAreaPanHandler extends ChartBaseElement {
|
|
43
43
|
private bus;
|
|
@@ -62,6 +62,7 @@ export declare class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
62
62
|
* If the zoomToCursor configuration is set to false, it calls the zoomXToEnd method of the scaleModel to zoom in or out based on the zoomIn parameter.
|
|
63
63
|
* Finally, it fires the draw event of the bus to redraw the canvas.
|
|
64
64
|
* @param {WheelEvent} e - Wheel event
|
|
65
|
+
* @param {number} zoomSensitivity - zoom sensitivity
|
|
65
66
|
* @returns {void}
|
|
66
67
|
*/
|
|
67
68
|
private zoomXHandler;
|
|
@@ -74,7 +75,7 @@ export declare class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
74
75
|
private calculateDynamicSesitivity;
|
|
75
76
|
/**
|
|
76
77
|
* Registers a handler for panning the chart along the Y-axis.
|
|
77
|
-
* @param {ScaleModel}
|
|
78
|
+
* @param {ScaleModel} scale - The scale model of the extent.
|
|
78
79
|
* @param {HitBoundsTest} hitTest - The hit test of the pane.
|
|
79
80
|
* @returns {DragNDropYComponent} - The drag and drop component for panning the chart along the Y-axis.
|
|
80
81
|
*/
|
|
@@ -29,7 +29,7 @@ import { DragNDropYComponent } from '../dran-n-drop_helper/drag-n-drop-y.compone
|
|
|
29
29
|
* @param {CanvasBoundsContainer} canvasBoundsContainer - An instance of the CanvasBoundsContainer class.
|
|
30
30
|
* @param {CanvasAnimation} canvasAnimation - An instance of the CanvasAnimation class.
|
|
31
31
|
* @param {ChartPanComponent} chartPanComponent - An instance of the ChartPanComponent class.
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
*/
|
|
34
34
|
export class ChartAreaPanHandler extends ChartBaseElement {
|
|
35
35
|
constructor(bus, config, scale, canvasInputListener, canvasBoundsContainer, canvasAnimation, chartPanComponent, hitTestCanvasModel) {
|
|
@@ -56,6 +56,7 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
56
56
|
* If the zoomToCursor configuration is set to false, it calls the zoomXToEnd method of the scaleModel to zoom in or out based on the zoomIn parameter.
|
|
57
57
|
* Finally, it fires the draw event of the bus to redraw the canvas.
|
|
58
58
|
* @param {WheelEvent} e - Wheel event
|
|
59
|
+
* @param {number} zoomSensitivity - zoom sensitivity
|
|
59
60
|
* @returns {void}
|
|
60
61
|
*/
|
|
61
62
|
this.zoomXHandler = (e, zoomSensitivity) => {
|
|
@@ -120,9 +121,9 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
120
121
|
.pipe(filter(() => this.chartPanningOptions.horizontal && this.chartPanningOptions.vertical), throttleTime(this.wheelThrottleTime, animationFrameScheduler, { trailing: true, leading: true }))
|
|
121
122
|
.subscribe(e => {
|
|
122
123
|
const device = deviceDetector();
|
|
123
|
-
const direction = device === 'apple' || device === 'mobile' ? 1 :
|
|
124
|
+
const direction = device === 'apple' || device === 'mobile' ? -1 : 1;
|
|
124
125
|
const deltaX = 0 + e.deltaX * direction;
|
|
125
|
-
const deltaY = 0 + e.deltaY *
|
|
126
|
+
const deltaY = 0 + e.deltaY * direction;
|
|
126
127
|
if (e.ctrlKey) {
|
|
127
128
|
const zoomSensitivity = this.calculateDynamicSesitivity(e, this.config.scale.zoomSensitivity.wheel);
|
|
128
129
|
this.zoomXHandler(e, zoomSensitivity);
|
|
@@ -162,7 +163,7 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
162
163
|
}
|
|
163
164
|
/**
|
|
164
165
|
* Registers a handler for panning the chart along the Y-axis.
|
|
165
|
-
* @param {ScaleModel}
|
|
166
|
+
* @param {ScaleModel} scale - The scale model of the extent.
|
|
166
167
|
* @param {HitBoundsTest} hitTest - The hit test of the pane.
|
|
167
168
|
* @returns {DragNDropYComponent} - The drag and drop component for panning the chart along the Y-axis.
|
|
168
169
|
*/
|
|
@@ -22,11 +22,11 @@ export class CrossToolComponent extends ChartBaseElement {
|
|
|
22
22
|
this.drawingManager = drawingManager;
|
|
23
23
|
this.paneManager = paneManager;
|
|
24
24
|
this.crossToolTypeDrawers = {};
|
|
25
|
-
this.model = new CrossToolModel(config.components.crossTool, this.crossToolCanvasModel, crossEventProducer, hoverProducer);
|
|
25
|
+
this.model = new CrossToolModel(config.components.crossTool, this.crossToolCanvasModel, crossEventProducer, hoverProducer, this.canvasBoundsContainer);
|
|
26
26
|
this.addChildEntity(this.model);
|
|
27
27
|
const clearCanvasDrawer = new ClearCanvasDrawer(this.crossToolCanvasModel);
|
|
28
28
|
this.registerDefaultDrawerTypes();
|
|
29
|
-
const crossToolDrawer = new CrossToolDrawer(this.model, this.crossToolCanvasModel, this.crossToolTypeDrawers);
|
|
29
|
+
const crossToolDrawer = new CrossToolDrawer(this.model, this.config, this.crossToolCanvasModel, this.crossToolTypeDrawers);
|
|
30
30
|
const compositeDrawer = new CompositeDrawer();
|
|
31
31
|
compositeDrawer.addDrawer(clearCanvasDrawer, 'CLEAR_CANVAS');
|
|
32
32
|
compositeDrawer.addDrawer(crossToolDrawer, 'CROSS_TOOL_DRAWER');
|
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
import { CanvasModel } from '../../model/canvas.model';
|
|
7
7
|
import { Drawer } from '../../drawers/drawing-manager';
|
|
8
8
|
import { CrossToolHover, CrossToolModel, CrossToolType } from './cross-tool.model';
|
|
9
|
+
import { FullChartConfig } from '../../chart.config';
|
|
9
10
|
export interface CrossToolTypeDrawer {
|
|
10
11
|
draw: (ctx: CanvasRenderingContext2D, hover: CrossToolHover) => void;
|
|
11
12
|
}
|
|
12
13
|
export declare class CrossToolDrawer implements Drawer {
|
|
13
14
|
private model;
|
|
15
|
+
private config;
|
|
14
16
|
private crossToolCanvasModel;
|
|
15
17
|
private readonly crossToolTypeDrawers;
|
|
16
|
-
constructor(model: CrossToolModel, crossToolCanvasModel: CanvasModel, crossToolTypeDrawers: Record<CrossToolType, CrossToolTypeDrawer>);
|
|
18
|
+
constructor(model: CrossToolModel, config: FullChartConfig, crossToolCanvasModel: CanvasModel, crossToolTypeDrawers: Record<CrossToolType, CrossToolTypeDrawer>);
|
|
17
19
|
/**
|
|
18
20
|
* Draws the cross tool on the canvas.
|
|
19
21
|
* @function
|
|
@@ -4,8 +4,9 @@
|
|
|
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
|
export class CrossToolDrawer {
|
|
7
|
-
constructor(model, crossToolCanvasModel, crossToolTypeDrawers) {
|
|
7
|
+
constructor(model, config, crossToolCanvasModel, crossToolTypeDrawers) {
|
|
8
8
|
this.model = model;
|
|
9
|
+
this.config = config;
|
|
9
10
|
this.crossToolCanvasModel = crossToolCanvasModel;
|
|
10
11
|
this.crossToolTypeDrawers = crossToolTypeDrawers;
|
|
11
12
|
}
|
|
@@ -18,12 +19,12 @@ export class CrossToolDrawer {
|
|
|
18
19
|
* @returns {void}
|
|
19
20
|
*/
|
|
20
21
|
draw() {
|
|
21
|
-
const drawer = this.crossToolTypeDrawers[this.
|
|
22
|
+
const drawer = this.crossToolTypeDrawers[this.config.components.crossTool.type];
|
|
22
23
|
if (drawer) {
|
|
23
24
|
this.model.currentHover && drawer.draw(this.crossToolCanvasModel.ctx, this.model.currentHover);
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
26
|
-
console.error(`No cross tool drawer type registered for drawer type ${this.
|
|
27
|
+
console.error(`No cross tool drawer type registered for drawer type ${this.config.components.crossTool.type}`);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
@@ -9,6 +9,7 @@ import { CrossEventProducerComponent } from '../../inputhandlers/cross-event-pro
|
|
|
9
9
|
import { Hover, HoverProducerComponent } from '../../inputhandlers/hover-producer.component';
|
|
10
10
|
import { CanvasModel } from '../../model/canvas.model';
|
|
11
11
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
12
|
+
import { CanvasBoundsContainer } from '../../canvas/canvas-bounds-container';
|
|
12
13
|
export type CrossToolType = 'cross-and-labels' | 'only-labels' | 'none' | string;
|
|
13
14
|
export interface CrossToolHover {
|
|
14
15
|
x: number;
|
|
@@ -21,11 +22,11 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
21
22
|
private crossToolCanvasModel;
|
|
22
23
|
private crossEventProducer;
|
|
23
24
|
private hoverProducer;
|
|
25
|
+
private canvasBoundsContainer;
|
|
24
26
|
currentHoverSubject: BehaviorSubject<CrossToolHover | null>;
|
|
25
27
|
get currentHover(): CrossToolHover | null;
|
|
26
28
|
set currentHover(value: CrossToolHover | null);
|
|
27
|
-
|
|
28
|
-
constructor(config: Required<ChartConfigComponentsCrossTool>, crossToolCanvasModel: CanvasModel, crossEventProducer: CrossEventProducerComponent, hoverProducer: HoverProducerComponent);
|
|
29
|
+
constructor(config: Required<ChartConfigComponentsCrossTool>, crossToolCanvasModel: CanvasModel, crossEventProducer: CrossEventProducerComponent, hoverProducer: HoverProducerComponent, canvasBoundsContainer: CanvasBoundsContainer);
|
|
29
30
|
/**
|
|
30
31
|
* Sets the type of the CrossTool object.
|
|
31
32
|
*
|
|
@@ -35,9 +36,7 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
35
36
|
setType(type: CrossToolType): void;
|
|
36
37
|
/**
|
|
37
38
|
* Method to activate the cross tool.
|
|
38
|
-
* It subscribes to the
|
|
39
|
-
* It also subscribes to the eventBus's hover and close hover events and updates the hover and fires the draw event accordingly.
|
|
40
|
-
* It also subscribes to the chartModel's candlesSetSubject and timeZoneModel's observeTimeZoneChanged events and recalculates the cross tool X formatter.
|
|
39
|
+
* It subscribes to the hoverProducer's hover event and updates the crosstool.
|
|
41
40
|
*/
|
|
42
41
|
protected doActivate(): void;
|
|
43
42
|
/**
|
|
@@ -59,5 +58,6 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
59
58
|
* @param {number} hover.candleHover.closestOHLCY - The y coordinate of the closest OHLC price of the candle.
|
|
60
59
|
* @returns {void}
|
|
61
60
|
*/
|
|
62
|
-
|
|
61
|
+
updateCrossTool(hover: Hover, magnetTarget?: import("./cross-tool.component").MagnetTarget): void;
|
|
62
|
+
private updateCrossToolMobile;
|
|
63
63
|
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { BehaviorSubject } from 'rxjs';
|
|
7
7
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
8
|
-
import { CHART_UUID } from '../../canvas/canvas-bounds-container';
|
|
8
|
+
import { CanvasElement, CHART_UUID } from '../../canvas/canvas-bounds-container';
|
|
9
|
+
import { isMobile } from '../../utils/device/browser.utils';
|
|
9
10
|
export class CrossToolModel extends ChartBaseElement {
|
|
10
11
|
get currentHover() {
|
|
11
12
|
return this.currentHoverSubject.getValue();
|
|
@@ -13,16 +14,15 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
13
14
|
set currentHover(value) {
|
|
14
15
|
this.currentHoverSubject.next(value);
|
|
15
16
|
}
|
|
16
|
-
constructor(config, crossToolCanvasModel, crossEventProducer, hoverProducer) {
|
|
17
|
+
constructor(config, crossToolCanvasModel, crossEventProducer, hoverProducer, canvasBoundsContainer) {
|
|
17
18
|
super();
|
|
18
19
|
this.config = config;
|
|
19
20
|
this.crossToolCanvasModel = crossToolCanvasModel;
|
|
20
21
|
this.crossEventProducer = crossEventProducer;
|
|
21
22
|
this.hoverProducer = hoverProducer;
|
|
23
|
+
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
22
24
|
// the main hover object which will be presented on UI
|
|
23
25
|
this.currentHoverSubject = new BehaviorSubject(null);
|
|
24
|
-
this.type = 'cross-and-labels';
|
|
25
|
-
this.type = config.type;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Sets the type of the CrossTool object.
|
|
@@ -31,19 +31,17 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
31
31
|
* @returns {void}
|
|
32
32
|
*/
|
|
33
33
|
setType(type) {
|
|
34
|
-
this.type = type;
|
|
34
|
+
this.config.type = type;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Method to activate the cross tool.
|
|
38
|
-
* It subscribes to the
|
|
39
|
-
* It also subscribes to the eventBus's hover and close hover events and updates the hover and fires the draw event accordingly.
|
|
40
|
-
* It also subscribes to the chartModel's candlesSetSubject and timeZoneModel's observeTimeZoneChanged events and recalculates the cross tool X formatter.
|
|
38
|
+
* It subscribes to the hoverProducer's hover event and updates the crosstool.
|
|
41
39
|
*/
|
|
42
40
|
doActivate() {
|
|
43
41
|
super.doActivate();
|
|
44
42
|
this.addRxSubscription(this.hoverProducer.hoverSubject.subscribe(hover => {
|
|
45
43
|
if (this.crossEventProducer.crossSubject.getValue() !== null && hover !== null) {
|
|
46
|
-
this.
|
|
44
|
+
isMobile() ? this.updateCrossToolMobile(hover) : this.updateCrossTool(hover);
|
|
47
45
|
}
|
|
48
46
|
else {
|
|
49
47
|
this.currentHover = null;
|
|
@@ -56,7 +54,7 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
56
54
|
* @private
|
|
57
55
|
*/
|
|
58
56
|
fireDraw() {
|
|
59
|
-
if (this.type !== 'none') {
|
|
57
|
+
if (this.config.type !== 'none') {
|
|
60
58
|
this.crossToolCanvasModel.fireDraw();
|
|
61
59
|
}
|
|
62
60
|
}
|
|
@@ -74,7 +72,7 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
74
72
|
* @param {number} hover.candleHover.closestOHLCY - The y coordinate of the closest OHLC price of the candle.
|
|
75
73
|
* @returns {void}
|
|
76
74
|
*/
|
|
77
|
-
|
|
75
|
+
updateCrossTool(hover, magnetTarget = this.config.magnetTarget) {
|
|
78
76
|
if (this.currentHover === null) {
|
|
79
77
|
this.currentHover = { x: hover.x, y: 0, time: hover.timeFormatted, paneId: hover.paneId };
|
|
80
78
|
}
|
|
@@ -110,4 +108,37 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
110
108
|
this.currentHover.paneId = hover.paneId;
|
|
111
109
|
this.currentHoverSubject.next(this.currentHover);
|
|
112
110
|
}
|
|
111
|
+
updateCrossToolMobile(hover) {
|
|
112
|
+
var _a;
|
|
113
|
+
// mobile crosstool works only after long touch event
|
|
114
|
+
if (!this.hoverProducer.longTouchActivatedSubject.getValue()) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const { fixed, temp, isSet } = this.crossEventProducer.crossToolTouchInfo;
|
|
118
|
+
// long touch makes crosstool fixed and the further moving will place crosstool under the current hover coordinates (ordinary logic)
|
|
119
|
+
// if crosstool is already set (long touch end event happened) the moving of chart will move crosstool according to it's initial (fixed position)
|
|
120
|
+
if (!isSet) {
|
|
121
|
+
this.updateCrossTool(hover);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// additional crosstool move logic
|
|
125
|
+
const paneBounds = this.canvasBoundsContainer.getBounds(CanvasElement.PANE_UUID(hover.paneId));
|
|
126
|
+
const offset = 5;
|
|
127
|
+
// take a difference inbetween current hover and temporary crosstool coordinates
|
|
128
|
+
const xDiff = hover.x - temp.x;
|
|
129
|
+
const yDiff = hover.y - temp.y;
|
|
130
|
+
// apply the difference to the fixed coordinates
|
|
131
|
+
const rawX = fixed.x + xDiff;
|
|
132
|
+
const rawY = fixed.y + yDiff;
|
|
133
|
+
const paneYStart = paneBounds.y + offset;
|
|
134
|
+
const paneYEnd = paneBounds.y + paneBounds.height - offset;
|
|
135
|
+
// check for chart bounds and don't move crosstool outside of it
|
|
136
|
+
const x = rawX < offset ? offset : rawX > paneBounds.width - offset ? paneBounds.width - offset : rawX;
|
|
137
|
+
const y = rawY < paneYStart ? paneYStart : rawY > paneYEnd ? paneYEnd : rawY;
|
|
138
|
+
const crossToolHover = (_a = this.hoverProducer.createHover(x, y, hover.paneId)) !== null && _a !== void 0 ? _a : hover;
|
|
139
|
+
const updatedHover = Object.assign(Object.assign({}, crossToolHover), { x,
|
|
140
|
+
y });
|
|
141
|
+
this.crossEventProducer.crossToolHover = updatedHover;
|
|
142
|
+
this.updateCrossTool(updatedHover);
|
|
143
|
+
}
|
|
113
144
|
}
|
|
@@ -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 { CanvasElement } from '../../../canvas/canvas-bounds-container';
|
|
6
|
+
import { CanvasElement, X_AXIS_MOBILE_PADDING } from '../../../canvas/canvas-bounds-container';
|
|
7
7
|
import { avoidAntialiasing, drawRoundedRect } from '../../../utils/canvas/canvas-drawing-functions.utils';
|
|
8
8
|
import { priceLabelDrawersMap } from '../../y_axis/price_labels/price-label.drawer';
|
|
9
9
|
export class CrossAndLabelsDrawerType {
|
|
@@ -98,12 +98,12 @@ export class CrossAndLabelsDrawerType {
|
|
|
98
98
|
const boxWidth = width + xLabelPaddingLeft + xLabelPaddingRight;
|
|
99
99
|
const boxHeight = fontHeight + xLabelPaddingTop + xLabelPaddingBottom;
|
|
100
100
|
const xBoxPos = Math.max(x - boxWidth / 2, 0);
|
|
101
|
-
const yBoxPos = xAxis.y + xLabelMarginTop;
|
|
101
|
+
const yBoxPos = xAxis.y + xLabelMarginTop + X_AXIS_MOBILE_PADDING / 2;
|
|
102
102
|
drawRoundedRect(ctx, xBoxPos, yBoxPos, boxWidth, boxHeight);
|
|
103
103
|
// label
|
|
104
104
|
ctx.fillStyle = crossToolColors.labelTextColor;
|
|
105
105
|
const xTextPos = Math.max(x - width / 2, xLabelPaddingLeft);
|
|
106
|
-
const yTextPos = xAxis.y + xLabelMarginTop + fontHeight + xLabelPaddingTop - 1; // -1 for vertical adjustment
|
|
106
|
+
const yTextPos = xAxis.y + xLabelMarginTop + fontHeight + X_AXIS_MOBILE_PADDING / 2 + xLabelPaddingTop - 1; // -1 for vertical adjustment
|
|
107
107
|
ctx.fillText(labelText, xTextPos, yTextPos);
|
|
108
108
|
ctx.restore();
|
|
109
109
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
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
|
+
*/
|
|
6
|
+
import { Point } from '../../inputlisteners/canvas-input-listener.component';
|
|
7
|
+
export interface CustomIcon {
|
|
8
|
+
normal: string;
|
|
9
|
+
hover: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CustomIconImage {
|
|
12
|
+
img: HTMLImageElement;
|
|
13
|
+
svgHeight: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const getIconHash: (type: string, state: keyof CustomIcon) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a custom icon for a given event type.
|
|
18
|
+
* @param {string} type - The type of the event.
|
|
19
|
+
* @param {CustomIcon} [icon] - The custom icon object containing the normal and hover images.
|
|
20
|
+
* @returns {void}
|
|
21
|
+
*/
|
|
22
|
+
export declare const createCustomIcon: (type: string, icon?: CustomIcon) => {
|
|
23
|
+
type: string;
|
|
24
|
+
normal: CustomIconImage;
|
|
25
|
+
hover: CustomIconImage;
|
|
26
|
+
} | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Creates an icon image from a string containing SVG data.
|
|
29
|
+
* @param {string} iconString - The string containing SVG data.
|
|
30
|
+
* @returns {CustomIconImage} An object containing an Image object and the height of the SVG element.
|
|
31
|
+
*/
|
|
32
|
+
export declare const createIconImage: (iconString: string) => CustomIconImage;
|
|
33
|
+
export declare const drawCustomSvgIcon: (ctx: CanvasRenderingContext2D, icons: Record<string, CustomIconImage>, point: Point, type: string, isHovered: boolean) => void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
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
|
+
*/
|
|
6
|
+
export const getIconHash = (type, state) => `${type}_${state}`;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a custom icon for a given event type.
|
|
9
|
+
* @param {string} type - The type of the event.
|
|
10
|
+
* @param {CustomIcon} [icon] - The custom icon object containing the normal and hover images.
|
|
11
|
+
* @returns {void}
|
|
12
|
+
*/
|
|
13
|
+
export const createCustomIcon = (type, icon) => {
|
|
14
|
+
if (icon) {
|
|
15
|
+
const normal = createIconImage(icon.normal);
|
|
16
|
+
const hover = createIconImage(icon.hover);
|
|
17
|
+
return { type, normal, hover };
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Creates an icon image from a string containing SVG data.
|
|
22
|
+
* @param {string} iconString - The string containing SVG data.
|
|
23
|
+
* @returns {CustomIconImage} An object containing an Image object and the height of the SVG element.
|
|
24
|
+
*/
|
|
25
|
+
export const createIconImage = (iconString) => {
|
|
26
|
+
var _a;
|
|
27
|
+
const parser = new DOMParser();
|
|
28
|
+
const svgSelector = parser.parseFromString(iconString, 'text/html').querySelector('svg');
|
|
29
|
+
let svgHeight = 0;
|
|
30
|
+
if (svgSelector) {
|
|
31
|
+
svgHeight = parseInt((_a = svgSelector.getAttribute('height')) !== null && _a !== void 0 ? _a : '', 10);
|
|
32
|
+
}
|
|
33
|
+
const svg64 = btoa(iconString);
|
|
34
|
+
const b64Start = 'data:image/svg+xml;base64,';
|
|
35
|
+
const image64 = b64Start + svg64;
|
|
36
|
+
const img = new Image();
|
|
37
|
+
img.src = image64;
|
|
38
|
+
return {
|
|
39
|
+
img,
|
|
40
|
+
svgHeight,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export const drawCustomSvgIcon = (ctx, icons, point, type, isHovered) => {
|
|
44
|
+
if (isHovered) {
|
|
45
|
+
const hover = icons[getIconHash(type, 'hover')];
|
|
46
|
+
ctx.drawImage(hover.img, point.x - hover.svgHeight / 2, point.y - hover.svgHeight / 2);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const normal = icons[getIconHash(type, 'normal')];
|
|
50
|
+
ctx.drawImage(normal.img, point.x - normal.svgHeight / 2, point.y - normal.svgHeight / 2);
|
|
51
|
+
}
|
|
52
|
+
};
|