UNPKG

scichart

Version:

Fast WebGL JavaScript Charting Library and Framework

276 lines (275 loc) 14.2 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.getAdjustedRotation = exports.TitleRendererBase = void 0; var app_1 = require("../../constants/app"); var DeletableEntity_1 = require("../../Core/DeletableEntity"); var Deleter_1 = require("../../Core/Deleter"); var Rect_1 = require("../../Core/Rect"); var TextPosition_1 = require("../../types/TextPosition"); var TextStyle_1 = require("../../types/TextStyle"); var parseColor_1 = require("../../utils/parseColor"); var text_1 = require("../../utils/text"); var createNativeRect_1 = require("../Visuals/Helpers/createNativeRect"); var NativeObject_1 = require("../Visuals/Helpers/NativeObject"); var DpiHelper_1 = require("../Visuals/TextureManager/DpiHelper"); var TextureManager_1 = require("../Visuals/TextureManager/TextureManager"); var TitleRendererBase = /** @class */ (function (_super) { __extends(TitleRendererBase, _super); function TitleRendererBase(webAssemblyContext) { var _this = _super.call(this) || this; _this.drawDebug = false; _this.useCache = true; _this.viewRectProperty = Rect_1.Rect.createZero(); /** * The height taken by the text with normal(horizontal) orientation including padding */ _this.textHeight = 0; /** * The width taken by the text with normal(horizontal) orientation including padding */ _this.textWidth = 0; /** * The height taken by the text considering current orientation including padding */ _this.desiredHeightProperty = 0; /** * The width taken by the text considering current orientation including padding */ _this.desiredWidthProperty = 0; _this.useNativeTextProperty = false; _this.webAssemblyContext = webAssemblyContext; _this.textureManager = new TextureManager_1.TextureManager(webAssemblyContext); _this.onDpiChanged = _this.onDpiChanged.bind(_this); DpiHelper_1.DpiHelper.dpiChanged.subscribe(_this.onDpiChanged); return _this; } Object.defineProperty(TitleRendererBase.prototype, "viewRect", { /** * Defines a bounding {@link Rect} containing the title text */ get: function () { return this.viewRectProperty; }, enumerable: false, configurable: true }); // TODO consider if this class should be abstract TitleRendererBase.prototype.measure = function () { var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } }; TitleRendererBase.prototype.layout = function (originRect) { }; TitleRendererBase.prototype.draw = function () { var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } }; TitleRendererBase.prototype.delete = function () { this.resetCache(); this.textureManager = (0, Deleter_1.deleteSafe)(this.textureManager); this.webAssemblyContext = undefined; DpiHelper_1.DpiHelper.dpiChanged.unsubscribe(this.onDpiChanged); }; TitleRendererBase.prototype.resetCache = function () { this.invalidateCache(); this.textStyle = undefined; this.originalTextStyle = undefined; }; TitleRendererBase.prototype.invalidateCache = function () { var _a; (0, Deleter_1.deleteSafe)((_a = this.texture) === null || _a === void 0 ? void 0 : _a.bitmapTexture); this.texture = undefined; }; TitleRendererBase.prototype.onDpiChanged = function (args) { this.resetCache(); }; /** * Performs rendering of the title */ TitleRendererBase.prototype.drawInternal = function (renderContext, useNativeText, titlePosition) { if (!this.text || this.text.length === 0) { return; } if (useNativeText) { this.drawWithNativeText(renderContext, titlePosition); } else { this.drawWithTexture(renderContext, titlePosition); } // if (this.drawDebug) { // this.drawTitleDebugViewRect(renderContext); // } }; TitleRendererBase.prototype.drawWithNativeText = function (renderContext, position) { var titleText = Array.isArray(this.text) ? this.text.join("\n") : this.text; // @ts-ignore mismatch with TTextStyle var nativeFont = renderContext.getFont(this.textStyle, true); // calculate start coordinates for native text drawing; // the start point is the beginning of alphabetic text baseline var tx = this.viewRect.left + this.nativeTextShiftX; var ty = this.viewRect.top + this.nativeTextShiftY; var adjRotation = (0, exports.getAdjustedRotation)(this.textStyle.rotation, position); var rotationRad = -(adjRotation * Math.PI) / 180; var nativeMultilineAlignment = (0, TextPosition_1.convertMultiLineAlignment)(this.textStyle.multilineAlignment, this.webAssemblyContext); var textColor = (0, parseColor_1.parseColorToUIntArgb)(this.textStyle.color); nativeFont.DrawStringAdvanced(titleText, textColor, Math.round(tx), Math.round(ty), (0, NativeObject_1.getVector4)(this.webAssemblyContext, tx, ty, rotationRad, 0), nativeMultilineAlignment, this.nativeLineSpacing); }; TitleRendererBase.prototype.drawWithTexture = function (renderContext, titlePosition) { var _a = this.texture, bitmapTexture = _a.bitmapTexture, textureHeight = _a.textureHeight, textureWidth = _a.textureWidth; if (bitmapTexture) { try { var nativeContext = renderContext.getNativeContext(); nativeContext.DrawTexture(bitmapTexture, Math.round(this.viewRect.left), Math.round(this.viewRect.top), textureWidth, textureHeight); if (!this.useCache) { bitmapTexture.delete(); this.texture = undefined; } } catch (err) { console.error("Error while drawing title: ", err); // webgl context probably lost. Clear the cache this.resetCache(); } } }; /** * Calculates width and hight of the title text */ TitleRendererBase.prototype.getTextSize = function (title, textStyle, renderContext) { if (title === void 0) { title = ""; } if (!title || title.length === 0) { this.desiredHeightProperty = 0; this.desiredWidthProperty = 0; this.textHeight = 0; this.textWidth = 0; return; } var hasHorizontalPlacement = (0, TextStyle_1.getIsHorizontalPlacement)(this.titlePosition); if (this.useNativeTextProperty) { // @ts-ignore mismatch with TTextStyle var nativeFont = renderContext.getFont(textStyle, !hasHorizontalPlacement); var titleString = Array.isArray(title) ? title.join("\n") : title; var adjRotation = (0, exports.getAdjustedRotation)(textStyle.rotation, this.titlePosition); var _a = (0, text_1.getNativeTextSize)(titleString, nativeFont, textStyle, this.webAssemblyContext, adjRotation), textHeight = _a.textHeight, textWidth = _a.textWidth, nativeLineSpacing = _a.nativeLineSpacing, deltaX = _a.deltaX, deltaY = _a.deltaY; this.textHeight = hasHorizontalPlacement ? textHeight : textWidth; this.textWidth = hasHorizontalPlacement ? textWidth : textHeight; this.nativeLineSpacing = nativeLineSpacing; this.nativeTextShiftX = deltaX; this.nativeTextShiftY = deltaY; this.desiredHeightProperty = hasHorizontalPlacement ? this.textHeight : this.textWidth; this.desiredWidthProperty = hasHorizontalPlacement ? this.textWidth : this.textHeight; } else { // current title texture doesn't include paddings, so they should be added here var texture = this.getTitleTexture(); this.texture = texture; this.desiredHeightProperty = texture.textureHeight; this.desiredWidthProperty = texture.textureWidth; this.textHeight = hasHorizontalPlacement ? this.desiredHeightProperty : this.desiredWidthProperty; this.textWidth = hasHorizontalPlacement ? this.desiredWidthProperty : this.desiredHeightProperty; } if (app_1.IS_TEST_ENV) { if (hasHorizontalPlacement) { this.desiredHeightProperty = (0, TextureManager_1.measureTextHeight)(textStyle.fontSize) + this.textStyle.padding.top + this.textStyle.padding.bottom; this.desiredWidthProperty = 0; } else { this.desiredHeightProperty = 0; this.desiredWidthProperty = (0, TextureManager_1.measureTextHeight)(textStyle.fontSize) + this.textStyle.padding.top + this.textStyle.padding.bottom; } } }; TitleRendererBase.prototype.getTitleTexture = function () { // TODO this is not used at the moment; consider unifying logic for Chart Title Renderer and Axis Title Renderer var titleText = Array.isArray(this.text) ? this.text : this.text.split("\n"); var texture = this.textureManager.createTextTexture(titleText, // @ts-ignore mismatch with TTextStyle this.textStyle // { ...this.textStyle, padding: new Thickness(0, 0, 0, 0) }, ); return texture; }; /** * Calculates the {@link TitleRenderer.viewRect} */ TitleRendererBase.prototype.getViewRect = function (title, originRect, titlePosition, alignment) { if (title === void 0) { title = ""; } if (!title || title.length === 0) { return Rect_1.Rect.createZero(); } var hasHorizontalPlacement = (0, TextStyle_1.getIsHorizontalPlacement)(titlePosition); var alignmentDelta = this.getAlignmentAdjustmentDelta(hasHorizontalPlacement ? originRect.width : originRect.height, titlePosition, alignment); switch (titlePosition) { case TextStyle_1.ETitlePosition.Top: return new Rect_1.Rect(originRect.x + alignmentDelta, originRect.y, this.textWidth, this.textHeight); case TextStyle_1.ETitlePosition.Bottom: return new Rect_1.Rect(originRect.x + alignmentDelta, originRect.bottom - this.textHeight, this.textWidth, this.textHeight); case TextStyle_1.ETitlePosition.Left: return new Rect_1.Rect(originRect.x, originRect.y + alignmentDelta, this.textHeight, this.textWidth); case TextStyle_1.ETitlePosition.Right: return new Rect_1.Rect(originRect.right - this.textHeight, originRect.y + alignmentDelta, this.textHeight, this.textWidth); default: return (0, TextStyle_1.handleInvalidChartTitlePosition)(titlePosition); } }; TitleRendererBase.prototype.drawTitleDebugViewRect = function (renderContext) { var viewRect = this.viewRect; var vecRects = (0, NativeObject_1.getVectorRectVertex)(this.webAssemblyContext); var brush = new this.webAssemblyContext.SCRTSolidBrush((0, parseColor_1.parseColorToUIntArgb)("rgba(0,255,0,0.7)"), false); var nativeRect = (0, createNativeRect_1.createNativeRect)(this.webAssemblyContext, 0, 0, viewRect.width, viewRect.height); vecRects.push_back(nativeRect); renderContext.drawRects(vecRects, brush, viewRect.left, viewRect.top); brush.delete(); }; /** * Calculates the offset of title text alignment defined by {@link TChartTitleStyle.alignment} or {@link TTextStyle.alignment} */ TitleRendererBase.prototype.getAlignmentAdjustmentDelta = function (availableSpace, position, alignment) { switch (alignment) { case TextStyle_1.ETextAlignment.Center: return availableSpace / 2 - this.textWidth / 2; case TextStyle_1.ETextAlignment.Left: return position === TextStyle_1.ETitlePosition.Left ? availableSpace - this.textWidth : 0; case TextStyle_1.ETextAlignment.Right: return position === TextStyle_1.ETitlePosition.Left ? 0 : availableSpace - this.textWidth; default: return (0, TextStyle_1.handleInvalidTextAlignment)(alignment); } }; return TitleRendererBase; }(DeletableEntity_1.DeletableEntity)); exports.TitleRendererBase = TitleRendererBase; var getAdjustedRotation = function (rotation, position) { if (rotation !== undefined) { return (rotation + 360) % 360; } var adjustedRotation = 0; if (position === TextStyle_1.ETitlePosition.Left) { adjustedRotation += -90; } else if (position === TextStyle_1.ETitlePosition.Right) { adjustedRotation += 90; } return (adjustedRotation + 360) % 360; }; exports.getAdjustedRotation = getAdjustedRotation;