Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Low label doesn't show up #81

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/chart/components/high_low/high-low.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FullChartConfig } from '../../chart.config';
import { ChartModel } from '../chart/chart.model';
import { CanvasModel } from '../../model/canvas.model';
import { getTextLineHeight } from '../../utils/canvas/canvas-text-functions.utils';
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';

type MarkerType = 'high' | 'low';

Expand Down Expand Up @@ -41,7 +42,10 @@ export class HighLowDrawer implements Drawer {
ctx.font = this.config.components.highLow.font;
this.drawMarkerLabel(ctx, finalHighIdx, high, 'high');
this.drawMarkerLabel(ctx, finalLowIdx, low, 'low');
const chartBounds = this.canvasBoundsContainer.getBounds('PANE_CHART');
ctx.restore();
// We need clip here so lowLabel won't overlap other panes
clipToBounds(ctx, chartBounds);
}
}

Expand All @@ -55,7 +59,10 @@ export class HighLowDrawer implements Drawer {
*/
private drawMarkerLabel(ctx: CanvasRenderingContext2D, candleIdx: number, yValue: number, type: MarkerType): void {
const y = this.getMarkerY(ctx, yValue, type === 'low');
if (!this.checkMarkerInBounds(y)) {
const fontSize = getTextLineHeight(ctx, false);
// we need to measure fit into the bounds for low label by its top point
const yForBoundsTrack = type === 'low' ? y - fontSize : y;
disyakidneyshot marked this conversation as resolved.
Show resolved Hide resolved
if (!this.checkMarkerInBounds(yForBoundsTrack)) {
return;
}
const text = this.getMarkerText(yValue, type);
Expand Down Expand Up @@ -89,7 +96,7 @@ export class HighLowDrawer implements Drawer {
private getMarkerY(ctx: CanvasRenderingContext2D, yValue: number, offset: boolean = false): number {
const y = this.chartModel.toY(yValue);
if (offset) {
const fontSize = getTextLineHeight(ctx);
const fontSize = getTextLineHeight(ctx, false);
return y + fontSize;
}
return y;
Expand Down
2 changes: 1 addition & 1 deletion src/chart/components/highlights/highlights.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CanvasBoundsContainer, CanvasElement } from '../../canvas/canvas-bounds
import { Drawer } from '../../drawers/drawing-manager';
import { ChartModel } from '../chart/chart.model';
import { unitToPixels } from '../../model/scaling/viewport.model';
import { clipToBounds } from '../../drawers/data-series.drawer';
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';

const LABEL_PADDINGS = [20, 10];

Expand Down
2 changes: 1 addition & 1 deletion src/chart/components/volumes/volumes.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { BarType, FullChartConfig } from '../../chart.config';
import { clipToBounds } from '../../drawers/data-series.drawer';
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
import { PriceMovement } from '../../model/candle-series.model';
import { CanvasModel } from '../../model/canvas.model';
import { Pixel, ViewportModel, unitToPixels } from '../../model/scaling/viewport.model';
Expand Down
52 changes: 26 additions & 26 deletions src/chart/components/y_axis/price_labels/price-label.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import {
FullChartColors,
getFontFromConfig,
YAxisAlign,
YAxisLabelAppearanceType,
YAxisLabelAppearanceType, YAxisLabelMode,
} from '../../../chart.config';
import { redrawBackgroundArea } from '../../../drawers/chart-background.drawer';
import { Bounds } from '../../../model/bounds.model';
import { avoidAntialiasing, drawLine } from '../../../utils/canvas/canvas-drawing-functions.utils';
import { calculateSymbolHeight, calculateTextWidth } from '../../../utils/canvas/canvas-font-measure-tool.utils';
import { floor } from '../../../utils/math.utils';
import { drawBadgeLabel, drawPlainLabel, drawRectLabel } from '../y-axis-labels.drawer';
import { drawBadgeLabel, drawPlainLabel, drawRectLabel, checkLabelInBoundaries } from '../y-axis-labels.drawer';
import { VisualYAxisLabel, YAxisVisualLabelType } from './y-axis-labels.model';

type LabelDrawer = typeof drawBadgeLabel | typeof drawRectLabel | typeof drawPlainLabel;
Expand Down Expand Up @@ -96,22 +96,30 @@ export function drawLabel(
showLine && avoidAntialiasing(ctx, () => drawLine(ctx, lineXStart, lineY, lineXEnd, lineY, 1));
const _drawLabel = () => drawLabel(ctx, bounds, text, centralY, visualLabel, config, colors, false, backgroundCtx);

switch (mode) {
case 'line':
_drawLine();
_drawDescription();
break;
case 'line-label':
_drawLine();
_drawDescription();
_drawLabel();
break;
case 'label':
_drawDescription();
_drawLabel();
break;
case 'none':
break;
const drawLineLabel = () => {
disyakidneyshot marked this conversation as resolved.
Show resolved Hide resolved
_drawLine();
_drawDescription();
}

const drawLineLabelLabel = () => {
_drawLine();
_drawLabel();
_drawDescription();
}

const drawLabelLabel = () => {
_drawDescription();
_drawLabel();
}

const labelDrawerByMode: Record<Exclude<YAxisLabelMode, 'none'>, () => void> = {
'line': drawLineLabel,
'line-label': drawLineLabelLabel,
'label': drawLabelLabel,
}

if (mode !== 'none' && checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
labelDrawerByMode[mode]();
}

ctx.restore();
Expand Down Expand Up @@ -143,14 +151,6 @@ function drawDescription(
const labelBoxBottom = centralY + fontHeight / 2 + paddingBottom;
const labelBoxHeight = labelBoxBottom - labelBoxY;

// do not draw, if description is out of bounds
if (
centralY < labelBounds.y + labelBoxHeight / 2 ||
centralY > labelBounds.y + labelBounds.height - labelBoxHeight / 2
) {
return;
}

ctx.save();

// overlay rect
Expand Down
45 changes: 27 additions & 18 deletions src/chart/components/y_axis/y-axis-labels.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ export const DEFAULT_PRICE_LABEL_PADDING = 4;
* @param text - text to draw
* @param centralY - y
* @param config - label styles config
* @param align
* @param yAxisState
* @param yAxisColors
* @param checkBoundaries
*/
export function drawBadgeLabel(
ctx: CanvasRenderingContext2D,
Expand All @@ -54,7 +55,7 @@ export function drawBadgeLabel(
config: YAxisLabelDrawConfig,
yAxisState: YAxisConfig,
yAxisColors: FullChartColors['yAxis'],
drawOutside: boolean = false,
checkBoundaries: boolean = true,
): void {
const align = yAxisState.align;
const textFont = config.textFont ?? getFontFromConfig(yAxisState);
Expand All @@ -71,12 +72,10 @@ export function drawBadgeLabel(
const labelBoxHeight = labelBoxBottomY - labelBoxTopY;

// do not draw, if label is out of bounds
if (
(centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2) &&
!drawOutside
) {
if (checkBoundaries && !checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
return;
}

ctx.save();
ctx.fillStyle = bgColor;
ctx.strokeStyle = bgColor;
Expand Down Expand Up @@ -119,8 +118,9 @@ export function drawBadgeLabel(
* @param text - text to draw
* @param centralY - y
* @param config - label styles config
* @param align
* @param yAxisState
* @param yAxisColors
* @param checkBoundaries
*/
export function drawRectLabel(
ctx: CanvasRenderingContext2D,
Expand All @@ -130,7 +130,7 @@ export function drawRectLabel(
config: YAxisLabelDrawConfig,
yAxisState: YAxisConfig,
yAxisColors: FullChartColors['yAxis'],
drawOutside: boolean = false,
checkBoundaries: boolean = true,
) {
const align = yAxisState.align;
const textFont = config.textFont ?? getFontFromConfig(yAxisState);
Expand All @@ -150,12 +150,10 @@ export function drawRectLabel(
const rounded = config.rounded ?? yAxisState.typeConfig.rectangle?.rounded;

// do not draw, if label is out of bounds
if (
(centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2) &&
!drawOutside
) {
if (checkBoundaries && !checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
return;
}

ctx.save();
ctx.fillStyle = bgColor;
ctx.strokeStyle = bgColor;
Expand Down Expand Up @@ -188,8 +186,10 @@ export function drawRectLabel(
* @param text - text to draw
* @param centralY - y
* @param config - label styles config
* @param align
* @param yAxisState
* @param yAxisColors
* @param checkBoundaries
* @param backgroundCtx
*/
export function drawPlainLabel(
ctx: CanvasRenderingContext2D,
Expand All @@ -199,7 +199,7 @@ export function drawPlainLabel(
config: YAxisLabelDrawConfig,
yAxisState: YAxisConfig,
yAxisColors: FullChartColors['yAxis'],
drawOutside: boolean = false,
checkBoundaries: boolean = true,
backgroundCtx?: CanvasRenderingContext2D,
) {
const align = yAxisState.align;
Expand All @@ -219,12 +219,10 @@ export function drawPlainLabel(
const labelBoxHeight = labelBoxBottomY - labelBoxTopY;

// do not draw, if label is out of bounds
if (
(centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2) &&
!drawOutside
) {
if (checkBoundaries && !checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
return;
}

ctx.save();
ctx.fillStyle = bgColor;
ctx.strokeStyle = bgColor;
Expand Down Expand Up @@ -261,3 +259,14 @@ export function getLabelYOffset(
const fontHeight = calculateSymbolHeight(font, ctx);
return fontHeight / 2 + paddingTop;
}

/**
* Checks if label fits in chart scale boundaries
* @param centralY
* @param bounds
* @param labelBoxHeight
* returns true if label fits
*/
export function checkLabelInBoundaries(centralY: number, bounds: Bounds, labelBoxHeight: number) {
return !(centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2);
}
2 changes: 1 addition & 1 deletion src/chart/components/y_axis/y-axis.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { FullChartConfig, YAxisAlign, getFontFromConfig } from '../../chart.config';
import { clipToBounds } from '../../drawers/data-series.drawer';
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
import { Drawer } from '../../drawers/drawing-manager';
import { Bounds } from '../../model/bounds.model';
import { CanvasModel } from '../../model/canvas.model';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import { BarType, FullChartConfig } from '../../chart.config';
import { BoundsProvider } from '../../model/bounds.model';
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
import { ChartDrawerConfig, clipToBounds, SeriesDrawer } from '../data-series.drawer';
import { ChartDrawerConfig, SeriesDrawer } from '../data-series.drawer';
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';

export const candleTypesList: BarType[] = [
'candle',
Expand Down
9 changes: 1 addition & 8 deletions src/chart/drawers/data-series.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
*/
import { DynamicModelDrawer } from '../components/dynamic-objects/dynamic-objects.drawer';
import { PaneManager } from '../components/pane/pane-manager.component';
import { Bounds } from '../model/bounds.model';
import { CanvasModel } from '../model/canvas.model';
import { DataSeriesModel, VisualSeriesPoint } from '../model/data-series.model';
import { clipToBounds } from '../utils/canvas/canvas-drawing-functions.utils';

export interface ChartDrawerConfig {
singleColor?: string;
Expand Down Expand Up @@ -69,13 +69,6 @@ export class DataSeriesDrawer implements DynamicModelDrawer<DataSeriesModel> {
}
}

export const clipToBounds = (ctx: CanvasRenderingContext2D, bounds: Bounds) => {
ctx.beginPath();
ctx.rect(bounds.x, bounds.y, bounds.width, bounds.height);
ctx.clip();
ctx.closePath();
};

export const setLineWidth = (
ctx: CanvasRenderingContext2D,
lineWidth: number,
Expand Down
3 changes: 2 additions & 1 deletion src/chart/drawers/ht-data-series.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import { PaneManager } from '../components/pane/pane-manager.component';
import { DataSeriesModel } from '../model/data-series.model';
import { HitTestCanvasModel } from '../model/hit-test-canvas.model';
import { ChartDrawerConfig, clipToBounds, SeriesDrawer } from './data-series.drawer';
import { ChartDrawerConfig, SeriesDrawer } from './data-series.drawer';
import { clipToBounds } from '../utils/canvas/canvas-drawing-functions.utils';
import { Drawer } from './drawing-manager';

/***
Expand Down
19 changes: 18 additions & 1 deletion src/chart/utils/canvas/canvas-drawing-functions.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { YAxisAlign } from '../../chart.config';
import { Bounds } from '../../model/bounds.model';

/**
* Draws a rounded rectangle on a canvas context
Expand Down Expand Up @@ -171,7 +172,7 @@ export function avoidAntialiasing(ctx: CanvasRenderingContext2D, draw: () => voi
* @param {{x: number, y: number}} a - The first point of the rectangle.
* @param {{x: number, y: number}} b - The second point of the rectangle.
* @returns {void}

*/
export function fillRect(
ctx: CanvasRenderingContext2D,
Expand All @@ -190,3 +191,19 @@ export function fillRect(
const h = Math.abs(a.y - b.y);
ctx.fillRect(x, y, w, h);
}

/**
* Sets clipping region for a Canvas 2D context according to the provided bounds.
*
* @param {CanvasRenderingContext2D} ctx - The canvas 2D context which will get the new clip region.
* @param {object} bounds - The bounds of the clipping region. Object containing x, y, width and height properties.
*
* @example
* clipToBounds(ctx, {x: 50, y: 50, width: 100, height: 100});
*/
export const clipToBounds = (ctx: CanvasRenderingContext2D, bounds: Bounds) => {
ctx.beginPath();
ctx.rect(bounds.x, bounds.y, bounds.width, bounds.height);
ctx.clip();
ctx.closePath();
};
12 changes: 9 additions & 3 deletions src/chart/utils/canvas/canvas-text-functions.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export interface CanvasTextProperties {
rtl?: boolean;
}

/**
* Baseline Height in Project
*/
const BASELINE = 1.33;

/**
* Sets the font, fill style and text alignment of a canvas context based on the provided properties.
* @param {CanvasRenderingContext2D} ctx - The canvas context to modify.
Expand Down Expand Up @@ -47,9 +52,10 @@ export function prepareTextForFill(ctx: CanvasRenderingContext2D, properties: Ca
/**
* Calculates the line height of a text based on the font size of the provided CanvasRenderingContext2D.
* @param {CanvasRenderingContext2D} ctx - The CanvasRenderingContext2D object used to draw the text.
* @param includeBaseLine
* @returns {number} The calculated line height of the text.
*/
export function getTextLineHeight(ctx: CanvasRenderingContext2D): number {
export function getTextLineHeight(ctx: CanvasRenderingContext2D, includeBaseLine: boolean = true): number {
disyakidneyshot marked this conversation as resolved.
Show resolved Hide resolved
const textSizeMatch = ctx.font.match(/(\d+.)?\d+(px|pt)/gi);
let textSize = '10px';
if (textSizeMatch && textSizeMatch.length) {
Expand All @@ -60,7 +66,7 @@ export function getTextLineHeight(ctx: CanvasRenderingContext2D): number {
textSize = textSizeMatch[0];
}
}
return parseInt(textSize, 10) * 1.33; // Base Line Height in Project
return includeBaseLine ? parseInt(textSize, 10) * BASELINE : parseInt(textSize, 10);
}

/**
Expand Down Expand Up @@ -106,7 +112,7 @@ export function getTextLines(text: string): string[] {
* @param {number} y - The y-coordinate of the starting position of the text.
* @param {CanvasTextProperties} properties - An object containing properties for the text, such as font size, style, and alignment.
* @returns {void}

*/
export function drawText(
ctx: CanvasRenderingContext2D,
Expand Down