Skip to content

Commit

Permalink
Pull request #5506: Bugfix/DXCF-5742 indicators it s difficult to ope…
Browse files Browse the repository at this point in the history
…n 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: 0a1563dfbe8c1ffc991eb1abce74e9f344bada53
  • Loading branch information
Keelaro1 authored and dxcity committed Feb 28, 2025
1 parent 1beeb63 commit e34f5cb
Show file tree
Hide file tree
Showing 21 changed files with 151 additions and 135 deletions.
10 changes: 5 additions & 5 deletions docs/how-to/custom-data-series-drawer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const myDrawer = {
ctx, // CanvasRenderingContext2D
allPoints, // VisualSeriesPoint[][]
model, // DataSeriesModel - can be also CandleSeriesModel - in this case points have all candle fields
drawerConfig, // ChartDrawerConfig
hitTestDrawerConfig, // HTSeriesDrawerConfig
) {
allPoints.forEach((points, idx) => {
const allPoints = points.flat();
Expand All @@ -25,12 +25,12 @@ const myDrawer = {
if (point.close > prevPoint?.close) {
// it is not necessary to save and restore when modifying the context state
// - it is done by DataSeriesDrawer, which calls draw() method of specific data series drawer
ctx.fillStyle = drawerConfig.singleColor ?? 'green';
ctx.fillStyle = hitTestDrawerConfig.color ?? 'green';
ctx.fillText('', x, y);
} else {
// drawerConfig.singleColor is defined when the drawer is drawn by hit test drawer
// in order to work with hit test correctly you have to use drawerConfig.singleColor if it's defined
ctx.fillStyle = drawerConfig.singleColor ?? 'red';
// hitTestDrawerConfig.color is defined when the drawer is drawn by hit test drawer
// in order to work with hit test correctly you have to use hitTestDrawerConfig.color if it's defined
ctx.fillStyle = hitTestDrawerConfig.color ?? 'red';
ctx.fillText('', x, y);
}
}
Expand Down
10 changes: 5 additions & 5 deletions docs/how-to/custom-data-series-drawer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ <h1>Chart custom data-series drawer example</h1>
ctx, // CanvasRenderingContext2D
allPoints, // VisualSeriesPoint[][]
model, // DataSeriesModel - can be also CandleSeriesModel - in this case points have all candle fields
drawerConfig, // ChartDrawerConfig
hitTestDrawerConfig, // HTSeriesDrawerConfig
) {
allPoints.forEach((points, idx) => {
const allPoints = points.flat();
Expand All @@ -49,12 +49,12 @@ <h1>Chart custom data-series drawer example</h1>
if (point.close > prevPoint?.close) {
// it is not necessary to save and restore when modifying the context state
// - it is done by DataSeriesDrawer, which calls draw() method of specific data series drawer
ctx.fillStyle = drawerConfig.singleColor ?? 'green';
ctx.fillStyle = hitTestDrawerConfig.color ?? 'green';
ctx.fillText('⬆', x, y);
} else {
// drawerConfig.singleColor is defined when the drawer is drawn by hit test drawer
// in order to work with hit test correctly you have to use drawerConfig.singleColor if it's defined
ctx.fillStyle = drawerConfig.singleColor ?? 'red';
// hitTestDrawerConfig.color is defined when the drawer is drawn by hit test drawer
// in order to work with hit test correctly you have to use hitTestDrawerConfig.color if it's defined
ctx.fillStyle = hitTestDrawerConfig.color ?? 'red';
ctx.fillText('⬇', x, y);
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/chart/drawers/chart-type-drawers/area.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.mode
import VisualCandle from '../../model/visual-candle';
import { flat } from '../../utils/array.utils';
import { floor } from '../../utils/math.utils';
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';

export class AreaDrawer implements SeriesDrawer {
constructor(private config: ChartConfigComponentsChart) {}
Expand All @@ -18,16 +18,16 @@ export class AreaDrawer implements SeriesDrawer {
ctx: CanvasRenderingContext2D,
points: VisualSeriesPoint[][],
model: DataSeriesModel,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
) {
if (model instanceof CandleSeriesModel) {
// @ts-ignore
const visualCandles: VisualCandle[] = flat(points);
if (visualCandles.length === 0) {
return;
}
if (drawerConfig.singleColor) {
ctx.strokeStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.strokeStyle = hitTestDrawerConfig.color;
} else {
ctx.strokeStyle = model.colors.areaTheme.lineColor;
}
Expand Down Expand Up @@ -62,8 +62,8 @@ export class AreaDrawer implements SeriesDrawer {
ctx.closePath();

let fillColor: CanvasGradient;
if (drawerConfig.singleColor) {
ctx.fillStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.fillStyle = hitTestDrawerConfig.color;
} else {
ctx.fillStyle =
model.colors.areaTheme.startColor && model.colors.areaTheme.stopColor
Expand Down
14 changes: 7 additions & 7 deletions src/chart/drawers/chart-type-drawers/bar.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ import VisualCandle from '../../model/visual-candle';
import { flat } from '../../utils/array.utils';
import { avoidAntialiasing } from '../../utils/canvas/canvas-drawing-functions.utils';
import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
import { ChartDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
import { HTSeriesDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';

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

private setFillStyle(
ctx: CanvasRenderingContext2D,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
candleSeries: CandleSeriesModel,
visualCandle: VisualCandle,
) {
if (drawerConfig.singleColor) {
ctx.strokeStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.strokeStyle = hitTestDrawerConfig.color;
} else {
const barTheme = candleSeries.colors.barTheme;
if (barTheme) {
Expand All @@ -35,15 +35,15 @@ export class BarDrawer implements SeriesDrawer {
ctx: CanvasRenderingContext2D,
points: VisualSeriesPoint[][],
candleSeries: DataSeriesModel,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
) {
if (candleSeries instanceof CandleSeriesModel) {
// @ts-ignore
const visualCandles: VisualCandle[] = flat(points);
setLineWidth(ctx, this.config.barLineWidth, candleSeries, drawerConfig);
setLineWidth(ctx, this.config.barLineWidth, candleSeries, hitTestDrawerConfig);
avoidAntialiasing(ctx, () => {
for (const visualCandle of visualCandles) {
this.setFillStyle(ctx, drawerConfig, candleSeries, visualCandle);
this.setFillStyle(ctx, hitTestDrawerConfig, candleSeries, visualCandle);
ctx.beginPath();
const bodyLineX = candleSeries.view.toX(visualCandle.centerUnit);
const openLineStartX = candleSeries.view.toX(visualCandle.startUnit);
Expand Down
20 changes: 10 additions & 10 deletions src/chart/drawers/chart-type-drawers/baseline.drawer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
Expand All @@ -9,7 +9,7 @@ import { CandleSeriesModel } from '../../model/candle-series.model';
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
import { Pixel } from '../../model/scaling/viewport.model';
import { flat } from '../../utils/array.utils';
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';

export class BaselineDrawer implements SeriesDrawer {
constructor(private baseLineModel: BaselineModel, private canvasBoundContainer: CanvasBoundsContainer) {}
Expand All @@ -18,9 +18,9 @@ export class BaselineDrawer implements SeriesDrawer {
ctx: CanvasRenderingContext2D,
points: VisualSeriesPoint[][],
model: DataSeriesModel,
drawerConfig?: ChartDrawerConfig,
hitTestDrawerConfig?: HTSeriesDrawerConfig,
) {
if (drawerConfig !== undefined && model instanceof CandleSeriesModel) {
if (hitTestDrawerConfig !== undefined && model instanceof CandleSeriesModel) {
const visualCandles = flat(points);
// calculate baseline
const baselineYPercents = this.baseLineModel.baselineYPercents;
Expand All @@ -41,7 +41,7 @@ export class BaselineDrawer implements SeriesDrawer {
const curHigherThanBL = currentCloseYPx < baseLine;

if (prev !== void 0 && prevHigherThanBL !== curHigherThanBL) {
setBaselineFillStyle(ctx, model, drawerConfig, prevHigherThanBL);
setBaselineFillStyle(ctx, model, hitTestDrawerConfig, prevHigherThanBL);

const prevLineXPx = model.view.toX(prev.centerUnit);
const prevCloseYPx = model.view.toY(prev.close);
Expand Down Expand Up @@ -69,7 +69,7 @@ export class BaselineDrawer implements SeriesDrawer {
ctx.beginPath();
ctx.moveTo(currentLineXPx, currentCloseYPx);
} else if (next === void 0) {
setBaselineFillStyle(ctx, model, drawerConfig, curHigherThanBL);
setBaselineFillStyle(ctx, model, hitTestDrawerConfig, curHigherThanBL);
ctx.lineTo(currentLineXPx, currentCloseYPx);
ctx.stroke();
ctx.lineTo(currentLineXPx, baseLine);
Expand All @@ -93,12 +93,12 @@ export class BaselineDrawer implements SeriesDrawer {
const setBaselineFillStyle = (
ctx: CanvasRenderingContext2D,
candleSeries: CandleSeriesModel,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
upper: boolean,
): void => {
if (drawerConfig.singleColor) {
ctx.fillStyle = drawerConfig.singleColor;
ctx.strokeStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.fillStyle = hitTestDrawerConfig.color;
ctx.strokeStyle = hitTestDrawerConfig.color;
} else {
ctx.fillStyle = upper
? candleSeries.colors.baseLineTheme.upperSectionFillColor
Expand Down
38 changes: 21 additions & 17 deletions src/chart/drawers/chart-type-drawers/candle.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CandleTheme, ChartConfigComponentsChart } from '../../chart.config';
import VisualCandle from '../../model/visual-candle';
import { avoidAntialiasing } from '../../utils/canvas/canvas-drawing-functions.utils';
import { dpr } from '../../utils/device/device-pixel-ratio.utils';
import { ChartDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
import { HTSeriesDrawerConfig, SeriesDrawer, setLineWidth } from '../data-series.drawer';
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
import { flat } from '../../utils/array.utils';

Expand Down Expand Up @@ -42,21 +42,21 @@ export class CandleDrawer implements SeriesDrawer {
*/
points: VisualSeriesPoint[][],
model: DataSeriesModel,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
) {
if (model instanceof CandleSeriesModel) {
// @ts-ignore
const visualCandles: VisualCandle[] = flat(points);
// TODO FIXME draw called 3-4 times on single candle update even if multichart is off
setLineWidth(ctx, this.config.candleLineWidth, model, drawerConfig, this.config.candleLineWidth);
setLineWidth(ctx, this.config.candleLineWidth, model, hitTestDrawerConfig, this.config.candleLineWidth);
avoidAntialiasing(ctx, () => {
this.pixelLength = 1 / dpr;
this.halfLineWidthCU = ctx.lineWidth / 2;
this.lineWidthCU = ctx.lineWidth;
for (const visualCandle of visualCandles) {
const { candleTheme, activeCandleTheme } = model.colors;
if (candleTheme && activeCandleTheme) {
this.drawCandle(ctx, drawerConfig, model, visualCandle);
this.drawCandle(ctx, hitTestDrawerConfig, model, visualCandle);
}
}
});
Expand All @@ -65,7 +65,7 @@ export class CandleDrawer implements SeriesDrawer {

drawCandle(
ctx: CanvasRenderingContext2D,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
candleSeries: CandleSeriesModel,
visualCandle: VisualCandle,
) {
Expand All @@ -75,8 +75,8 @@ export class CandleDrawer implements SeriesDrawer {
const isHollow = visualCandle.isHollow;

// choose candle filling color
if (drawerConfig.singleColor) {
ctx.fillStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.fillStyle = hitTestDrawerConfig.color;
} else if (isHollow) {
ctx.fillStyle = currentCandleTheme[`${direction}WickColor`];
} else {
Expand All @@ -96,8 +96,8 @@ export class CandleDrawer implements SeriesDrawer {
ctx.fillStyle = candleColor;

// wick style, borders are drawn after the wicks, so style for borders will be changed in drawBorder method
if (drawerConfig.singleColor) {
ctx.strokeStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.strokeStyle = hitTestDrawerConfig.color;
} else {
ctx.strokeStyle = wickColor;
}
Expand Down Expand Up @@ -136,7 +136,7 @@ export class CandleDrawer implements SeriesDrawer {
}
this.drawCandleBorder(
ctx,
drawerConfig,
hitTestDrawerConfig,
currentCandleTheme,
visualCandle,
baseX + this.halfLineWidthCU,
Expand All @@ -155,16 +155,20 @@ export class CandleDrawer implements SeriesDrawer {
const paddingBaseX = baseX + paddingWidthOffset;
const paddingWidth = width - paddingWidthOffset * 2;
if (!isHollow) {
if (drawerConfig.singleColor) {
ctx.fillStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.fillStyle = hitTestDrawerConfig.color;
}
ctx.fillRect(paddingBaseX, bodyStart, paddingWidth, bodyH);
const bodyWidth = hitTestDrawerConfig.hoverWidth ? width + paddingWidthOffset : paddingWidth;
const bodyHeight = hitTestDrawerConfig.hoverWidth
? bodyH + hitTestDrawerConfig.hoverWidth + paddingWidthOffset
: bodyH;
ctx.fillRect(paddingBaseX, bodyStart, bodyWidth, bodyHeight);
}
// choose border color around candle and draw candle
if (showCandleBorder) {
this.drawCandleBorder(
ctx,
drawerConfig,
hitTestDrawerConfig,
currentCandleTheme,
visualCandle,
paddingBaseX + this.halfLineWidthCU,
Expand Down Expand Up @@ -199,16 +203,16 @@ export class CandleDrawer implements SeriesDrawer {

private drawCandleBorder(
ctx: CanvasRenderingContext2D,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
candleTheme: CandleTheme,
visualCandle: VisualCandle,
x: number,
y: number,
w: number,
h: number,
) {
if (drawerConfig.singleColor) {
ctx.strokeStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.strokeStyle = hitTestDrawerConfig.color;
} else {
const direction = visualCandle.name;
ctx.strokeStyle =
Expand Down
12 changes: 6 additions & 6 deletions src/chart/drawers/chart-type-drawers/histogram.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CandleSeriesModel } from '../../model/candle-series.model';
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
import VisualCandle from '../../model/visual-candle';
import { floorToDPR } from '../../utils/device/device-pixel-ratio.utils';
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';

export class HistogramDrawer implements SeriesDrawer {
constructor(private config: ChartConfigComponentsHistogram) {}
Expand All @@ -17,7 +17,7 @@ export class HistogramDrawer implements SeriesDrawer {
ctx: CanvasRenderingContext2D,
points: VisualSeriesPoint[][],
model: DataSeriesModel,
drawerConfig: ChartDrawerConfig,
hitTestDrawerConfig: HTSeriesDrawerConfig,
) {
if (model instanceof CandleSeriesModel) {
// @ts-ignore
Expand All @@ -32,8 +32,8 @@ export class HistogramDrawer implements SeriesDrawer {
if (histogramColors === undefined) {
return;
}
if (drawerConfig.singleColor) {
ctx.fillStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.fillStyle = hitTestDrawerConfig.color;
} else {
ctx.fillStyle = histogramColors[`${direction}Bright`];
}
Expand All @@ -46,8 +46,8 @@ export class HistogramDrawer implements SeriesDrawer {

// the bar itself
const gradient = ctx.createLinearGradient(0, closeY + capHeight, 0, bottomY);
if (drawerConfig.singleColor) {
ctx.fillStyle = drawerConfig.singleColor;
if (hitTestDrawerConfig.color) {
ctx.fillStyle = hitTestDrawerConfig.color;
} else {
gradient.addColorStop(0, histogramColors[`${direction}Cap`]);
gradient.addColorStop(1, histogramColors[`${direction}Bottom`]);
Expand Down
Loading

0 comments on commit e34f5cb

Please sign in to comment.