UNPKG

scichart

Version:

Fast WebGL JavaScript Charting Library and Framework

238 lines (237 loc) 12 kB
"use strict"; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SciChart3DRenderer = void 0; var IAnnotation_1 = require("../../Charting/Visuals/Annotations/IAnnotation"); var Deleter_1 = require("../../Core/Deleter"); var Guard_1 = require("../../Core/Guard"); var Rect_1 = require("../../Core/Rect"); var AutoRange_1 = require("../../types/AutoRange"); var WatermarkPosition_1 = require("../../types/WatermarkPosition"); var perfomance_1 = require("../../utils/perfomance"); var AxisCubeDescriptor_1 = require("./Primitives/AxisCubeDescriptor"); var RenderPassInfo3D_1 = require("./Primitives/RenderPassInfo3D"); var SceneDescriptor_1 = require("./Primitives/SceneDescriptor"); /** * A class used internally in SciChart to perform layout, arrangement, data-preparation and rendering on the Cartesian 3D {@link SciChart3DSurface} */ var SciChart3DRenderer = /** @class */ (function () { function SciChart3DRenderer(scs, wasmContext) { this.isInvalidated = false; Guard_1.Guard.notNull(scs, "scs"); this.scs = scs; this.wasmContext = wasmContext; } /** * get the {@link SceneDescriptor} to define the look & styling of the scene in the current render pass * @param scs the {@link SciChart3DSurface} we are drawing */ SciChart3DRenderer.getSceneDescriptor = function (scs) { var _a, _b, _c; // Collect info from axis and scene how to draw / what to draw var scene = new SceneDescriptor_1.SceneDescriptor(); scene.axisCubeDescriptor = new AxisCubeDescriptor_1.AxisCubeDescriptor(); scene.axisCubeDescriptor.dimensions = scs.worldDimensions; scene.axisCubeDescriptor.isVisible = true; scene.axisCubeDescriptor.xAxisDescriptor = (_a = scs.xAxis) === null || _a === void 0 ? void 0 : _a.toAxisDescriptor(); scene.axisCubeDescriptor.yAxisDescriptor = (_b = scs.yAxis) === null || _b === void 0 ? void 0 : _b.toAxisDescriptor(); scene.axisCubeDescriptor.zAxisDescriptor = (_c = scs.zAxis) === null || _c === void 0 ? void 0 : _c.toAxisDescriptor(); return scene; }; /** * Prepares render data and returns a {@link RenderPassInfo3D} for the current render pass * @param scs the {@link SciChart3DSurface} we are drawing */ SciChart3DRenderer.prepareRenderData = function (scs) { var rpd = new RenderPassInfo3D_1.RenderPassInfo3D(); rpd.xCalc = scs.xAxis.getCurrentCoordinateCalculator(); rpd.yCalc = scs.yAxis.getCurrentCoordinateCalculator(); rpd.zCalc = scs.zAxis.getCurrentCoordinateCalculator(); rpd.worldDimensions = scs.worldDimensions; rpd.sceneDescriptor = SciChart3DRenderer.getSceneDescriptor(scs); return rpd; }; /** * Performs autorange on the {@link AxisBase3D} depending on flags such as {@link AxisBase3D.autoRange} * @param axis The {@link AxisBase3D} we are auto-ranging * @param scs the {@link SciChart3DSurface} we are drawing */ SciChart3DRenderer.tryPerformAutoRangeOn = function (axis, scs) { var shouldAutoRange = ((!axis.hasValidVisibleRange() || axis.hasDefaultVisibleRange()) && axis.autoRange === AutoRange_1.EAutoRange.Once) || axis.autoRange === AutoRange_1.EAutoRange.Always; if (shouldAutoRange) { var newRange = scs.viewportManager.calculateAutoRange(axis); if (newRange && !(newRange === axis.visibleRange) && axis.isValidRange(newRange)) { axis.visibleRange = newRange; } } }; /** * The main render loop */ SciChart3DRenderer.prototype.render = function () { var _this = this; var _a, _b; if (this.scs.isDeleted || !this.scs.isInitialized) { return; } this.isInvalidated = false; var renderStartMark = perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.RenderStart, { contextId: this.scs.id, level: perfomance_1.EPerformanceDebugLevel.Verbose }); // Step 1: Sanity checks this.isSurfaceValid(this.scs); // Throws errors if false // Enable/disable hit test as required. this.scs.webAssemblyContext3D.SCRTSetIsSelectionBufferEnabled(this.scs.isHitTestEnabled); // Step 1: Update the current active SceneWorld and camera var sceneWorld = this.scs.getSceneWorld(); if (!sceneWorld) { console.warn("SciChart3DRenderer: Undefined scene world!"); return; } this.wasmContext.SCRTSetActiveWorld(sceneWorld); this.updateWorldDimensions(sceneWorld, this.scs.worldDimensions); var tsrCamera = sceneWorld.GetMainCamera(); var typescriptCamera = this.scs.camera; typescriptCamera.updateEngineCamera(tsrCamera); var _c = this.scs.viewportManager, width = _c.width, height = _c.height; var viewRect = new Rect_1.Rect(0, 0, width, height); this.scs.setSeriesViewRect(viewRect); // Animation Step var timeElapsed = this.previousTime ? Date.now() - this.previousTime : undefined; this.previousTime = Date.now(); var animationStartMark = perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.GenericAnimationStart, { contextId: this.scs.id, level: perfomance_1.EPerformanceDebugLevel.Verbose }); this.scs.genericAnimationsRun.raiseEvent(); this.scs.onAnimate(timeElapsed); perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.GenericAnimationEnd, { contextId: this.scs.id, relatedId: (_a = animationStartMark === null || animationStartMark === void 0 ? void 0 : animationStartMark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: perfomance_1.EPerformanceDebugLevel.Verbose }); // Step 2: Update background of the chart this.scs.updateBackground(); // Step 3: Prepare the Axes this.prepareAxes(this.scs.xAxis, this.scs.yAxis, this.scs.zAxis); // Step 4: Prepare the RenderPassData var rpd = SciChart3DRenderer.prepareRenderData(this.scs); // Step 5: Prepare the Axis Cube // Viewport3D already checked to be not null in IsSurfaceValid this.scs.rootEntity.visitEntities(function (e) { return e.setRenderPassData(rpd); }); var userAnnotations = this.scs.annotations.asArray(); var modifierAnnotations = this.scs.modifierAnnotations.asArray(); var annotations = __spreadArray(__spreadArray([], userAnnotations, true), modifierAnnotations, true); var svgAnnotations = annotations.filter(function (el) { return el.type === IAnnotation_1.EAnnotationType.SVG || el.type === IAnnotation_1.EAnnotationType.SVGTextAnnotation || el.type === IAnnotation_1.EAnnotationType.SVGCustomAnnotation; }); svgAnnotations.forEach(function (svg) { var _a; var mark = perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.DrawAnnotationStart, { contextId: svg.id, parentContextId: _this.scs.id, level: perfomance_1.EPerformanceDebugLevel.Verbose }); svg.update(undefined, undefined, 0, 0); perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.DrawAnnotationEnd, { contextId: svg.id, parentContextId: _this.scs.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: perfomance_1.EPerformanceDebugLevel.Verbose }); }); // We add the same padding as we have for 2D 6px this.updateWatermark(); // Step 6: Notify that scene is about to be drawn this.scs.onSciChartRendered(); // Invalidate for the animations if (this.scs.isRunningAnimation) { setTimeout(this.scs.invalidateElement, 0); } perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.RenderEnd, { contextId: this.scs.id, relatedId: (_b = renderStartMark === null || renderStartMark === void 0 ? void 0 : renderStartMark.detail) === null || _b === void 0 ? void 0 : _b.relatedId, level: perfomance_1.EPerformanceDebugLevel.Verbose }); }; SciChart3DRenderer.prototype.updateWatermark = function () { var chartHeight = this.scs.getMainCanvas().clientHeight; var chartWidth = this.scs.getMainCanvas().clientWidth; var left = 5; var bottom = chartHeight - 10; var wmWidth = Math.max(72, Math.min(0.25 * chartWidth, 256)); var wmHeight = (42 * wmWidth) / 256; switch (this.scs.watermarkPosition) { case WatermarkPosition_1.EWatermarkPosition.BottomRight: left = chartWidth - wmWidth - 5; bottom = 12; break; case WatermarkPosition_1.EWatermarkPosition.TopLeft: left = 5; bottom = chartHeight - (5 + wmHeight); break; case WatermarkPosition_1.EWatermarkPosition.TopRight: left = chartWidth - wmWidth - 5; bottom = chartHeight - (5 + wmHeight); break; case WatermarkPosition_1.EWatermarkPosition.BottomLeft: left = 5; bottom = 12; break; } this.scs.updateWatermark(left, bottom); }; SciChart3DRenderer.prototype.isSurfaceValid = function (sciChartSurface, viewportSize) { if (!sciChartSurface.xAxis) { throw new Error("Unable to draw SciChart3DSurface as the xAxis is undefined"); } if (!sciChartSurface.yAxis) { throw new Error("Unable to draw SciChart3DSurface as the yAxis is undefined"); } if (!sciChartSurface.zAxis) { throw new Error("Unable to draw SciChart3DSurface as the zAxis is undefined"); } return true; }; SciChart3DRenderer.prototype.prepareAxes = function () { var _this = this; var axis = []; for (var _i = 0; _i < arguments.length; _i++) { axis[_i] = arguments[_i]; } axis.forEach(function (el) { el.validateAxis(); SciChart3DRenderer.tryPerformAutoRangeOn(el, _this.scs); el.isMeasured = true; }); }; SciChart3DRenderer.prototype.updateWorldDimensions = function (sceneWorld, worldDimensions) { Guard_1.Guard.notNull(worldDimensions, "worldDimensions"); var worldDimensionsVector4; try { worldDimensionsVector4 = this.scs.worldDimensions.toTsrVector3(this.wasmContext); sceneWorld.SetWorldDimensions(worldDimensionsVector4); } finally { (0, Deleter_1.deleteSafe)(worldDimensionsVector4); } }; return SciChart3DRenderer; }()); exports.SciChart3DRenderer = SciChart3DRenderer; /** @ignore */ var toString = function (vector) { return "TSRVector3 (".concat(vector.x.toFixed(2), ", ").concat(vector.y.toFixed(2), ", ").concat(vector.z.toFixed(2), ")"); };