@devexperts/dxcharts-lite
Version:
193 lines (192 loc) • 9.43 kB
JavaScript
/*
* Copyright (C) 2019 - 2026 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;
};