@devexperts/dxcharts-lite 2.7.29 → 2.7.30
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/components/cross_tool/cross-tool.model.d.ts +1 -0
- package/dist/chart/components/cross_tool/cross-tool.model.js +8 -1
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +1 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +6 -3
- package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +8 -1
- package/dist/chart/components/y_axis/y-axis-labels.drawer.js +1 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +4 -0
- package/dist/chart/inputhandlers/hover-producer.component.js +47 -14
- package/dist/chart/model/scale.model.d.ts +2 -6
- package/dist/chart/model/scaling/viewport.model.d.ts +2 -0
- package/dist/chart/utils/__tests__/canvas-lower-hover-strip.utils.test.d.ts +6 -0
- package/dist/chart/utils/__tests__/canvas-lower-hover-strip.utils.test.js +34 -0
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.d.ts +1 -1
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +4 -1
- package/dist/chart/utils/canvas-lower-hover-strip.utils.d.ts +17 -0
- package/dist/chart/utils/canvas-lower-hover-strip.utils.js +20 -0
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
|
@@ -38,6 +38,7 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
38
38
|
* @returns {void}
|
|
39
39
|
*/
|
|
40
40
|
setType(type: CrossToolType): void;
|
|
41
|
+
private shouldKeepXForMobileTouchCrosshair;
|
|
41
42
|
/**
|
|
42
43
|
* Method to activate the cross tool.
|
|
43
44
|
* It subscribes to the hoverProducer's hover event and updates the crosstool.
|
|
@@ -35,6 +35,11 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
35
35
|
setType(type) {
|
|
36
36
|
this.config.type = type;
|
|
37
37
|
}
|
|
38
|
+
shouldKeepXForMobileTouchCrosshair() {
|
|
39
|
+
return (isMobile() &&
|
|
40
|
+
this.hoverProducer.longTouchActivatedSubject.getValue() &&
|
|
41
|
+
this.crossEventProducer.crossSubject.getValue() !== null);
|
|
42
|
+
}
|
|
38
43
|
/**
|
|
39
44
|
* Method to activate the cross tool.
|
|
40
45
|
* It subscribes to the hoverProducer's hover event and updates the crosstool.
|
|
@@ -100,7 +105,9 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
100
105
|
*/
|
|
101
106
|
updateCrossTool(hover, magnetTarget = this.config.magnetTarget, discrete = this.config.discrete) {
|
|
102
107
|
var _a;
|
|
103
|
-
const x = discrete
|
|
108
|
+
const x = discrete && !this.shouldKeepXForMobileTouchCrosshair()
|
|
109
|
+
? this.chartModel.toX((_a = this.chartModel.candleFromX(hover.x, true).idx) !== null && _a !== void 0 ? _a : 0)
|
|
110
|
+
: hover.x;
|
|
104
111
|
if (this.currentHover === null) {
|
|
105
112
|
this.currentHover = { x, y: 0, time: hover.timeFormatted, paneId: hover.paneId };
|
|
106
113
|
}
|
|
@@ -66,7 +66,7 @@ export function drawLabel(ctx, yAxisDescriptionsCtx, backgroundCtx, bounds, pane
|
|
|
66
66
|
}
|
|
67
67
|
const lineY = (_e = visualLabel.lineY) !== null && _e !== void 0 ? _e : visualLabel.y;
|
|
68
68
|
const _drawLine = () => showLine &&
|
|
69
|
-
avoidAntialiasing(ctx, () => drawLine(ctx, lineXStart, lineY, lineXEnd, lineY, 1, visualLabel.lineDash));
|
|
69
|
+
avoidAntialiasing(ctx, () => { var _a; return drawLine(ctx, lineXStart, lineY, lineXEnd, lineY, 1, (_a = visualLabel.lineDash) !== null && _a !== void 0 ? _a : [], visualLabel.lineCap); });
|
|
70
70
|
const _drawLabel = () => drawLabel(ctx, bounds, replaceMinusSign(text), centralY, visualLabel, config, colors.yAxis, false);
|
|
71
71
|
const drawLineLabel = () => {
|
|
72
72
|
_drawLine();
|
|
@@ -166,9 +166,12 @@ export class FancyYAxisLabelsModel extends ChartBaseElement {
|
|
|
166
166
|
* @returns {LabelGroup} - A new LabelGroup object with updated label coordinates.
|
|
167
167
|
*/
|
|
168
168
|
updateLabelsCoordinates(labels, points) {
|
|
169
|
-
return Object.assign(Object.assign({}, labels), { labels: labels.labels.map((label, idx) =>
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
return Object.assign(Object.assign({}, labels), { labels: labels.labels.map((label, idx) => {
|
|
170
|
+
var _a;
|
|
171
|
+
return (Object.assign(Object.assign({}, label), {
|
|
172
|
+
// Keep connector Y at the price level when the Y-axis price label box was shifted to avoid overlap
|
|
173
|
+
lineY: (_a = label.lineY) !== null && _a !== void 0 ? _a : label.y, y: points[idx] }));
|
|
174
|
+
}) });
|
|
172
175
|
}
|
|
173
176
|
/**
|
|
174
177
|
* Returns an Observable that emits a void value whenever the labels position is recalculated.
|
|
@@ -3,13 +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 { YAxisConfig, FullChartColors } from '../../chart.config';
|
|
6
|
+
import { YAxisConfig, FullChartColors, YAxisLabelAppearanceType, YAxisLabelMode } from '../../chart.config';
|
|
7
7
|
import { Bounds } from '../../model/bounds.model';
|
|
8
8
|
export interface YAxisLabelDrawProps {
|
|
9
9
|
ctx: CanvasRenderingContext2D;
|
|
10
10
|
bounds: Bounds;
|
|
11
11
|
text: string;
|
|
12
12
|
centralY: number;
|
|
13
|
+
lineY?: number;
|
|
13
14
|
config: YAxisLabelDrawConfig;
|
|
14
15
|
subGroupId?: number;
|
|
15
16
|
}
|
|
@@ -26,6 +27,12 @@ export interface YAxisLabelDrawConfig {
|
|
|
26
27
|
paddingStart?: number;
|
|
27
28
|
rounded?: boolean;
|
|
28
29
|
lineDash?: Array<number>;
|
|
30
|
+
/** When set (e.g. `round` with short dash gaps), strokes render as dotted segments. */
|
|
31
|
+
lineCap?: CanvasLineCap;
|
|
32
|
+
/** Overrides chart-wide `components.yAxis.labels.settings.drawings.mode` for this label (e.g. drawings). */
|
|
33
|
+
yAxisLabelMode?: YAxisLabelMode;
|
|
34
|
+
/** Overrides chart-wide `components.yAxis.labels.settings.drawings.type` for this label (e.g. drawings). */
|
|
35
|
+
yAxisLabelType?: YAxisLabelAppearanceType;
|
|
29
36
|
}
|
|
30
37
|
export declare const DEFAULT_PRICE_LABEL_PADDING = 4;
|
|
31
38
|
/**
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
9
9
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
10
10
|
*/
|
|
11
|
-
import { getFontFromConfig } from '../../chart.config';
|
|
11
|
+
import { getFontFromConfig, } from '../../chart.config';
|
|
12
12
|
import { drawPriceLabel, drawRoundedRect } from '../../utils/canvas/canvas-drawing-functions.utils';
|
|
13
13
|
import { calculateSymbolHeight, calculateTextWidth } from '../../utils/canvas/canvas-font-measure-tool.utils';
|
|
14
14
|
import { getLabelTextColorByBackgroundColor } from '../../utils/canvas/canvas-text-functions.utils';
|
|
@@ -130,6 +130,10 @@ export declare class HoverProducerComponent extends ChartBaseElement {
|
|
|
130
130
|
*/
|
|
131
131
|
fireLastCross(): void;
|
|
132
132
|
setLongTouchCrosshairSuppressed(value: boolean): void;
|
|
133
|
+
/**
|
|
134
|
+
* Resets the current crosshair/touch state back to the default mobile idle state.
|
|
135
|
+
*/
|
|
136
|
+
resetCrossTool(clearMobile?: boolean): void;
|
|
133
137
|
/**
|
|
134
138
|
* Registers a hover producer part with the given id.
|
|
135
139
|
*
|
|
@@ -134,7 +134,7 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
134
134
|
this.paneManager.chartPanComponent.setChartPanningOptions(false, false);
|
|
135
135
|
}));
|
|
136
136
|
this.addRxSubscription(this.canvasInputListener.observeTouchEndDocument().subscribe(event => {
|
|
137
|
-
var _a, _b;
|
|
137
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
138
138
|
const { clientX, clientY } = event.changedTouches[0];
|
|
139
139
|
const { fixed, temp } = this.crossEventProducer.crossToolTouchInfo;
|
|
140
140
|
const x = clientX - this.canvasBoundsContainer.canvasOnPageLocation.x;
|
|
@@ -142,28 +142,32 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
142
142
|
// common tap without moving, hide crosstool
|
|
143
143
|
if (this.crossEventProducer.crossToolTouchInfo.isCommonTap &&
|
|
144
144
|
!checkChartIsMoving(x, temp.x, y, temp.y)) {
|
|
145
|
-
this.
|
|
146
|
-
this.longTouchActivatedSubject.next(false);
|
|
147
|
-
this.crossEventProducer.fireCrossClose();
|
|
148
|
-
this.crossEventProducer.crossToolHover = null;
|
|
149
|
-
this.crossEventProducer.crossToolTouchInfo.isSet = false;
|
|
145
|
+
this.resetCrossTool();
|
|
150
146
|
return;
|
|
151
147
|
}
|
|
152
148
|
if (!this.crossEventProducer.crossToolTouchInfo.isSet) {
|
|
153
149
|
this.crossEventProducer.crossToolTouchInfo.isSet = true;
|
|
154
|
-
|
|
150
|
+
const crossToolHover = this.crossEventProducer.crossToolHover;
|
|
151
|
+
const anchorX = (_a = crossToolHover === null || crossToolHover === void 0 ? void 0 : crossToolHover.x) !== null && _a !== void 0 ? _a : x;
|
|
152
|
+
const anchorY = (_b = crossToolHover === null || crossToolHover === void 0 ? void 0 : crossToolHover.y) !== null && _b !== void 0 ? _b : y;
|
|
155
153
|
this.crossEventProducer.crossToolTouchInfo.temp = {
|
|
156
|
-
x:
|
|
157
|
-
y:
|
|
154
|
+
x: anchorX,
|
|
155
|
+
y: anchorY,
|
|
158
156
|
};
|
|
159
157
|
this.crossEventProducer.crossToolTouchInfo.fixed = {
|
|
160
|
-
x,
|
|
161
|
-
y,
|
|
158
|
+
x: anchorX,
|
|
159
|
+
y: anchorY,
|
|
162
160
|
};
|
|
163
|
-
this.
|
|
161
|
+
const paneId = (_e = (_c = crossToolHover === null || crossToolHover === void 0 ? void 0 : crossToolHover.paneId) !== null && _c !== void 0 ? _c : (_d = this.paneManager.getPaneIfHit({ x: anchorX, y: anchorY })) === null || _d === void 0 ? void 0 : _d.uuid) !== null && _e !== void 0 ? _e : '';
|
|
162
|
+
const hover = crossToolHover !== null && crossToolHover !== void 0 ? crossToolHover : this.hover;
|
|
163
|
+
if (!hover) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
this.crossEventProducer.crossToolHover = Object.assign(Object.assign({}, hover), { x: anchorX, y: anchorY, paneId });
|
|
167
|
+
this.crossEventProducer.crossSubject.next([anchorX, anchorY, paneId]);
|
|
164
168
|
}
|
|
165
169
|
else {
|
|
166
|
-
const pane = (
|
|
170
|
+
const pane = (_g = (_f = this.crossEventProducer.crossToolHover) === null || _f === void 0 ? void 0 : _f.paneId) !== null && _g !== void 0 ? _g : 'CHART';
|
|
167
171
|
const paneBounds = this.canvasBoundsContainer.getBounds(CanvasElement.PANE_UUID(pane));
|
|
168
172
|
const paneYStart = paneBounds.y + 5;
|
|
169
173
|
const paneYEnd = paneBounds.y + paneBounds.height - 5;
|
|
@@ -172,6 +176,13 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
172
176
|
const newX = fixed.x < 0 ? 0 : fixed.x > paneBounds.width ? paneBounds.width : (fixed.x += xDiff);
|
|
173
177
|
const newY = fixed.y < paneYStart ? paneYStart : fixed.y > paneYEnd ? paneYEnd : (fixed.y += yDiff);
|
|
174
178
|
this.crossEventProducer.crossToolTouchInfo.fixed = { x: newX, y: newY };
|
|
179
|
+
this.crossEventProducer.crossToolTouchInfo.temp = { x: newX, y: newY };
|
|
180
|
+
const hover = (_h = this.crossEventProducer.crossToolHover) !== null && _h !== void 0 ? _h : this.hover;
|
|
181
|
+
if (!hover) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
this.crossEventProducer.crossToolHover = Object.assign(Object.assign({}, hover), { x: newX, y: newY, paneId: pane });
|
|
185
|
+
this.crossEventProducer.crossSubject.next([newX, newY, pane]);
|
|
175
186
|
}
|
|
176
187
|
}));
|
|
177
188
|
//#endregion
|
|
@@ -236,9 +247,16 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
236
247
|
* @param {VisualCandle} candle - The VisualCandle object to create the hover from.
|
|
237
248
|
*/
|
|
238
249
|
updateHover(candle) {
|
|
250
|
+
var _a, _b;
|
|
239
251
|
const updatedHover = this.createHoverFromCandle(candle);
|
|
240
252
|
if (this.hover && updatedHover) {
|
|
241
|
-
const
|
|
253
|
+
const shouldKeepSetTouchCrosshair = isMobile() &&
|
|
254
|
+
this.longTouchActivatedSubject.getValue() &&
|
|
255
|
+
this.crossEventProducer.crossSubject.getValue() !== null;
|
|
256
|
+
const crossToolHover = this.crossEventProducer.crossToolHover;
|
|
257
|
+
const hoverX = shouldKeepSetTouchCrosshair ? ((_a = crossToolHover === null || crossToolHover === void 0 ? void 0 : crossToolHover.x) !== null && _a !== void 0 ? _a : this.hover.x) : this.hover.x;
|
|
258
|
+
const hoverY = shouldKeepSetTouchCrosshair ? ((_b = crossToolHover === null || crossToolHover === void 0 ? void 0 : crossToolHover.y) !== null && _b !== void 0 ? _b : this.hover.y) : this.hover.y;
|
|
259
|
+
const hover = Object.assign(Object.assign({}, updatedHover), { x: hoverX, y: hoverY });
|
|
242
260
|
this.fireHover(hover);
|
|
243
261
|
}
|
|
244
262
|
}
|
|
@@ -293,6 +311,21 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
293
311
|
setLongTouchCrosshairSuppressed(value) {
|
|
294
312
|
this.longTouchCrosshairSuppressed = value;
|
|
295
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Resets the current crosshair/touch state back to the default mobile idle state.
|
|
316
|
+
*/
|
|
317
|
+
resetCrossTool(clearMobile = false) {
|
|
318
|
+
this.paneManager.chartPanComponent.setChartPanningOptions(true, true);
|
|
319
|
+
this.longTouchActivatedSubject.next(false);
|
|
320
|
+
this.crossEventProducer.fireCrossClose();
|
|
321
|
+
this.crossEventProducer.crossToolHover = null;
|
|
322
|
+
this.crossEventProducer.crossToolTouchInfo.isSet = false;
|
|
323
|
+
if (clearMobile) {
|
|
324
|
+
this.crossEventProducer.crossToolTouchInfo.isCommonTap = false;
|
|
325
|
+
this.crossEventProducer.crossToolTouchInfo.fixed = { x: 0, y: 0 };
|
|
326
|
+
this.crossEventProducer.crossToolTouchInfo.temp = { x: 0, y: 0 };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
296
329
|
/**
|
|
297
330
|
* Registers a hover producer part with the given id.
|
|
298
331
|
*
|
|
@@ -7,7 +7,7 @@ import { Subject } from 'rxjs';
|
|
|
7
7
|
import { ChartConfigComponentsOffsets, ChartScale, FullChartConfig } from '../chart.config';
|
|
8
8
|
import { CanvasAnimation } from '../animation/canvas-animation';
|
|
9
9
|
import { AutoScaleViewportSubModel } from './scaling/auto-scale.model';
|
|
10
|
-
import { Price, Unit, ViewportModel, ViewportModelState, Zoom } from './scaling/viewport.model';
|
|
10
|
+
import { Price, Unit, ViewportModel, ViewportModelState, XScale, YScale, Zoom } from './scaling/viewport.model';
|
|
11
11
|
import { BoundsProvider } from './bounds.model';
|
|
12
12
|
import VisualCandle from './visual-candle';
|
|
13
13
|
export interface HighLowWithIndex {
|
|
@@ -16,11 +16,7 @@ export interface HighLowWithIndex {
|
|
|
16
16
|
highIdx: number;
|
|
17
17
|
lowIdx: number;
|
|
18
18
|
}
|
|
19
|
-
export interface ScaleHistoryItem {
|
|
20
|
-
xStart: Unit;
|
|
21
|
-
xEnd: Unit;
|
|
22
|
-
yStart: Unit;
|
|
23
|
-
yEnd: Unit;
|
|
19
|
+
export interface ScaleHistoryItem extends XScale, YScale {
|
|
24
20
|
}
|
|
25
21
|
export declare const getDefaultHighLowWithIndex: () => HighLowWithIndex;
|
|
26
22
|
export type ViewportPercent = number;
|
|
@@ -57,6 +57,8 @@ export interface ViewportModelState {
|
|
|
57
57
|
zoomY: Zoom;
|
|
58
58
|
inverseY: boolean;
|
|
59
59
|
}
|
|
60
|
+
export type XScale = Pick<ViewportModelState, 'xStart' | 'xEnd'>;
|
|
61
|
+
export type YScale = Pick<ViewportModelState, 'yStart' | 'yEnd'>;
|
|
60
62
|
/**
|
|
61
63
|
* Abstract viewport model.
|
|
62
64
|
* Viewport has 4 coordinates: xStart, xEnd, yStart and yEnd - all stored in {@link Unit}.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2026 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 {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2026 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 { isCanvasPointInLowerHoverStrip } from '../canvas-lower-hover-strip.utils';
|
|
7
|
+
const baseBounds = () => ({
|
|
8
|
+
x: 0,
|
|
9
|
+
y: 0,
|
|
10
|
+
pageX: 0,
|
|
11
|
+
pageY: 0,
|
|
12
|
+
width: 1000,
|
|
13
|
+
height: 1000,
|
|
14
|
+
});
|
|
15
|
+
describe('canvas-lower-hover-strip.utils', () => {
|
|
16
|
+
it('returns true for a point in the lower strip (bottom offset 0)', () => {
|
|
17
|
+
const b = baseBounds();
|
|
18
|
+
expect(isCanvasPointInLowerHoverStrip({ x: 500, y: 900 }, b, 0)).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it('returns false for a point in the upper area', () => {
|
|
21
|
+
const b = baseBounds();
|
|
22
|
+
expect(isCanvasPointInLowerHoverStrip({ x: 500, y: 100 }, b, 0)).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
it('shifts the strip when bottomOffsetPx is non-zero', () => {
|
|
25
|
+
const b = baseBounds();
|
|
26
|
+
const yAtStripStartNoOffset = b.height * 0.85 + 10;
|
|
27
|
+
expect(isCanvasPointInLowerHoverStrip({ x: 1, y: yAtStripStartNoOffset - 1 }, b, 0)).toBe(false);
|
|
28
|
+
expect(isCanvasPointInLowerHoverStrip({ x: 1, y: yAtStripStartNoOffset }, b, 0)).toBe(true);
|
|
29
|
+
const bottomOffset = 50;
|
|
30
|
+
const yAtStripStartWithOffset = b.height * 0.85 - bottomOffset + 10;
|
|
31
|
+
expect(isCanvasPointInLowerHoverStrip({ x: 1, y: yAtStripStartWithOffset - 1 }, b, bottomOffset)).toBe(false);
|
|
32
|
+
expect(isCanvasPointInLowerHoverStrip({ x: 1, y: yAtStripStartWithOffset }, b, bottomOffset)).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -46,7 +46,7 @@ export declare function drawPriceLabel(ctx: CanvasRenderingContext2D, x0: number
|
|
|
46
46
|
*
|
|
47
47
|
* @returns {void}
|
|
48
48
|
*/
|
|
49
|
-
export declare function drawLine(ctx: CanvasRenderingContext2D, x0: number, y0: number, x1: number, y1: number, thickness?: number, lineDash?: Array<number
|
|
49
|
+
export declare function drawLine(ctx: CanvasRenderingContext2D, x0: number, y0: number, x1: number, y1: number, thickness?: number, lineDash?: Array<number>, lineCap?: CanvasLineCap): void;
|
|
50
50
|
/**
|
|
51
51
|
* Try to avoid anti-aliasing
|
|
52
52
|
*/
|
|
@@ -109,10 +109,13 @@ export function drawPriceLabel(ctx, x0, y0, x1, y1, x2, y2, _width, rounded, ali
|
|
|
109
109
|
*
|
|
110
110
|
* @returns {void}
|
|
111
111
|
*/
|
|
112
|
-
export function drawLine(ctx, x0, y0, x1, y1, thickness = 1, lineDash = []) {
|
|
112
|
+
export function drawLine(ctx, x0, y0, x1, y1, thickness = 1, lineDash = [], lineCap) {
|
|
113
113
|
ctx.save();
|
|
114
114
|
ctx.setLineDash(lineDash);
|
|
115
115
|
ctx.lineWidth = thickness;
|
|
116
|
+
if (lineCap !== undefined) {
|
|
117
|
+
ctx.lineCap = lineCap;
|
|
118
|
+
}
|
|
116
119
|
ctx.beginPath();
|
|
117
120
|
ctx.moveTo(x0, y0);
|
|
118
121
|
ctx.lineTo(x1, y1);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2026 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 { Bounds } from '../model/bounds.model';
|
|
7
|
+
export interface CanvasPointerPoint {
|
|
8
|
+
readonly x: number;
|
|
9
|
+
readonly y: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Canvas-space hit test for the lower band (time scale / volume strip).
|
|
13
|
+
* Reusable for any UI that should react when the pointer is near the bottom of the chart.
|
|
14
|
+
*
|
|
15
|
+
* Rectangle matches the Figma hover region (full width, lower ~15% of canvas height plus offsets).
|
|
16
|
+
*/
|
|
17
|
+
export declare function isCanvasPointInLowerHoverStrip(point: CanvasPointerPoint, canvasBounds: Bounds, bottomOffsetPx: number): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2026 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
|
+
/**
|
|
7
|
+
* Canvas-space hit test for the lower band (time scale / volume strip).
|
|
8
|
+
* Reusable for any UI that should react when the pointer is near the bottom of the chart.
|
|
9
|
+
*
|
|
10
|
+
* Rectangle matches the Figma hover region (full width, lower ~15% of canvas height plus offsets).
|
|
11
|
+
*/
|
|
12
|
+
export function isCanvasPointInLowerHoverStrip(point, canvasBounds, bottomOffsetPx) {
|
|
13
|
+
const rectX = 0;
|
|
14
|
+
const rectY = canvasBounds.height * 0.85 - bottomOffsetPx + 10;
|
|
15
|
+
const rectWidth = canvasBounds.width;
|
|
16
|
+
const rectHeight = canvasBounds.height * 0.15 + bottomOffsetPx + 10;
|
|
17
|
+
const dx = point.x - rectX;
|
|
18
|
+
const dy = point.y - rectY;
|
|
19
|
+
return dx >= 0 && dx < rectWidth && dy >= 0 && dy < rectHeight;
|
|
20
|
+
}
|