UNPKG

@devexperts/dxcharts-lite

Version:
234 lines (231 loc) 8.37 kB
/* * 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/. */ /** * The minimum supported canvas size in chart-core (in pixels). * Any size of <canvas> element below these dimensions will not be rendered (is NOT INTENDED to be rendered). * @doc-tags chart-core,canvas */ export const MIN_SUPPORTED_CANVAS_SIZE = { width: 20, height: 20, }; export class CanvasModel { constructor(eventBus, canvas, drawingManager, canvasModels, resizer, options = {}) { var _a; this.eventBus = eventBus; this.canvas = canvas; this.drawingManager = drawingManager; this.resizer = resizer; this.width = 0; this.height = 0; this.prevHeight = 0; this.prevWidth = 0; this.type = CANDLE_TYPE; canvasModels.push(this); this.parent = findHeightParent(canvas); const ctx = canvas.getContext('2d', options); if (ctx === null) { throw new Error("Couldn't get 2d context????"); } this.context = ctx; this._canvasId = (_a = canvas.getAttribute('data-element')) !== null && _a !== void 0 ? _a : ''; this.updateCanvasWidthHeight(canvas, this.getChartResizerElement().getBoundingClientRect()); } /** * About rendering for non-integer dpi * https://stackoverflow.com/questions/17553557/draw-crisp-lines-on-html5-canvas-with-browser-zoom * @param bcr */ updateDPR(bcr) { const { width, height } = bcr; const dpi = window.devicePixelRatio; this.canvas.style.height = height + 'px'; this.canvas.style.width = width + 'px'; this.canvas.width = width * dpi; this.canvas.height = height * dpi; this.width = width; this.height = height; this.ctx.scale(dpi, dpi); } get canvasId() { return this._canvasId; } get ctx() { return this.context; } /** * Clears the canvas by using the clearRect method of the canvas context. * @function * @name clear * @memberof Canvas * @returns {void} */ clear() { this.context.clearRect(0, 0, this.width, this.height); } /** * Checks if the type is linked. * * @returns {boolean} Returns true if the type is linked, false otherwise. */ isLinked() { var _a, _b; return (_b = (_a = this.type) === null || _a === void 0 ? void 0 : _a.linked) !== null && _b !== void 0 ? _b : false; } /** * Triggers the 'fireDraw' event on the event bus with the canvas ID as the parameter. */ fireDraw() { this.eventBus.fireDraw([this.canvasId]); } /** * Updates the width and height of the canvas element based on the client width and height of the canvas element and the height of the chart resizer element. * @param {HTMLCanvasElement} canvas - The canvas element to update. * @param {ClientRect | DOMRect} [bcr=this.getChartResizerElement().getBoundingClientRect()] - The bounding client rectangle of the chart resizer element. * @returns {void} */ updateCanvasWidthHeight(canvas, bcr = this.getChartResizerElement().getBoundingClientRect()) { if (canvas.clientWidth !== this.width) { canvas.width = canvas.clientWidth; this.width = canvas.clientWidth; } const height = bcr.height; if (height !== this.height) { canvas.style.height = height + 'px'; this.height = height; canvas.height = height; this.prevHeight = height; } } /** * Returns the chart resizer element. If the resizer is not defined, it returns the parent element. * * @returns {HTMLElement} The chart resizer element. */ getChartResizerElement() { var _a; return (_a = this.resizer) !== null && _a !== void 0 ? _a : this.parent; } /** * Checks if the canvas is ready to be used by verifying if its width and height are greater than the minimum supported canvas size. * * @returns {boolean} - Returns true if the canvas is ready to be used, false otherwise. */ isReady() { return this.width > MIN_SUPPORTED_CANVAS_SIZE.width && this.height > MIN_SUPPORTED_CANVAS_SIZE.height; } } const CANDLE_TYPE = { name: 'candle', }; const BAR_TYPE = { name: 'candle', }; const LINE_TYPE = { name: 'line', linked: true, }; const AREA_TYPE = { name: 'area', linked: true, }; const TYPES = { candle: CANDLE_TYPE, bar: BAR_TYPE, line: LINE_TYPE, area: AREA_TYPE, }; /** * Creates a new canvas model for the main chart canvas. * * @param {EventBus} eventBus - The event bus used to communicate between components. * @param {HTMLCanvasElement} canvas - The canvas element to create the model for. * @param {HTMLElement} resizer - The element used to resize the canvas. * @param {BarType} barType - The type of bar to use for the chart. * @param {FullChartConfig} config - The configuration object for the chart. * @param {DrawingManager} drawingManager - The drawing manager used to draw on the canvas. * @param {CanvasModel[]} canvasModels - An array of canvas models to add the new model to. * * @returns {CanvasModel} The newly created canvas model. export function createMainCanvasModel( eventBus, canvas, resizer, barType, config, drawingManager, canvasModels, ) { const canvasModel = createCanvasModel(eventBus, canvas, config, drawingManager, canvasModels, resizer); // @ts-ignore canvasModel.type = TYPES[barType] ?? CANDLE_TYPE; return canvasModel; }*/ export function createMainCanvasModel(eventBus, canvas, resizer, barType, config, drawingManager, canvasModels) { var _a; const canvasModel = createCanvasModel(eventBus, canvas, config, drawingManager, canvasModels, resizer); // @ts-ignore canvasModel.type = (_a = TYPES[barType]) !== null && _a !== void 0 ? _a : CANDLE_TYPE; return canvasModel; } /** * Creates a new CanvasModel instance. * * @param {EventBus} eventBus - The event bus to use. * @param {HTMLCanvasElement} canvas - The canvas element to use. * @param {FullChartConfig} config - The configuration object for the chart. * @param {DrawingManager} drawingManager - The drawing manager to use. * @param {CanvasModel[]} canvasModels - An array of existing canvas models. * @param {HTMLElement} [resizer] - The element to use for resizing the canvas. * * @returns {CanvasModel} A new instance of the CanvasModel class. */ export function createCanvasModel(eventBus, canvas, config, drawingManager, canvasModels, resizer, options) { const canvasModel = new CanvasModel(eventBus, canvas, drawingManager, canvasModels, resizer, options); initCanvasWithConfig(canvasModel, config); return canvasModel; } /** * Initializes a canvas with a given configuration. * @param {CanvasModel} canvasModel - The canvas model to be initialized. * @param {FullChartConfig} config - The configuration object for the canvas. * @returns {void} */ export function initCanvasWithConfig(canvasModel, config) { const canvas = canvasModel.canvas; if (config.fixedSize) { canvas.width = config.fixedSize.width; canvas.height = config.fixedSize.height; canvas.style.width = config.fixedSize.width + 'px'; canvas.style.height = config.fixedSize.height + 'px'; canvasModel.width = config.fixedSize.width; canvasModel.height = config.fixedSize.height; } canvas.style.position = 'absolute'; canvas.style.top = '0'; canvas.style.left = '0'; canvas.style.direction = 'ltr'; } /** * Gets the first parent with "data-chart-container" attribute to compute height */ function findHeightParent(initial) { let el = initial; while (el) { if (el.nodeType === 1 && el.hasAttribute('data-chart-container')) { return el; } else { if (el.parentElement !== null) { el = el.parentElement; } else { break; } } } return el; }