Skip to content

Commit 7c48c08

Browse files
Keelaro1dxcity
authored and
dxcity
committed
Pull request #5506: Bugfix/DXCF-5742 indicators it s difficult to open the right click menu for some indicators
Merge in DXCHARTS/dxchart5 from bugfix/DXCF-5742-indicators-it-s-difficult-to-open-the-right-click-menu-for-some-indicators to master * commit '46184b2f67a1391d294feb2b82782bd067516e88': [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // remove copy [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // pr fix [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init [DXCF-5742] Indicators - It's difficult to open the right-click menu for some indicators // init GitOrigin-RevId: 565d3e991cb9c82d73f65170c2bda2ee302a2b5b
1 parent 4b3bae5 commit 7c48c08

21 files changed

+151
-135
lines changed

docs/how-to/custom-data-series-drawer/README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const myDrawer = {
1313
ctx, // CanvasRenderingContext2D
1414
allPoints, // VisualSeriesPoint[][]
1515
model, // DataSeriesModel - can be also CandleSeriesModel - in this case points have all candle fields
16-
drawerConfig, // ChartDrawerConfig
16+
hitTestDrawerConfig, // HTSeriesDrawerConfig
1717
) {
1818
allPoints.forEach((points, idx) => {
1919
const allPoints = points.flat();
@@ -25,12 +25,12 @@ const myDrawer = {
2525
if (point.close > prevPoint?.close) {
2626
// it is not necessary to save and restore when modifying the context state
2727
// - it is done by DataSeriesDrawer, which calls draw() method of specific data series drawer
28-
ctx.fillStyle = drawerConfig.singleColor ?? 'green';
28+
ctx.fillStyle = hitTestDrawerConfig.color ?? 'green';
2929
ctx.fillText('', x, y);
3030
} else {
31-
// drawerConfig.singleColor is defined when the drawer is drawn by hit test drawer
32-
// in order to work with hit test correctly you have to use drawerConfig.singleColor if it's defined
33-
ctx.fillStyle = drawerConfig.singleColor ?? 'red';
31+
// hitTestDrawerConfig.color is defined when the drawer is drawn by hit test drawer
32+
// in order to work with hit test correctly you have to use hitTestDrawerConfig.color if it's defined
33+
ctx.fillStyle = hitTestDrawerConfig.color ?? 'red';
3434
ctx.fillText('', x, y);
3535
}
3636
}

docs/how-to/custom-data-series-drawer/index.html

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h1>Chart custom data-series drawer example</h1>
3737
ctx, // CanvasRenderingContext2D
3838
allPoints, // VisualSeriesPoint[][]
3939
model, // DataSeriesModel - can be also CandleSeriesModel - in this case points have all candle fields
40-
drawerConfig, // ChartDrawerConfig
40+
hitTestDrawerConfig, // HTSeriesDrawerConfig
4141
) {
4242
allPoints.forEach((points, idx) => {
4343
const allPoints = points.flat();
@@ -49,12 +49,12 @@ <h1>Chart custom data-series drawer example</h1>
4949
if (point.close > prevPoint?.close) {
5050
// it is not necessary to save and restore when modifying the context state
5151
// - it is done by DataSeriesDrawer, which calls draw() method of specific data series drawer
52-
ctx.fillStyle = drawerConfig.singleColor ?? 'green';
52+
ctx.fillStyle = hitTestDrawerConfig.color ?? 'green';
5353
ctx.fillText('⬆', x, y);
5454
} else {
55-
// drawerConfig.singleColor is defined when the drawer is drawn by hit test drawer
56-
// in order to work with hit test correctly you have to use drawerConfig.singleColor if it's defined
57-
ctx.fillStyle = drawerConfig.singleColor ?? 'red';
55+
// hitTestDrawerConfig.color is defined when the drawer is drawn by hit test drawer
56+
// in order to work with hit test correctly you have to use hitTestDrawerConfig.color if it's defined
57+
ctx.fillStyle = hitTestDrawerConfig.color ?? 'red';
5858
ctx.fillText('⬇', x, y);
5959
}
6060
}

src/chart/drawers/chart-type-drawers/area.drawer.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.mode
99
import VisualCandle from '../../model/visual-candle';
1010
import { flat } from '../../utils/array.utils';
1111
import { floor } from '../../utils/math.utils';
12-
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
12+
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';
1313

1414
export class AreaDrawer implements SeriesDrawer {
1515
constructor(private config: ChartConfigComponentsChart) {}
@@ -18,16 +18,16 @@ export class AreaDrawer implements SeriesDrawer {
1818
ctx: CanvasRenderingContext2D,
1919
points: VisualSeriesPoint[][],
2020
model: DataSeriesModel,
21-
drawerConfig: ChartDrawerConfig,
21+
hitTestDrawerConfig: HTSeriesDrawerConfig,
2222
) {
2323
if (model instanceof CandleSeriesModel) {
2424
// @ts-ignore
2525
const visualCandles: VisualCandle[] = flat(points);
2626
if (visualCandles.length === 0) {
2727
return;
2828
}
29-
if (drawerConfig.singleColor) {
30-
ctx.strokeStyle = drawerConfig.singleColor;
29+
if (hitTestDrawerConfig.color) {
30+
ctx.strokeStyle = hitTestDrawerConfig.color;
3131
} else {
3232
ctx.strokeStyle = model.colors.areaTheme.lineColor;
3333
}
@@ -62,8 +62,8 @@ export class AreaDrawer implements SeriesDrawer {
6262
ctx.closePath();
6363

6464
let fillColor: CanvasGradient;
65-
if (drawerConfig.singleColor) {
66-
ctx.fillStyle = drawerConfig.singleColor;
65+
if (hitTestDrawerConfig.color) {
66+
ctx.fillStyle = hitTestDrawerConfig.color;
6767
} else {
6868
ctx.fillStyle =
6969
model.colors.areaTheme.startColor && model.colors.areaTheme.stopColor

src/chart/drawers/chart-type-drawers/bar.drawer.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ import VisualCandle from '../../model/visual-candle';
1010
import { flat } from '../../utils/array.utils';
1111
import { avoidAntialiasing } from '../../utils/canvas/canvas-drawing-functions.utils';
1212
import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
13-
import { ChartDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
13+
import { HTSeriesDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
1414

1515
export class BarDrawer implements SeriesDrawer {
1616
constructor(private config: ChartConfigComponentsChart) {}
1717

1818
private setFillStyle(
1919
ctx: CanvasRenderingContext2D,
20-
drawerConfig: ChartDrawerConfig,
20+
hitTestDrawerConfig: HTSeriesDrawerConfig,
2121
candleSeries: CandleSeriesModel,
2222
visualCandle: VisualCandle,
2323
) {
24-
if (drawerConfig.singleColor) {
25-
ctx.strokeStyle = drawerConfig.singleColor;
24+
if (hitTestDrawerConfig.color) {
25+
ctx.strokeStyle = hitTestDrawerConfig.color;
2626
} else {
2727
const barTheme = candleSeries.colors.barTheme;
2828
if (barTheme) {
@@ -35,15 +35,15 @@ export class BarDrawer implements SeriesDrawer {
3535
ctx: CanvasRenderingContext2D,
3636
points: VisualSeriesPoint[][],
3737
candleSeries: DataSeriesModel,
38-
drawerConfig: ChartDrawerConfig,
38+
hitTestDrawerConfig: HTSeriesDrawerConfig,
3939
) {
4040
if (candleSeries instanceof CandleSeriesModel) {
4141
// @ts-ignore
4242
const visualCandles: VisualCandle[] = flat(points);
43-
setLineWidth(ctx, this.config.barLineWidth, candleSeries, drawerConfig);
43+
setLineWidth(ctx, this.config.barLineWidth, candleSeries, hitTestDrawerConfig);
4444
avoidAntialiasing(ctx, () => {
4545
for (const visualCandle of visualCandles) {
46-
this.setFillStyle(ctx, drawerConfig, candleSeries, visualCandle);
46+
this.setFillStyle(ctx, hitTestDrawerConfig, candleSeries, visualCandle);
4747
ctx.beginPath();
4848
const bodyLineX = candleSeries.view.toX(visualCandle.centerUnit);
4949
const openLineStartX = candleSeries.view.toX(visualCandle.startUnit);

src/chart/drawers/chart-type-drawers/baseline.drawer.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
2+
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
33
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
44
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*/
@@ -9,7 +9,7 @@ import { CandleSeriesModel } from '../../model/candle-series.model';
99
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
1010
import { Pixel } from '../../model/scaling/viewport.model';
1111
import { flat } from '../../utils/array.utils';
12-
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
12+
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';
1313

1414
export class BaselineDrawer implements SeriesDrawer {
1515
constructor(private baseLineModel: BaselineModel, private canvasBoundContainer: CanvasBoundsContainer) {}
@@ -18,9 +18,9 @@ export class BaselineDrawer implements SeriesDrawer {
1818
ctx: CanvasRenderingContext2D,
1919
points: VisualSeriesPoint[][],
2020
model: DataSeriesModel,
21-
drawerConfig?: ChartDrawerConfig,
21+
hitTestDrawerConfig?: HTSeriesDrawerConfig,
2222
) {
23-
if (drawerConfig !== undefined && model instanceof CandleSeriesModel) {
23+
if (hitTestDrawerConfig !== undefined && model instanceof CandleSeriesModel) {
2424
const visualCandles = flat(points);
2525
// calculate baseline
2626
const baselineYPercents = this.baseLineModel.baselineYPercents;
@@ -41,7 +41,7 @@ export class BaselineDrawer implements SeriesDrawer {
4141
const curHigherThanBL = currentCloseYPx < baseLine;
4242

4343
if (prev !== void 0 && prevHigherThanBL !== curHigherThanBL) {
44-
setBaselineFillStyle(ctx, model, drawerConfig, prevHigherThanBL);
44+
setBaselineFillStyle(ctx, model, hitTestDrawerConfig, prevHigherThanBL);
4545

4646
const prevLineXPx = model.view.toX(prev.centerUnit);
4747
const prevCloseYPx = model.view.toY(prev.close);
@@ -69,7 +69,7 @@ export class BaselineDrawer implements SeriesDrawer {
6969
ctx.beginPath();
7070
ctx.moveTo(currentLineXPx, currentCloseYPx);
7171
} else if (next === void 0) {
72-
setBaselineFillStyle(ctx, model, drawerConfig, curHigherThanBL);
72+
setBaselineFillStyle(ctx, model, hitTestDrawerConfig, curHigherThanBL);
7373
ctx.lineTo(currentLineXPx, currentCloseYPx);
7474
ctx.stroke();
7575
ctx.lineTo(currentLineXPx, baseLine);
@@ -93,12 +93,12 @@ export class BaselineDrawer implements SeriesDrawer {
9393
const setBaselineFillStyle = (
9494
ctx: CanvasRenderingContext2D,
9595
candleSeries: CandleSeriesModel,
96-
drawerConfig: ChartDrawerConfig,
96+
hitTestDrawerConfig: HTSeriesDrawerConfig,
9797
upper: boolean,
9898
): void => {
99-
if (drawerConfig.singleColor) {
100-
ctx.fillStyle = drawerConfig.singleColor;
101-
ctx.strokeStyle = drawerConfig.singleColor;
99+
if (hitTestDrawerConfig.color) {
100+
ctx.fillStyle = hitTestDrawerConfig.color;
101+
ctx.strokeStyle = hitTestDrawerConfig.color;
102102
} else {
103103
ctx.fillStyle = upper
104104
? candleSeries.colors.baseLineTheme.upperSectionFillColor

src/chart/drawers/chart-type-drawers/candle.drawer.ts

+21-17
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CandleTheme, ChartConfigComponentsChart } from '../../chart.config';
88
import VisualCandle from '../../model/visual-candle';
99
import { avoidAntialiasing } from '../../utils/canvas/canvas-drawing-functions.utils';
1010
import { dpr } from '../../utils/device/device-pixel-ratio.utils';
11-
import { ChartDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
11+
import { HTSeriesDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
1212
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
1313
import { flat } from '../../utils/array.utils';
1414

@@ -42,21 +42,21 @@ export class CandleDrawer implements SeriesDrawer {
4242
*/
4343
points: VisualSeriesPoint[][],
4444
model: DataSeriesModel,
45-
drawerConfig: ChartDrawerConfig,
45+
hitTestDrawerConfig: HTSeriesDrawerConfig,
4646
) {
4747
if (model instanceof CandleSeriesModel) {
4848
// @ts-ignore
4949
const visualCandles: VisualCandle[] = flat(points);
5050
// TODO FIXME draw called 3-4 times on single candle update even if multichart is off
51-
setLineWidth(ctx, this.config.candleLineWidth, model, drawerConfig, this.config.candleLineWidth);
51+
setLineWidth(ctx, this.config.candleLineWidth, model, hitTestDrawerConfig, this.config.candleLineWidth);
5252
avoidAntialiasing(ctx, () => {
5353
this.pixelLength = 1 / dpr;
5454
this.halfLineWidthCU = ctx.lineWidth / 2;
5555
this.lineWidthCU = ctx.lineWidth;
5656
for (const visualCandle of visualCandles) {
5757
const { candleTheme, activeCandleTheme } = model.colors;
5858
if (candleTheme && activeCandleTheme) {
59-
this.drawCandle(ctx, drawerConfig, model, visualCandle);
59+
this.drawCandle(ctx, hitTestDrawerConfig, model, visualCandle);
6060
}
6161
}
6262
});
@@ -65,7 +65,7 @@ export class CandleDrawer implements SeriesDrawer {
6565

6666
drawCandle(
6767
ctx: CanvasRenderingContext2D,
68-
drawerConfig: ChartDrawerConfig,
68+
hitTestDrawerConfig: HTSeriesDrawerConfig,
6969
candleSeries: CandleSeriesModel,
7070
visualCandle: VisualCandle,
7171
) {
@@ -75,8 +75,8 @@ export class CandleDrawer implements SeriesDrawer {
7575
const isHollow = visualCandle.isHollow;
7676

7777
// choose candle filling color
78-
if (drawerConfig.singleColor) {
79-
ctx.fillStyle = drawerConfig.singleColor;
78+
if (hitTestDrawerConfig.color) {
79+
ctx.fillStyle = hitTestDrawerConfig.color;
8080
} else if (isHollow) {
8181
ctx.fillStyle = currentCandleTheme[`${direction}WickColor`];
8282
} else {
@@ -96,8 +96,8 @@ export class CandleDrawer implements SeriesDrawer {
9696
ctx.fillStyle = candleColor;
9797

9898
// wick style, borders are drawn after the wicks, so style for borders will be changed in drawBorder method
99-
if (drawerConfig.singleColor) {
100-
ctx.strokeStyle = drawerConfig.singleColor;
99+
if (hitTestDrawerConfig.color) {
100+
ctx.strokeStyle = hitTestDrawerConfig.color;
101101
} else {
102102
ctx.strokeStyle = wickColor;
103103
}
@@ -136,7 +136,7 @@ export class CandleDrawer implements SeriesDrawer {
136136
}
137137
this.drawCandleBorder(
138138
ctx,
139-
drawerConfig,
139+
hitTestDrawerConfig,
140140
currentCandleTheme,
141141
visualCandle,
142142
baseX + this.halfLineWidthCU,
@@ -155,16 +155,20 @@ export class CandleDrawer implements SeriesDrawer {
155155
const paddingBaseX = baseX + paddingWidthOffset;
156156
const paddingWidth = width - paddingWidthOffset * 2;
157157
if (!isHollow) {
158-
if (drawerConfig.singleColor) {
159-
ctx.fillStyle = drawerConfig.singleColor;
158+
if (hitTestDrawerConfig.color) {
159+
ctx.fillStyle = hitTestDrawerConfig.color;
160160
}
161-
ctx.fillRect(paddingBaseX, bodyStart, paddingWidth, bodyH);
161+
const bodyWidth = hitTestDrawerConfig.hoverWidth ? width + paddingWidthOffset : paddingWidth;
162+
const bodyHeight = hitTestDrawerConfig.hoverWidth
163+
? bodyH + hitTestDrawerConfig.hoverWidth + paddingWidthOffset
164+
: bodyH;
165+
ctx.fillRect(paddingBaseX, bodyStart, bodyWidth, bodyHeight);
162166
}
163167
// choose border color around candle and draw candle
164168
if (showCandleBorder) {
165169
this.drawCandleBorder(
166170
ctx,
167-
drawerConfig,
171+
hitTestDrawerConfig,
168172
currentCandleTheme,
169173
visualCandle,
170174
paddingBaseX + this.halfLineWidthCU,
@@ -199,16 +203,16 @@ export class CandleDrawer implements SeriesDrawer {
199203

200204
private drawCandleBorder(
201205
ctx: CanvasRenderingContext2D,
202-
drawerConfig: ChartDrawerConfig,
206+
hitTestDrawerConfig: HTSeriesDrawerConfig,
203207
candleTheme: CandleTheme,
204208
visualCandle: VisualCandle,
205209
x: number,
206210
y: number,
207211
w: number,
208212
h: number,
209213
) {
210-
if (drawerConfig.singleColor) {
211-
ctx.strokeStyle = drawerConfig.singleColor;
214+
if (hitTestDrawerConfig.color) {
215+
ctx.strokeStyle = hitTestDrawerConfig.color;
212216
} else {
213217
const direction = visualCandle.name;
214218
ctx.strokeStyle =

src/chart/drawers/chart-type-drawers/histogram.drawer.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CandleSeriesModel } from '../../model/candle-series.model';
88
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
99
import VisualCandle from '../../model/visual-candle';
1010
import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
11-
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
11+
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';
1212

1313
export class HistogramDrawer implements SeriesDrawer {
1414
constructor(private config: ChartConfigComponentsHistogram) {}
@@ -17,7 +17,7 @@ export class HistogramDrawer implements SeriesDrawer {
1717
ctx: CanvasRenderingContext2D,
1818
points: VisualSeriesPoint[][],
1919
model: DataSeriesModel,
20-
drawerConfig: ChartDrawerConfig,
20+
hitTestDrawerConfig: HTSeriesDrawerConfig,
2121
) {
2222
if (model instanceof CandleSeriesModel) {
2323
// @ts-ignore
@@ -32,8 +32,8 @@ export class HistogramDrawer implements SeriesDrawer {
3232
if (histogramColors === undefined) {
3333
return;
3434
}
35-
if (drawerConfig.singleColor) {
36-
ctx.fillStyle = drawerConfig.singleColor;
35+
if (hitTestDrawerConfig.color) {
36+
ctx.fillStyle = hitTestDrawerConfig.color;
3737
} else {
3838
ctx.fillStyle = histogramColors[`${direction}Bright`];
3939
}
@@ -46,8 +46,8 @@ export class HistogramDrawer implements SeriesDrawer {
4646

4747
// the bar itself
4848
const gradient = ctx.createLinearGradient(0, closeY + capHeight, 0, bottomY);
49-
if (drawerConfig.singleColor) {
50-
ctx.fillStyle = drawerConfig.singleColor;
49+
if (hitTestDrawerConfig.color) {
50+
ctx.fillStyle = hitTestDrawerConfig.color;
5151
} else {
5252
gradient.addColorStop(0, histogramColors[`${direction}Cap`]);
5353
gradient.addColorStop(1, histogramColors[`${direction}Bottom`]);

0 commit comments

Comments
 (0)