UNPKG

@devexperts/dxcharts-lite

Version:
193 lines (192 loc) 9.43 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/. */ import { CHART_UUID, CanvasElement } from '../../canvas/canvas-bounds-container'; export class WaterMarkDrawer { constructor(config, canvasBoundsContainer, canvasModel, waterMarkConfigProvider, watermarkDataProvider) { this.config = config; this.canvasBoundsContainer = canvasBoundsContainer; this.canvasModel = canvasModel; this.waterMarkConfigProvider = waterMarkConfigProvider; this.watermarkDataProvider = watermarkDataProvider; this.getConfig = (offset = 0, text, fontSize, color, totalHeight, redefinedWidth) => { const ctx = this.canvasModel.ctx; const chartBounds = this.canvasBoundsContainer.getBounds(CanvasElement.PANE_UUID(CHART_UUID)); const { position: posType, offsetY, offsetX } = this.config.components.waterMark; let width; if (!redefinedWidth) { ctx.font = setFont(this.config, fontSize); width = ctx.measureText(text).width; if (chartBounds.width - 10 < width) { ctx.font = reCountingSize(this.config, this.canvasBoundsContainer, fontSize, width); width = ctx.measureText(text).width; } } else { width = redefinedWidth; } switch (posType) { case 'left-top': return { x: offsetX + chartBounds.x, y: offsetY + offset + chartBounds.y, font: ctx.font, text, color, }; case 'left-bottom': return { x: offsetX + chartBounds.x, y: chartBounds.height - totalHeight - offsetY + offset + chartBounds.y, font: ctx.font, text, color, }; case 'center': return { x: chartBounds.width / 2 - width / 2 + chartBounds.x, y: (chartBounds.height - totalHeight) / 2 + offset + chartBounds.y, font: ctx.font, text, color, }; } }; } /** * Draws a watermark on the canvas if the watermark is visible and the colors are provided in the configuration. * The watermark consists of three rows of text and an optional logo image. * The height of each row is calculated based on the font size and the actual text height. * The total height of the watermark is calculated by adding the heights of all rows and the logo image. * The watermark is drawn using the drawWaterMark() method and the configuration is provided by the getConfig() method. * The font size and color of each row are provided in the waterMarkConfig object. * The logo image is drawn using the drawImage() method and its dimensions are provided in the waterMarkConfig object. * @function */ draw() { var _a, _b, _c, _d, _e, _f, _g; if (((_a = this.config.components.waterMark) === null || _a === void 0 ? void 0 : _a.visible) && this.config.colors) { const { firstRow, secondRow, thirdRow } = this.watermarkDataProvider(); const waterMarkConfig = this.waterMarkConfigProvider(); const waterMarkTheme = this.config.colors.waterMarkTheme; const ctx = this.canvasModel.ctx; let firstRowHeight = 0; let secondRowHeight = 0; let secondRowGap = 0; let thirdRowHeight = 0; let thirdRowGap = 0; ctx.save(); // set font for first watermark Row if (waterMarkConfig.firstRowFontSize && firstRow) { ctx.font = setFont(this.config, waterMarkConfig.firstRowFontSize); const firstRowMetrics = ctx.measureText(firstRow); firstRowHeight = firstRowMetrics.actualBoundingBoxAscent + firstRowMetrics.actualBoundingBoxDescent; } // set font for second watermark Row if (waterMarkConfig.secondRowFontSize && secondRow) { ctx.font = setFont(this.config, waterMarkConfig.secondRowFontSize); const secondRowMetrics = ctx.measureText(secondRow); secondRowHeight = secondRowMetrics.actualBoundingBoxAscent + secondRowMetrics.actualBoundingBoxDescent; secondRowGap = (_b = waterMarkConfig.firstRowBottomPadding) !== null && _b !== void 0 ? _b : 0; } // set font for third watermark Row if (waterMarkConfig.thirdRowFontSize && thirdRow) { ctx.font = setFont(this.config, waterMarkConfig.thirdRowFontSize); const thirdRowMetrics = ctx.measureText(thirdRow); thirdRowHeight = thirdRowMetrics.actualBoundingBoxAscent + thirdRowMetrics.actualBoundingBoxDescent; thirdRowGap = (_c = waterMarkConfig.secondRowBottomPadding) !== null && _c !== void 0 ? _c : 0; } const imageGap = (_d = waterMarkConfig.thirdRowBottomPadding) !== null && _d !== void 0 ? _d : 0; const imageHeight = (_e = waterMarkConfig.logoHeight) !== null && _e !== void 0 ? _e : 0; const totalHeight = firstRowHeight + secondRowHeight + secondRowGap + thirdRowHeight + thirdRowGap + imageGap + imageHeight; // draw first Row if (firstRow) { this.drawWaterMark(this.getConfig(firstRowHeight, firstRow, waterMarkConfig.firstRowFontSize, waterMarkTheme.firstRowColor, totalHeight)); } // draw second Row if (secondRow) { this.drawWaterMark(this.getConfig(firstRowHeight + secondRowGap + secondRowHeight, secondRow, waterMarkConfig.secondRowFontSize, waterMarkTheme.secondRowColor, totalHeight)); } // draw third Row if (thirdRow) { this.drawWaterMark(this.getConfig(firstRowHeight + secondRowGap + secondRowHeight + thirdRowGap + thirdRowHeight, thirdRow, waterMarkConfig.thirdRowFontSize, waterMarkTheme.thirdRowColor, totalHeight)); } // draw image if (this.logoImage) { const config = this.getConfig(firstRowHeight + secondRowGap + secondRowHeight + thirdRowGap + thirdRowHeight + imageGap, '', waterMarkConfig.thirdRowFontSize, waterMarkTheme.thirdRowColor, totalHeight, waterMarkConfig.logoWidth); this.canvasModel.ctx.drawImage(this.logoImage, config.x, config.y, (_f = waterMarkConfig.logoWidth) !== null && _f !== void 0 ? _f : 0, (_g = waterMarkConfig.logoHeight) !== null && _g !== void 0 ? _g : 0); } ctx.restore(); } } /** * Returns an array of canvas ids. * * @returns {Array<string>} An array of canvas ids. */ getCanvasIds() { return [this.canvasModel.canvasId]; } /** * Sets the logo image to be displayed. * * @param {CanvasImageSource} img - The image to be set as the logo. * @returns {void} */ setLogoImage(img) { this.logoImage = img; } /** * Draws a watermark on the canvas. * * @private * @param {Object} config - The configuration object for the watermark. * @param {string} config.text - The text to be displayed as the watermark. * @param {string} config.font - The font to be used for the watermark. * @param {string} config.color - The color to be used for the watermark. * @param {number} config.x - The x-coordinate of the starting point of the watermark. * @param {number} config.y - The y-coordinate of the starting point of the watermark. * @returns {void} */ drawWaterMark(config) { const text = config.text; if (!text || !text.length) { return; } const ctx = this.canvasModel.ctx; ctx.font = config.font; ctx.fillStyle = config.color; const x = config.x; const y = config.y; ctx.fillText(text, x, y); } /** * A method that resets the state of an object to its initial values. * * @function * @name reset * @returns {void} */ reset() { } } export const reCountingSize = (config, canvasBoundsContainer, fontSize, fontWidth) => { const getFontSize = (fontSize, fontWidth) => { const chart = canvasBoundsContainer.getBounds(CanvasElement.CHART); return (chart.width / fontWidth) * fontSize; }; const size = getFontSize(fontSize, fontWidth); let font = undefined; if (config.components && config.components.waterMark) { font = config.components.waterMark.fontFamily; } return size + 'px ' + font; }; export const setFont = (config, fontSize) => { let font = undefined; if (config.components && config.components.waterMark) { font = config.components.waterMark.fontFamily; } return fontSize + 'px ' + font; };